1 package kotlinx.coroutines.testing 2 3 import kotlinx.coroutines.* 4 import org.junit.rules.* 5 import org.junit.runner.* 6 import org.junit.runners.model.* 7 import java.lang.Runnable 8 import java.util.concurrent.* 9 import kotlin.coroutines.* 10 11 class ExecutorRule(private val numberOfThreads: Int) : TestRule, ExecutorCoroutineDispatcher() { 12 13 private var _executor: ExecutorCoroutineDispatcher? = null 14 override val executor: Executor 15 get() = _executor?.executor ?: error("Executor is not initialized") 16 applynull17 override fun apply(base: Statement, description: Description): Statement { 18 return object : Statement() { 19 override fun evaluate() { 20 val threadPrefix = description.className.substringAfterLast(".") + "#" + description.methodName 21 _executor = newFixedThreadPoolContext(numberOfThreads, threadPrefix) 22 ignoreLostThreads(threadPrefix) 23 try { 24 return base.evaluate() 25 } finally { 26 val service = executor as ExecutorService 27 service.shutdown() 28 if (!service.awaitTermination(10, TimeUnit.SECONDS)) { 29 error("Test $description timed out") 30 } 31 } 32 } 33 } 34 } 35 dispatchnull36 override fun dispatch(context: CoroutineContext, block: Runnable) { 37 _executor?.dispatch(context, block) ?: error("Executor is not initialized") 38 } 39 closenull40 override fun close() { 41 error("Cannot be closed manually") 42 } 43 } 44