ronantakizawa/codereview-bench huggingface dataset:
Repository: ktorio/ktor
File: ktor-http/ktor-http-cio/common/src/io/ktor/http/cio/RequestResponse.kt (Kotlin)

Code before:
     *
     * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.HttpMessage.close)
     */
    override fun close() {
        release()
    }
}

/**
 * Represents an HTTP request
 *
 * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.Request)
 *
 * @property method
 * @property uri
 * @property version
 */
public class Request internal constructor(
    public val method: HttpMethod,
    public val uri: CharSequence,
    public val version: CharSequence,
    headers: HttpHeadersMap,
    builder: CharArrayBuilder
) : HttpMessage(headers, builder) {
    @InternalAPI
    public var onClose: (() -> Unit)? = null
}

/**
 * Represents an HTTP response
 *
 * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.Response)
 *
 * @property version
 * @property status
 * @property statusText
 */
public class Response internal constructor(
    public val version: CharSequence,
    public val status: Int,
    public val statusText: CharSequence,
    headers: HttpHeadersMap,
    builder: CharArrayBuilder
) : HttpMessage(headers, builder)


Review comment (suggestion):
Maybe we can drop the field and call the attribute directly from an extension function:

```
@InternalApi
fun Request.onClose() {
    call.attributes.getOrNull(HttpRequestCloseHandlerKey)?.invoke()
}
```

Code after:
     *
     * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.HttpMessage.close)
     */
    override fun close() {
        release()
    }
}

/**
 * Represents an HTTP request
 *
 * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.Request)
 *
 * @property method
 * @property uri
 * @property version
 */
public class Request internal constructor(
    public val method: HttpMethod,
    public val uri: CharSequence,
    public val version: CharSequence,
    headers: HttpHeadersMap,
    builder: CharArrayBuilder
) : HttpMessage(headers, builder)

/**
 * Represents an HTTP response
 *
 * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.http.cio.Response)
 *
 * @property version
 * @property status
 * @property statusText
 */
public class Response internal constructor(
    public val version: CharSequence,
    public val status: Int,
    public val statusText: CharSequence,
    headers: HttpHeadersMap,
    builder: CharArrayBuilder
) : HttpMessage(headers, builder)
Repository: ktorio/ktor
File: ktor-client/ktor-client-java/jvm/src/io/ktor/client/engine/java/JavaHttpResponseBodyHandler.kt (Kotlin)

Code before:

        override fun onError(cause: Throwable) {
            close(cause)
        }

        override fun onComplete() {
            subscription.getAndSet(null)
            queue.close()
        }

        override fun getBody(): CompletionStage<HttpResponseData> {
            return CompletableFuture.completedStage(httpResponse)
        }

        private fun close(cause: Throwable?) {
            if (!closed.compareAndSet(expect = false, update = true)) {
                return
            }

            try {
                queue.close(cause)
                subscription.getAndSet(null)?.cancel()
            } finally {
                cause?.apply {
                    consumerJob.completeExceptionally(cause)
                } ?: consumerJob.complete()
                responseChannel.cancel(cause)
            }
        }
    }
}


Review comment (suggestion):
Minor. `.let` + function reference is probably more suitable here
```suggestion
                cause?.let(consumerJob::completeExceptionally) ?: consumerJob.complete()
```

Code after:
                }
            }
        }

        override fun onError(cause: Throwable) {
            close(cause)
        }

        override fun onComplete() {
            subscription.getAndSet(null)
            queue.close()
        }

        override fun getBody(): CompletionStage<HttpResponseData> {
            return CompletableFuture.completedStage(httpResponse)
        }

        private fun close(cause: Throwable?) {
            if (!closed.compareAndSet(expect = false, update = true)) {
                return
            }

            try {
                queue.close(cause)
                subscription.getAndSet(null)?.cancel()
            } finally {
                cause?.let(consumerJob::completeExceptionally) ?: consumerJob.complete()
                responseChannel.cancel(cause)
            }
        }
    }
}
Repository: ktorio/ktor
File: ktor-http/common/src/io/ktor/http/Mimes.kt (Kotlin)

