Stress-testing infrastructure
Tests are run x10 longer with "-DstressTest" JVM option
diff --git a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/JobTest.kt b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/JobTest.kt
index ca54780..63522a3 100644
--- a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/JobTest.kt
+++ b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/JobTest.kt
@@ -16,10 +16,10 @@
package kotlinx.coroutines.experimental
-import org.junit.Assert.*
+import org.junit.Assert.assertEquals
import org.junit.Test
-class JobTest {
+class JobTest : TestBase() {
@Test
fun testState() {
val job = Job()
@@ -48,7 +48,7 @@
@Test
fun testManyHandlers() {
val job = Job()
- val n = 100
+ val n = 100 * stressTestMultiplier
val fireCount = IntArray(n)
for (i in 0 until n) job.invokeOnCompletion { fireCount[i]++ }
check(job.isActive)
@@ -66,7 +66,7 @@
@Test
fun testUnregisterInHandler() {
val job = Job()
- val n = 100
+ val n = 100 * stressTestMultiplier
val fireCount = IntArray(n)
for (i in 0 until n) {
var registration: Job.Registration? = null
@@ -90,7 +90,7 @@
@Test
fun testManyHandlersWithUnregister() {
val job = Job()
- val n = 100
+ val n = 100 * stressTestMultiplier
val fireCount = IntArray(n)
val registrations = Array<Job.Registration>(n) { i -> job.invokeOnCompletion { fireCount[i]++ } }
check(job.isActive)
@@ -105,7 +105,7 @@
@Test
fun testExceptionsInHandler() {
val job = Job()
- val n = 100
+ val n = 100 * stressTestMultiplier
val fireCount = IntArray(n)
class TestException : Throwable()
for (i in 0 until n) job.invokeOnCompletion {
@@ -123,7 +123,7 @@
@Test
fun testMemoryRelease() {
val job = Job()
- val n = 10_000_000
+ val n = 10_000_000 * stressTestMultiplier
var fireCount = 0
for (i in 0 until n) job.invokeOnCompletion { fireCount++ }.unregister()
}
diff --git a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/TestBase.kt b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/TestBase.kt
index f955982..0454fc3 100644
--- a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/TestBase.kt
+++ b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/TestBase.kt
@@ -22,6 +22,9 @@
import java.util.concurrent.atomic.AtomicReference
open class TestBase {
+ val isStressTest = System.getProperty("stressTest") != null
+ val stressTestMultiplier = if (isStressTest) 10 else 1
+
var actionIndex = AtomicInteger()
var finished = AtomicBoolean()
var error = AtomicReference<Throwable>()
diff --git a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/channels/ChannelAtomicCancelStressTest.kt b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/channels/ChannelAtomicCancelStressTest.kt
index 1363785..da2fd00 100644
--- a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/channels/ChannelAtomicCancelStressTest.kt
+++ b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/channels/ChannelAtomicCancelStressTest.kt
@@ -29,14 +29,14 @@
* Tests cancel atomicity for channel send & receive operations, including their select versions.
*/
@RunWith(Parameterized::class)
-class ChannelAtomicCancelStressTest(val kind: TestChannelKind) {
+class ChannelAtomicCancelStressTest(val kind: TestChannelKind) : TestBase() {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun params(): Collection<Array<Any>> = TestChannelKind.values().map { arrayOf<Any>(it) }
}
- val TEST_DURATION = 3000L
+ val TEST_DURATION = 3000L * stressTestMultiplier
val channel = kind.create()
val senderDone = ArrayChannel<Boolean>(1)
diff --git a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/channels/ChannelSendReceiveStressTest.kt b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/channels/ChannelSendReceiveStressTest.kt
index 0f5878a..3843497 100644
--- a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/channels/ChannelSendReceiveStressTest.kt
+++ b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/channels/ChannelSendReceiveStressTest.kt
@@ -31,7 +31,7 @@
val kind: TestChannelKind,
val nSenders: Int,
val nReceivers: Int
-) {
+) : TestBase() {
companion object {
@Parameterized.Parameters(name = "{0}, nSenders={1}, nReceivers={2}")
@JvmStatic
@@ -43,8 +43,8 @@
}
}
- val timeLimit = 30_000L // 30 sec
- val nEvents = 1_000_000
+ val timeLimit = 30_000L * stressTestMultiplier // 30 sec
+ val nEvents = 1_000_000 * stressTestMultiplier
val channel = kind.create()
val sendersCompleted = AtomicInteger()
diff --git a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListAtomicStressTest.kt b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListAtomicStressTest.kt
index 7c3d676..d3ac3bc 100644
--- a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListAtomicStressTest.kt
+++ b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListAtomicStressTest.kt
@@ -16,6 +16,7 @@
package kotlinx.coroutines.experimental.internal
+import kotlinx.coroutines.experimental.TestBase
import org.junit.Assert.*
import org.junit.Test
import java.util.*
@@ -26,14 +27,15 @@
* This stress test has 4 threads adding randomly to the list and them immediately undoing
* this addition by remove, and 4 threads trying to remove nodes from two lists simultaneously (atomically).
*/
-class LockFreeLinkedListAtomicStressTest {
+class LockFreeLinkedListAtomicStressTest : TestBase() {
data class IntNode(val i: Int) : LockFreeLinkedListNode()
+ val TEST_DURATION = 5000L * stressTestMultiplier
+
val threads = mutableListOf<Thread>()
val nLists = 4
val nAdderThreads = 4
val nRemoverThreads = 4
- val timeout = 5000L
val completedAdder = AtomicInteger()
val completedRemover = AtomicInteger()
@@ -45,7 +47,7 @@
@Test
fun testStress() {
- val deadline = System.currentTimeMillis() + timeout
+ val deadline = System.currentTimeMillis() + TEST_DURATION
repeat(nAdderThreads) { threadId ->
threads += thread(start = false, name = "adder-$threadId") {
val rnd = Random()
diff --git a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListLongStressTest.kt b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListLongStressTest.kt
index 5daf1c5..9fc258e 100644
--- a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListLongStressTest.kt
+++ b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListLongStressTest.kt
@@ -16,6 +16,7 @@
package kotlinx.coroutines.experimental.internal
+import kotlinx.coroutines.experimental.TestBase
import org.junit.Test
import java.util.*
import java.util.concurrent.atomic.AtomicInteger
@@ -27,12 +28,12 @@
* and 6 threads iterating and concurrently removing items. The resulting list that is being
* stressed is long.
*/
-class LockFreeLinkedListLongStressTest {
+class LockFreeLinkedListLongStressTest : TestBase() {
data class IntNode(val i: Int) : LockFreeLinkedListNode()
val list = LockFreeLinkedListHead()
val threads = mutableListOf<Thread>()
- val nAdded = 10_000_000
+ val nAdded = 10_000_000 * stressTestMultiplier
val nAddThreads = 4 // must be power of 2 (!!!)
val nRemoveThreads = 6
val removeProbability = 0.2
diff --git a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListShortStressTest.kt b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListShortStressTest.kt
index a142117..5a7376f 100644
--- a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListShortStressTest.kt
+++ b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/internal/LockFreeLinkedListShortStressTest.kt
@@ -16,6 +16,7 @@
package kotlinx.coroutines.experimental.internal
+import kotlinx.coroutines.experimental.TestBase
import org.junit.Assert.*
import org.junit.Test
import java.util.*
@@ -27,14 +28,15 @@
* this addition by remove, and 4 threads removing first node. The resulting list that is being
* stressed is very short.
*/
-class LockFreeLinkedListShortStressTest {
+class LockFreeLinkedListShortStressTest : TestBase() {
data class IntNode(val i: Int) : LockFreeLinkedListNode()
val list = LockFreeLinkedListHead()
+ val TEST_DURATION = 5000L * stressTestMultiplier
+
val threads = mutableListOf<Thread>()
val nAdderThreads = 6
val nRemoverThreads = 4
- val timeout = 5000L
val completedAdder = AtomicInteger()
val completedRemover = AtomicInteger()
@@ -44,7 +46,7 @@
@Test
fun testStress() {
- val deadline = System.currentTimeMillis() + timeout
+ val deadline = System.currentTimeMillis() + TEST_DURATION
repeat(nAdderThreads) { threadId ->
threads += thread(start = false, name = "adder-$threadId") {
val rnd = Random()
diff --git a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectArrayChannelTest.kt b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectArrayChannelTest.kt
index c9cf44c..4f468ef 100644
--- a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectArrayChannelTest.kt
+++ b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectArrayChannelTest.kt
@@ -226,7 +226,7 @@
@Test
fun testSelectSendResourceCleanup() = runBlocking<Unit> {
val channel = ArrayChannel<Int>(1)
- val n = 10_000_000
+ val n = 10_000_000 * stressTestMultiplier
expect(1)
channel.send(-1) // fill the buffer, so all subsequent sends cannot proceed
repeat(n) { i ->
@@ -241,7 +241,7 @@
@Test
fun testSelectReceiveResourceCleanup() = runBlocking<Unit> {
val channel = ArrayChannel<Int>(1)
- val n = 10_000_000
+ val n = 10_000_000 * stressTestMultiplier
expect(1)
repeat(n) { i ->
select {
diff --git a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectMutexTest.kt b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectMutexTest.kt
index 0e1f0a2..4124f28 100644
--- a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectMutexTest.kt
+++ b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectMutexTest.kt
@@ -72,7 +72,7 @@
@Test
fun testSelectCancelledResourceRelease() = runBlocking<Unit> {
- val n = 1_000
+ val n = 1_000 * stressTestMultiplier
val mutex = Mutex(true) as MutexImpl // locked
expect(1)
repeat(n) { i ->
diff --git a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectPhilosophersStressTest.kt b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectPhilosophersStressTest.kt
index 5212587..9406ff2 100644
--- a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectPhilosophersStressTest.kt
+++ b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectPhilosophersStressTest.kt
@@ -21,8 +21,8 @@
import org.junit.Assert.assertTrue
import org.junit.Test
-class SelectPhilosophersStressTest {
- val TEST_DURATION = 3000L
+class SelectPhilosophersStressTest : TestBase() {
+ val TEST_DURATION = 3000L * stressTestMultiplier
val n = 10 // number of philosophers
val forks = Array<Mutex>(n) { Mutex() }
diff --git a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectRendezvousChannelTest.kt b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectRendezvousChannelTest.kt
index 6dc68c8..c3e4333 100644
--- a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectRendezvousChannelTest.kt
+++ b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/selects/SelectRendezvousChannelTest.kt
@@ -235,7 +235,7 @@
@Test
fun testSelectSendResourceCleanup() = runBlocking<Unit> {
val channel = RendezvousChannel<Int>()
- val n = 10_000_000
+ val n = 10_000_000 * stressTestMultiplier
expect(1)
repeat(n) { i ->
select {
@@ -249,7 +249,7 @@
@Test
fun testSelectReceiveResourceCleanup() = runBlocking<Unit> {
val channel = RendezvousChannel<Int>()
- val n = 10_000_000
+ val n = 10_000_000 * stressTestMultiplier
expect(1)
repeat(n) { i ->
select {
diff --git a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/sync/MutexTest.kt b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/sync/MutexTest.kt
index 0a0fcd5..a04840b 100644
--- a/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/sync/MutexTest.kt
+++ b/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/sync/MutexTest.kt
@@ -63,7 +63,7 @@
@Test
fun testStress() = runBlocking<Unit> {
- val n = 1000
+ val n = 1000 * stressTestMultiplier
val k = 100
var shared = 0
val mutex = Mutex()