Skip to content

Commit df9bb17

Browse files
committed
Add the model checking mode in Lincheck tests
1 parent 9587590 commit df9bb17

10 files changed

+65
-73
lines changed

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ junit_version=4.12
1212
atomicfu_version=0.14.4
1313
knit_version=0.2.2
1414
html_version=0.6.8
15-
lincheck_version=2.7.1
15+
lincheck_version=2.9-SNAPSHOT
1616
dokka_version=0.9.16-rdev-2-mpp-hacks
1717
byte_buddy_version=1.10.9
1818
reactor_version=3.2.5.RELEASE
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
package kotlinx.coroutines
5+
6+
import org.jetbrains.kotlinx.lincheck.*
7+
import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.*
8+
import org.jetbrains.kotlinx.lincheck.strategy.stress.*
9+
import org.jetbrains.kotlinx.lincheck.verifier.*
10+
import org.junit.*
11+
12+
abstract class AbstractLincheckTest : VerifierState() {
13+
open fun <O: Options<O, *>> O.customize(isStressTest: Boolean): O = this
14+
15+
@Test
16+
fun modelCheckingTest() = ModelCheckingOptions()
17+
.iterations(if (isStressTest) 100 else 30)
18+
.invocationsPerIteration(if (isStressTest) 10_000 else 1_000)
19+
.commonConfiguration()
20+
.check(this::class)
21+
22+
@Test
23+
fun stressTest() = StressOptions()
24+
.iterations(if (isStressTest) 100 else 20)
25+
.invocationsPerIteration(if (isStressTest) 10_000 else 1_000)
26+
.commonConfiguration()
27+
.check(this::class)
28+
29+
private fun <O : Options<O, *>> O.commonConfiguration(): O = this
30+
.actorsBefore(if (isStressTest) 3 else 1)
31+
.threads(3)
32+
.actorsPerThread(if (isStressTest) 4 else 2)
33+
.actorsAfter(if (isStressTest) 3 else 1)
34+
.customize(isStressTest)
35+
36+
override fun extractState(): Any = error("Not implemented")
37+
}

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

-20
This file was deleted.

kotlinx-coroutines-core/jvm/test/linearizability/ChannelsLCStressTest.kt

+7-7
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ import kotlinx.coroutines.channels.Channel.Factory.CONFLATED
1111
import kotlinx.coroutines.channels.Channel.Factory.RENDEZVOUS
1212
import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
1313
import kotlinx.coroutines.selects.*
14+
import org.jetbrains.kotlinx.lincheck.*
1415
import org.jetbrains.kotlinx.lincheck.annotations.*
1516
import org.jetbrains.kotlinx.lincheck.annotations.Operation
1617
import org.jetbrains.kotlinx.lincheck.paramgen.*
1718
import org.jetbrains.kotlinx.lincheck.verifier.*
18-
import org.junit.*
1919