Code before:
/*
 * Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.http

import io.ktor.util.*

internal const val INITIAL_MIMES_LIST_SIZE: Int = 1217

private val rawMimes: String
    get() = """
application/acad,dwg
application/andrew-inset,ez
application/applixware,aw
application/arj,arj
application/atom+xml,atom
application/atomcat+xml,atomcat
application/atomsvc+xml,atomsvc
application/base64,mm mme
application/binhex,hqx
application/binhex4,hqx
application/book,boo book
application/ccxml+xml,ccxml
application/cdf,cdf
application/cdmi-capability,cdmia
application/cdmi-container,cdmic
application/cdmi-domain,cdmid
application/cdmi-object,cdmio
application/cdmi-queue,cdmiq
application/clariscad,ccad
application/commonground,dp
application/cu-seeme,cu
application/davmount+xml,davmount

Review comment (refactor):
Updated this as `audio/mpeg,mpg` has been removed, it duplicates 

https://github.com/ktorio/ktor/blob/73f83874c756a5441a04984ca48e505a37027b58/ktor-http/common/src/io/ktor/http/Mimes.kt#L706

Code after:
/*
 * Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.http

import io.ktor.util.*

internal const val INITIAL_MIMES_LIST_SIZE: Int = 1216

private val rawMimes: String
    get() = """
application/acad,dwg
application/andrew-inset,ez
application/applixware,aw
application/arj,arj
application/atom+xml,atom
application/atomcat+xml,atomcat
application/atomsvc+xml,atomsvc
application/base64,mm mme
application/binhex,hqx
application/binhex4,hqx
application/book,boo book
application/ccxml+xml,ccxml
application/cdf,cdf
application/cdmi-capability,cdmia
application/cdmi-container,cdmic
application/cdmi-domain,cdmid
application/cdmi-object,cdmio
application/cdmi-queue,cdmiq
application/clariscad,ccad
application/commonground,dp
application/cu-seeme,cu
application/davmount+xml,davmount
Repository: ktorio/ktor
File: ktor-server/ktor-server-jetty-jakarta/jvm/test/io/ktor/tests/server/jetty/jakarta/JettyEngineTest.kt (Kotlin)

Code before:
)

class JettyHttpServerCommonTest :
    HttpServerCommonTestSuite<JettyApplicationEngine, JettyApplicationEngineBase.Configuration>(Jetty) {
    override fun testFlushingHeaders() {
        // no op
    }
}

class JettyHttpServerJvmTest : HttpServerJvmTestSuite<JettyApplicationEngine, JettyApplicationEngineBase.Configuration>(
    Jetty
) {
    @Ignore
    override fun testPipelining() {
    }

    @Ignore
    override fun testPipeliningWithFlushingHeaders() {
    }
}

class JettySustainabilityTest :
    SustainabilityTestSuite<JettyApplicationEngine, JettyApplicationEngineBase.Configuration>(Jetty) {

    override fun configure(configuration: JettyApplicationEngineBase.Configuration) {
        configuration.callGroupSize = 6
    }
}

class JettyConfigTest : ConfigTestSuite(Jetty)

class JettyConnectionTest : ConnectionTestSuite(Jetty)

class JettyServerPluginsTest : ServerPluginsTestSuite<JettyApplicationEngine, JettyApplicationEngineBase.Configuration>(
    Jetty
) {
    init {
        enableHttp2 = false
        enableSsl = false
    }
}


Review comment (bug):
I don't agree with making this change to satisfy the tests, this comment is to start a discussion thread. 
Without it the following tests will fail (when the `callGroupSize` is _lower_):
- `io.ktor.server.testing.suites.SustainabilityTestSuite#testBlockingDeadlock`
- `io.ktor.server.testing.suites.SustainabilityTestSuite#testBlockingConcurrency`

Which I now see the test I wrote was a similar like test.

The question is what to do about it, 
- Potentially the multiple of the max thread pool size could be increased substantially, and/or the base is increased from parallelism (x2-3), which I'm not opposed to because on single or dual core VMs this is very low.
- Or be `min()` of a value to satisfy these tests if the tests are setting the minimum client expectations.

Code after:
)

class JettyHttpServerCommonTest :
    HttpServerCommonTestSuite<JettyApplicationEngine, JettyApplicationEngineBase.Configuration>(Jetty) {
    override fun testFlushingHeaders() {
        // no op
    }
}

class JettyHttpServerJvmTest : HttpServerJvmTestSuite<JettyApplicationEngine, JettyApplicationEngineBase.Configuration>(
    Jetty
) {
    @Ignore
    override fun testPipelining() {
    }

    @Ignore
    override fun testPipeliningWithFlushingHeaders() {
    }
}

class JettySustainabilityTest :
    SustainabilityTestSuite<JettyApplicationEngine, JettyApplicationEngineBase.Configuration>(Jetty)

class JettyConfigTest : ConfigTestSuite(Jetty)

class JettyConnectionTest : ConnectionTestSuite(Jetty)

class JettyServerPluginsTest : ServerPluginsTestSuite<JettyApplicationEngine, JettyApplicationEngineBase.Configuration>(
    Jetty
) {
    init {
        enableHttp2 = false
        enableSsl = false
    }
}
Repository: ktorio/ktor
File: ktor-server/ktor-server-core/jvm/src/io/ktor/server/engine/EmbeddedServerJvm.kt (Kotlin)

Code before:
/*
 * Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.server.engine

import io.ktor.events.*
import io.ktor.events.EventDefinition
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.engine.internal.*
import io.ktor.server.routing.routingRoot
import io.ktor.util.*
import io.ktor.util.logging.*
import io.ktor.util.pipeline.*
import io.ktor.util.reflect.*
import io.ktor.utils.io.*
import io.ktor.utils.io.core.*
import kotlinx.coroutines.*
import java.io.File
import java.net.URL
import java.net.URLDecoder
import java.nio.file.*
import java.nio.file.StandardWatchEventKinds.*
import java.nio.file.attribute.BasicFileAttributes
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.getOrSet
import kotlin.concurrent.read
import kotlin.concurrent.write

private typealias ApplicationModule = suspend Application.() -> Unit

public actual class EmbeddedServer<
    TEngine : ApplicationEngine,
    TConfiguration : ApplicationEngine.Configuration
    >

Review comment (suggestion):
The import statement for routingRoot is added but not used anywhere in this file. This appears to be an accidental addition unrelated to the chunked encoding fix and should be removed to keep the imports clean.
```suggestion

```

Code after:
/*
 * Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.server.engine

import io.ktor.events.*
import io.ktor.events.EventDefinition
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.engine.internal.*
import io.ktor.util.*
import io.ktor.util.logging.*
import io.ktor.util.pipeline.*
import io.ktor.util.reflect.*
import io.ktor.utils.io.*
import io.ktor.utils.io.core.*
import kotlinx.coroutines.*
import java.io.File
import java.net.URL
import java.net.URLDecoder
import java.nio.file.*
import java.nio.file.StandardWatchEventKinds.*
import java.nio.file.attribute.BasicFileAttributes
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.getOrSet
import kotlin.concurrent.read
import kotlin.concurrent.write

private typealias ApplicationModule = suspend Application.() -> Unit

public actual class EmbeddedServer<
    TEngine : ApplicationEngine,
    TConfiguration : ApplicationEngine.Configuration
    >
actual constructor(
Repository: ktorio/ktor
File: ktor-utils/jvm/test/io/ktor/util/GMTDateCalendarTest.kt (Kotlin)

Code before:
/*
 * Copyright 2014-2023 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.util

import io.ktor.util.date.*
import java.util.*
import kotlin.test.*

class GMTDateCalendarTest {

    @Test
    fun testTimestampIsConsistent() {
        val calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Berlin"))
        val actual = calendar.toDate(null)
        val expected = GMTDate(actual.timestamp)

        assertEquals(expected, actual)
    }

    @Test
    fun testTimestampIsDifferentWithDifferentTimezone() {
        val calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Berlin"))
        val gmt = GMTDate()
        val actual = calendar.toDate(null)

        val offset: Long = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)).toLong()
        val diff = gmt.timestamp + offset - actual.timestamp
        assertTrue(diff >= 0)
        assertTrue(diff < 1000)
    }
}


Review comment (suggestion):
Probably all these tests could be replaced with one list of `Pair<Long, String>` where `Long` is the timestamp and `String` is the expected output of `toHttpDate`

Code after:
    fun testTimestampIsDifferentWithDifferentTimezone() {
        val calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Berlin"))
        val gmt = GMTDate()
        val actual = calendar.toDate(null)

        val offset: Long = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)).toLong()
        val diff = gmt.timestamp + offset - actual.timestamp
        assertTrue(diff >= 0)
        assertTrue(diff < 1000)
    }

    @Test
    fun `epoch timestamp is 1970-01-01 00_00_00 GMT`() {
        val date = GMTDate(0L)
        assertEquals(1970, date.year)
        assertEquals(Month.JANUARY, date.month)
        assertEquals(1, date.dayOfMonth)
        assertEquals(0, date.hours)
        assertEquals(0, date.minutes)
        assertEquals(0, date.seconds)
        assertEquals(WeekDay.THURSDAY, date.dayOfWeek)
        assertEquals(1, date.dayOfYear)
    }

    @Test
    fun `leap year 2000 Feb 29 is handled correctly`() {
        // Feb 29, 2000 12:00:00 GMT - leap year divisible by 400
        val timestamp = 951825600000L
        val date = GMTDate(timestamp)
        assertEquals(2000, date.year)
        assertEquals(Month.FEBRUARY, date.month)
        assertEquals(29, date.dayOfMonth)
        assertEquals(WeekDay.TUESDAY, date.dayOfWeek)
        assertEquals(60, date.dayOfYear)
    }

    @Test
    fun `1900 is not a leap year`() {
        // March 1, 1900 00:00:00 GMT - not a leap year (divisible by 100 but not 400)
        val timestamp = -2203891200000L
        val date = GMTDate(timestamp)
        assertEquals(1900, date.year)
        assertEquals(Month.MARCH, date.month)
        assertEquals(1, date.dayOfMonth)
        assertEquals(60, date.dayOfYear)
    }

    @Test
    fun `leap year 2024 Feb 29 with time components`() {
        // Feb 29, 2024 15:30:45 GMT
        val timestamp = 1709220645000L
Repository: ktorio/ktor
File: ktor-client/ktor-client-core/jvm/src/io/ktor/client/statement/DispatcherSwitching.jvm.kt (Kotlin)

Code before:
/*
 * Copyright 2014-2026 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.client.statement

private const val USE_ENGINE_DISPATCHER_KEY: String = "io.ktor.client.statement.useEngineDispatcher"

@PublishedApi
internal actual val useEngineDispatcher: Boolean by lazy(LazyThreadSafetyMode.NONE) {
    System.getProperty(USE_ENGINE_DISPATCHER_KEY, "false").toBoolean()
}


Review comment (suggestion):
Alternatively thought about introducing some general flag like [progressive mode](https://kotlinlang.org/api/kotlin-gradle-plugin/kotlin-gradle-plugin-api/org.jetbrains.kotlin.gradle.dsl/-kotlin-common-compiler-options/progressive-mode.html) in Kotlin. It would allow us to introduce such behavior changes and enable them by default on new projects.
However, `useEngineDispatcher` is the only candidate for this progressive mode I'm aware

Code after:
/*
 * Copyright 2014-2026 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.client.statement

private const val USE_ENGINE_DISPATCHER_KEY: String = "io.ktor.client.statement.useEngineDispatcher"

@PublishedApi
internal actual val useEngineDispatcher: Boolean = System.getProperty(USE_ENGINE_DISPATCHER_KEY, "false").toBoolean()
Repository: kubernetes/kubernetes
File: staging/src/k8s.io/client-go/util/workqueue/queue.go (Go)

Code before:

		q.cond.L.Lock()
		defer q.cond.L.Unlock()

		q.drain = false
		q.shuttingDown = true
		q.cond.Broadcast()
	})
}

// ShutDownWithDrain is equivalent to ShutDown but waits until all items
// in the queue have been processed.
// ShutDown can be called after ShutDownWithDrain to force
// ShutDownWithDrain to stop waiting.
// Workers must call Done on an item after processing it, otherwise
// ShutDownWithDrain will block indefinitely.
func (q *Typed[T]) ShutDownWithDrain() {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()

	q.drain = true
	q.shuttingDown = true
	q.cond.Broadcast()

	for q.processing.Len() != 0 && q.drain {
		q.cond.Wait()
	}
}

func (q *Typed[T]) ShuttingDown() bool {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()

	return q.shuttingDown
}

func (q *Typed[T]) updateUnfinishedWorkLoop() {
	t := q.clock.NewTicker(q.unfinishedWorkUpdatePeriod)
	defer t.Stop()
	for {
		select {
		case <-t.C():
			q.cond.L.Lock()
			if !q.shuttingDown {
				q.metrics.updateUnfinishedWork()
			}
			q.cond.L.Unlock()
		case <-q.stopCh:
			return
		}
	}

Review comment (refactor):
`if !func() bool {` was a bit difficult to read. This is equivalent to exiting when `q.shuttingDown` is true. By using the stopCh, the behavior is the same and we can simplify this logic. 

Code after:

	q.cond.L.Lock()
	defer q.cond.L.Unlock()

	q.drain = false
	q.shuttingDown = true
	q.cond.Broadcast()
}

// ShutDownWithDrain is equivalent to ShutDown but waits until all items
// in the queue have been processed.
// ShutDown can be called after ShutDownWithDrain to force
// ShutDownWithDrain to stop waiting.
// Workers must call Done on an item after processing it, otherwise
// ShutDownWithDrain will block indefinitely.
func (q *Typed[T]) ShutDownWithDrain() {
	defer q.wg.Wait()
	q.stopOnce.Do(func() {
		defer close(q.stopCh)
	})
	q.cond.L.Lock()
	defer q.cond.L.Unlock()

	q.drain = true
	q.shuttingDown = true
	q.cond.Broadcast()

	for q.processing.Len() != 0 && q.drain {
		q.cond.Wait()
	}
}

func (q *Typed[T]) ShuttingDown() bool {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()

	return q.shuttingDown
}

func (q *Typed[T]) updateUnfinishedWork() {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	if !q.shuttingDown {
		q.metrics.updateUnfinishedWork()
	}
}

func (q *Typed[T]) updateUnfinishedWorkLoop() {
	t := q.clock.NewTicker(q.unfinishedWorkUpdatePeriod)
	defer t.Stop()
	for {
Repository: kubernetes/kubernetes
File: staging/src/k8s.io/client-go/util/workqueue/queue.go (Go)

Code before:
	q.shuttingDown = true
	q.cond.Broadcast()

	for q.processing.Len() != 0 && q.drain {
		q.cond.Wait()
	}
}

func (q *Typed[T]) ShuttingDown() bool {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()

	return q.shuttingDown
}

func (q *Typed[T]) updateUnfinishedWorkLoop() {
	t := q.clock.NewTicker(q.unfinishedWorkUpdatePeriod)
	defer t.Stop()
	for {
		select {
		case <-t.C():
			q.cond.L.Lock()
			if !q.shuttingDown {
				q.metrics.updateUnfinishedWork()
			}
			q.cond.L.Unlock()
		case <-q.stopCh:
			return
		}
	}
}


Review comment (suggestion):
nit: I'd prefer the unlock be done in a defer. That way it's guaranteed to be called even if the guarded code panics.

Code after:
	q.shuttingDown = true
	q.cond.Broadcast()

	for q.processing.Len() != 0 && q.drain {
		q.cond.Wait()
	}
}

func (q *Typed[T]) ShuttingDown() bool {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()

	return q.shuttingDown
}

func (q *Typed[T]) updateUnfinishedWork() {
	q.cond.L.Lock()
	defer q.cond.L.Unlock()
	if !q.shuttingDown {
		q.metrics.updateUnfinishedWork()
	}
}

func (q *Typed[T]) updateUnfinishedWorkLoop() {
	t := q.clock.NewTicker(q.unfinishedWorkUpdatePeriod)
	defer t.Stop()
	for {
		select {
		case <-t.C():
			q.updateUnfinishedWork()
		case <-q.stopCh:
			return
		}
	}
}
Repository: kubernetes/kubernetes
File: staging/src/k8s.io/apiserver/pkg/audit/policy/checker_test.go (Go)

Code before:
		"subresource": &authorizer.AttributesRecord{
			User:            tim,
			Verb:            "get",
			Namespace:       "default",
			APIGroup:        "", // Core
			APIVersion:      "v1",
			Resource:        "pods",
			Subresource:     "log",
			Name:            "busybox",
			ResourceRequest: true,
			Path:            "/api/v1/namespaces/default/pods/busybox",
		},
		"Unauthorized": &authorizer.AttributesRecord{
			Verb:            "get",
			Namespace:       "default",
			APIGroup:        "", // Core
			APIVersion:      "v1",
			Resource:        "pods",
			Name:            "busybox",
			ResourceRequest: true,
			Path:            "/api/v1/namespaces/default/pods/busybox",
		},
		"ClusterRoleUpdate": &authorizer.AttributesRecord{
			User:            tim,
			Verb:            "update",
			APIGroup:        "rbac.authorization.k8s.io", // Core
			APIVersion:      "v1beta1",
			Resource:        "clusterroles",
			Subresource:     "status",
			Name:            "somerole",
			ResourceRequest: true,
			Path:            "/apis/rbac.authorization.k8s.io/v1beta1/clusterroles/somerole",
		},
	}

	rules = map[string]audit.PolicyRule{
		"default": {
			Level: audit.LevelMetadata,
		},
		"create": {
			Level: audit.LevelRequest,
			Verbs: []string{"create"},
		},
		"tims": {
			Level: audit.LevelMetadata,
			Users: []string{"tim@k8s.io"},
		},
		"humans": {
			Level:      audit.LevelMetadata,
			UserGroups: []string{"humans"},
		},

Review comment (security):
```suggestion
			APIGroup:        "rbac.authorization.k8s.io",
```

Code after:
		"subresource": &authorizer.AttributesRecord{
			User:            tim,
			Verb:            "get",
			Namespace:       "default",
			APIGroup:        "", // Core
			APIVersion:      "v1",
			Resource:        "pods",
			Subresource:     "log",
			Name:            "busybox",
			ResourceRequest: true,
			Path:            "/api/v1/namespaces/default/pods/busybox",
		},
		"Unauthorized": &authorizer.AttributesRecord{
			Verb:            "get",
			Namespace:       "default",
			APIGroup:        "", // Core
			APIVersion:      "v1",
			Resource:        "pods",
			Name:            "busybox",
			ResourceRequest: true,
			Path:            "/api/v1/namespaces/default/pods/busybox",
		},
		"ClusterRoleUpdate": &authorizer.AttributesRecord{
			User:            tim,
			Verb:            "update",
			APIGroup:        "rbac.authorization.k8s.io",
			APIVersion:      "v1beta1",
			Resource:        "clusterroles",
			Subresource:     "status",
			Name:            "somerole",
			ResourceRequest: true,
			Path:            "/apis/rbac.authorization.k8s.io/v1beta1/clusterroles/somerole",
		},
	}

	rules = map[string]audit.PolicyRule{
		"default": {
			Level: audit.LevelMetadata,
		},
		"create": {
			Level: audit.LevelRequest,
			Verbs: []string{"create"},
		},
		"tims": {
			Level: audit.LevelMetadata,
			Users: []string{"tim@k8s.io"},
		},
		"humans": {
			Level:      audit.LevelMetadata,
			UserGroups: []string{"humans"},
		},