Skip to content

Commit 455c255

Browse files
committed
Introduce ExecutorRule for stress-tests for simpler development process
1 parent 9f4fd70 commit 455c255

File tree

3 files changed

+51
-14
lines changed

3 files changed

+51
-14
lines changed

kotlinx-coroutines-core/jvm/test/AwaitStressTest.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,8 @@ import java.util.concurrent.*
1111
class AwaitStressTest : TestBase() {
1212

1313
private val iterations = 50_000 * stressTestMultiplier
14-
private val pool = newFixedThreadPoolContext(4, "AwaitStressTest")
15-
16-
@After
17-
fun tearDown() {
18-
pool.close()
19-
}
14+
@get:Rule
15+
public val pool = ExecutorRule(4)
2016

2117
@Test
2218
fun testMultipleExceptions() = runTest {

kotlinx-coroutines-core/jvm/test/CancellableContinuationResumeCloseStressTest.kt

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,16 @@ import kotlin.test.*
1111
import kotlin.test.Test
1212

1313
class CancellableContinuationResumeCloseStressTest : TestBase() {
14-
private val dispatcher =
15-
newFixedThreadPoolContext(2, "CancellableContinuationResumeCloseStressTest")
14+
@get:Rule
15+
public val dispatcher = ExecutorRule(2)
16+
1617
private val startBarrier = CyclicBarrier(3)
1718
private val doneBarrier = CyclicBarrier(2)
1819
private val nRepeats = 1_000 * stressTestMultiplier
1920

2021
private val closed = atomic(false)
2122
private var returnedOk = false
2223

23-
@After
24-
fun tearDown() {
25-
dispatcher.close()
26-
}
27-
2824
@Test
2925
@Suppress("BlockingMethodInNonBlockingContext")
3026
fun testStress() = runTest {
@@ -65,4 +61,4 @@ class CancellableContinuationResumeCloseStressTest : TestBase() {
6561
fun close() {
6662
assertFalse(closed.getAndSet(true))
6763
}
68-
}
64+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.coroutines
6+
7+
import org.junit.rules.*
8+
import org.junit.runner.*
9+
import org.junit.runners.model.*
10+
import java.util.concurrent.*
11+
import kotlin.coroutines.*
12+
13+
class ExecutorRule(private val numberOfThreads: Int) : TestRule, ExecutorCoroutineDispatcher() {
14+
15+
private var _executor: ExecutorCoroutineDispatcher? = null
16+
override val executor: Executor
17+
get() = _executor?.executor ?: error("Executor is not initialized")
18+
19+
override fun apply(base: Statement, description: Description): Statement {
20+
return object : Statement() {
21+
override fun evaluate() {
22+
val threadPrefix = description.className.substringAfterLast(".") + "#" + description.methodName
23+
_executor = newFixedThreadPoolContext(numberOfThreads, threadPrefix)
24+
ignoreLostThreads(threadPrefix)
25+
try {
26+
return base.evaluate()
27+
} finally {
28+
val service = executor as ExecutorService
29+
service.shutdown()
30+
if (!service.awaitTermination(10, TimeUnit.SECONDS)) {
31+
error("Test $description timed out")
32+
}
33+
}
34+
}
35+
}
36+
}
37+
38+
override fun dispatch(context: CoroutineContext, block: Runnable) {
39+
_executor?.dispatch(context, block) ?: error("Executor is not initialized")
40+
}
41+
42+
override fun close() {
43+
error("Cannot be closed manually")
44+
}
45+
}

0 commit comments

Comments
 (0)