2020
class RendezvousChannelLCStressTest : ChannelLCStressTestBase(
2121
c = Channel(RENDEZVOUS),
@@ -51,7 +51,10 @@ class SequentialConflatedChannel : SequentialIntChannelBase(CONFLATED)
5151
Param(name = "value", gen = IntGen::class, conf = "1:5"),
5252
Param(name = "closeToken", gen = IntGen::class, conf = "1:3")
5353
)
54-
abstract class ChannelLCStressTestBase(private val c: Channel<Int>, private val sequentialSpecification: Class<*>) {
54+
abstract class ChannelLCStressTestBase(
55+
private val c: Channel<Int>,
56+
private val sequentialSpecification: Class<*>
57+
) : AbstractLincheckTest() {
5558
@Operation
5659
suspend fun send(@Param(name = "value") value: Int): Any = try {
5760
c.send(value)
@@ -113,11 +116,8 @@ abstract class ChannelLCStressTestBase(private val c: Channel<Int>, private val
113116
// @Operation
114117
fun isEmpty() = c.isEmpty
115118

116-
@Test
117-
fun test() = LCStressOptionsDefault()
118-
.actorsBefore(0)
119-
.sequentialSpecification(sequentialSpecification)
120-
.check(this::class)
119+
override fun <O : Options<O, *>> O.customize(isStressTest: Boolean): O =
120+
actorsBefore(0).sequentialSpecification(sequentialSpecification)
121121
}
122122

123123
private class NumberedCancellationException(number: Int) : CancellationException() {

kotlinx-coroutines-core/jvm/test/linearizability/LockFreeListLCStressTest.kt

+1-6
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@ import kotlinx.coroutines.internal.*
1010
import org.jetbrains.kotlinx.lincheck.annotations.*
1111
import org.jetbrains.kotlinx.lincheck.annotations.Operation
1212
import org.jetbrains.kotlinx.lincheck.paramgen.*
13-
import org.jetbrains.kotlinx.lincheck.verifier.*
14-
import kotlin.test.*
1513

1614
@Param(name = "value", gen = IntGen::class, conf = "1:5")
17-
class LockFreeListLCStressTest : VerifierState() {
15+
class LockFreeListLCStressTest : AbstractLincheckTest() {
1816
class Node(val value: Int): LockFreeLinkedListNode()
1917

2018
private val q: LockFreeLinkedListHead = LockFreeLinkedListHead()
@@ -43,9 +41,6 @@ class LockFreeListLCStressTest : VerifierState() {
4341

4442
private fun Any.isSame(value: Int) = this is Node && this.value == value
4543

46-
@Test
47-
fun testAddRemoveLinearizability() = LCStressOptionsDefault().check(this::class)
48-
4944
override fun extractState(): Any {
5045
val elements = ArrayList<Int>()
5146
q.forEach<Node> { elements.add(it.value) }

kotlinx-coroutines-core/jvm/test/linearizability/LockFreeTaskQueueLCStressTest.kt

+5-8
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ package kotlinx.coroutines.linearizability
77

88
import kotlinx.coroutines.*
99
import kotlinx.coroutines.internal.*
10+
import org.jetbrains.kotlinx.lincheck.*
1011
import org.jetbrains.kotlinx.lincheck.annotations.*
1112
import org.jetbrains.kotlinx.lincheck.annotations.Operation
1213
import org.jetbrains.kotlinx.lincheck.paramgen.*
13-
import org.jetbrains.kotlinx.lincheck.verifier.*
1414
import org.jetbrains.kotlinx.lincheck.verifier.quiescent.*
15-
import kotlin.test.*
1615

1716
@Param(name = "value", gen = IntGen::class, conf = "1:3")
18-
internal abstract class AbstractLockFreeTaskQueueWithoutRemoveLCStressTest protected constructor(singleConsumer: Boolean) : VerifierState() {
17+
internal abstract class AbstractLockFreeTaskQueueWithoutRemoveLCStressTest protected constructor(singleConsumer: Boolean) : AbstractLincheckTest() {
1918
@JvmField
2019
protected val q = LockFreeTaskQueue<Int>(singleConsumer = singleConsumer)
2120

@@ -29,12 +28,10 @@ internal abstract class AbstractLockFreeTaskQueueWithoutRemoveLCStressTest prote
2928
@Operation(group = "consumer")
3029
fun removeFirstOrNull() = q.removeFirstOrNull()
3130

32-
override fun extractState() = q.map { it } to q.isClosed()
31+
override fun <O : Options<O, *>> O.customize(isStressTest: Boolean): O =
32+
verifier(QuiescentConsistencyVerifier::class.java)
3333

34-
@Test
35-
fun testWithRemoveForQuiescentConsistency() = LCStressOptionsDefault()
36-
.verifier(QuiescentConsistencyVerifier::class.java)
37-
.check(this::class)
34+
override fun extractState() = q.map { it } to q.isClosed()
3835
}
3936

4037
@OpGroupConfig(name = "consumer", nonParallel = false)

kotlinx-coroutines-core/jvm/test/linearizability/MutexLCStressTest.kt

+4-7
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ package kotlinx.coroutines.linearizability
66

77
import kotlinx.coroutines.*
88
import kotlinx.coroutines.sync.*
9+
import org.jetbrains.kotlinx.lincheck.*
910
import org.jetbrains.kotlinx.lincheck.annotations.Operation
10-
import org.jetbrains.kotlinx.lincheck.verifier.*
11-
import org.junit.*
1211

13-
class MutexLCStressTest : VerifierState() {
12+
class MutexLCStressTest : AbstractLincheckTest() {
1413
private val mutex = Mutex()
1514

1615
@Operation
@@ -22,10 +21,8 @@ class MutexLCStressTest : VerifierState() {
2221
@Operation(handleExceptionsAsResult = [IllegalStateException::class])
2322
fun unlock() = mutex.unlock()
2423

25-
@Test
26-
fun test() = LCStressOptionsDefault()
27-
.actorsBefore(0)
28-
.check(this::class)
24+
override fun <O : Options<O, *>> O.customize(isStressTest: Boolean): O =
25+
actorsBefore(0)
2926

3027
override fun extractState() = mutex.isLocked
3128
}

kotlinx-coroutines-core/jvm/test/linearizability/SegmentListRemoveLCStressTest.kt

+5-11
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,11 @@ package kotlinx.coroutines.linearizability
88

99
import kotlinx.coroutines.*
1010
import kotlinx.coroutines.internal.*
11+
import org.jetbrains.kotlinx.lincheck.*
1112
import org.jetbrains.kotlinx.lincheck.annotations.*
12-
import org.jetbrains.kotlinx.lincheck.annotations.Operation
1313
import org.jetbrains.kotlinx.lincheck.paramgen.*
14-
import org.jetbrains.kotlinx.lincheck.verifier.*
15-
import org.junit.*
1614

17-
18-
class SegmentListRemoveLCStressTest : VerifierState() {
15+
class SegmentListRemoveLCStressTest : AbstractLincheckTest() {
1916
private val q = SegmentBasedQueue<Int>()
2017
private val segments: Array<OneElementSegment<Int>>
2118

@@ -29,17 +26,14 @@ class SegmentListRemoveLCStressTest : VerifierState() {
2926
segments[index].removeSegment()
3027
}
3128

29+
override fun <O : Options<O, *>> O.customize(isStressTest: Boolean): O = this
30+
.actorsBefore(0).actorsAfter(0)
31+
3232
override fun extractState() = segments.map { it.logicallyRemoved }
3333

3434
@Validate
3535
fun checkAllRemoved() {
3636
q.checkHeadPrevIsCleaned()
3737
q.checkAllSegmentsAreNotLogicallyRemoved()
3838
}
39-
40-
@Test
41-
fun test() = LCStressOptionsDefault()
42-
.actorsBefore(0)
43-
.actorsAfter(0)
44-
.check(this::class)
4539
}

kotlinx-coroutines-core/jvm/test/linearizability/SegmentQueueLCStressTest.kt

+1-6
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@ import kotlinx.coroutines.internal.SegmentBasedQueue
1010
import org.jetbrains.kotlinx.lincheck.annotations.*
1111
import org.jetbrains.kotlinx.lincheck.annotations.Operation
1212
import org.jetbrains.kotlinx.lincheck.paramgen.*
13-
import org.jetbrains.kotlinx.lincheck.verifier.*
14-
import org.junit.*
1513

1614
@Param(name = "value", gen = IntGen::class, conf = "1:5")
17-
class SegmentQueueLCStressTest : VerifierState() {
15+
class SegmentQueueLCStressTest : AbstractLincheckTest() {
1816
private val q = SegmentBasedQueue<Int>()
1917

2018
@Operation
@@ -39,7 +37,4 @@ class SegmentQueueLCStressTest : VerifierState() {
3937
val closed = q.enqueue(0) === null
4038
return elements to closed
4139
}
42-
43-
@Test
44-
fun test() = LCStressOptionsDefault().check(this::class)
4540
}

kotlinx-coroutines-core/jvm/test/linearizability/SemaphoreLCStressTest.kt

+4-7
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ package kotlinx.coroutines.linearizability
66

77
import kotlinx.coroutines.*
88
import kotlinx.coroutines.sync.*
9+
import org.jetbrains.kotlinx.lincheck.*
910
import org.jetbrains.kotlinx.lincheck.annotations.Operation
10-
import org.jetbrains.kotlinx.lincheck.verifier.*
11-
import org.junit.*
1211

13-
abstract class SemaphoreLCStressTestBase(permits: Int) : VerifierState() {
12+
abstract class SemaphoreLCStressTestBase(permits: Int) : AbstractLincheckTest() {
1413
private val semaphore = Semaphore(permits)
1514

1615
@Operation
@@ -22,10 +21,8 @@ abstract class SemaphoreLCStressTestBase(permits: Int) : VerifierState() {
2221
@Operation(handleExceptionsAsResult = [IllegalStateException::class])
2322
fun release() = semaphore.release()
2423

25-
@Test
26-
fun test() = LCStressOptionsDefault()
27-
.actorsBefore(0)
28-
.check(this::class)
24+
override fun <O : Options<O, *>> O.customize(isStressTest: Boolean): O =
25+
actorsBefore(0)
2926

3027
override fun extractState() = semaphore.availablePermits
3128
}

0 commit comments

Comments
 (0)