diff --git a/buildSrc/src/main/kotlin/CommunityProjectsBuild.kt b/buildSrc/src/main/kotlin/CommunityProjectsBuild.kt index ff5bb36f10..83f303429c 100644 --- a/buildSrc/src/main/kotlin/CommunityProjectsBuild.kt +++ b/buildSrc/src/main/kotlin/CommunityProjectsBuild.kt @@ -146,6 +146,7 @@ fun isSnapshotTrainEnabled(project: Project): Boolean { val firstPartyDependencies = listOf( "kotlin", "atomicfu", + "lincheck" ) fun shouldUseLocalMaven(project: Project): Boolean { diff --git a/gradle.properties b/gradle.properties index 442b47e4e8..3fc370f8c3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ benchmarks_jmh_version=1.37 junit_version=4.12 junit5_version=5.7.0 knit_version=0.5.0 -lincheck_version=2.18.1 +lincheck_version=3.0 dokka_version=2.0.0 org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled org.jetbrains.dokka.experimental.gradle.pluginMode.nowarn=true diff --git a/kotlinx-coroutines-core/build.gradle.kts b/kotlinx-coroutines-core/build.gradle.kts index 07fb22c640..e2b4fa6b1b 100644 --- a/kotlinx-coroutines-core/build.gradle.kts +++ b/kotlinx-coroutines-core/build.gradle.kts @@ -57,7 +57,7 @@ kotlin { } jvmTest { dependencies { - api("org.jetbrains.kotlinx:lincheck:${version("lincheck")}") + api("org.jetbrains.lincheck:lincheck:${version("lincheck")}") api("org.jetbrains.kotlinx:kotlinx-knit-test:${version("knit")}") implementation(project(":android-unit-tests")) implementation("org.openjdk.jol:jol-core:0.16") @@ -252,6 +252,7 @@ kover { // lincheck has NPE error on `ManagedStrategyStateHolder` class excludedClasses.addAll("org.jetbrains.kotlinx.lincheck.*") + excludedClasses.addAll("org.jetbrains.lincheck.*") } sources { excludedSourceSets.addAll("benchmark") diff --git a/kotlinx-coroutines-core/jvm/test/AbstractLincheckTest.kt b/kotlinx-coroutines-core/jvm/test/AbstractLincheckTest.kt index 6287be0081..c02ba94f02 100644 --- a/kotlinx-coroutines-core/jvm/test/AbstractLincheckTest.kt +++ b/kotlinx-coroutines-core/jvm/test/AbstractLincheckTest.kt @@ -1,9 +1,7 @@ package kotlinx.coroutines import kotlinx.coroutines.testing.* -import org.jetbrains.kotlinx.lincheck.* -import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.* -import org.jetbrains.kotlinx.lincheck.strategy.stress.* +import org.jetbrains.lincheck.datastructures.* import org.junit.* abstract class AbstractLincheckTest { diff --git a/kotlinx-coroutines-core/jvm/test/internal/OnDemandAllocatingPoolLincheckTest.kt b/kotlinx-coroutines-core/jvm/test/internal/OnDemandAllocatingPoolLincheckTest.kt index 77d8179929..1637839742 100644 --- a/kotlinx-coroutines-core/jvm/test/internal/OnDemandAllocatingPoolLincheckTest.kt +++ b/kotlinx-coroutines-core/jvm/test/internal/OnDemandAllocatingPoolLincheckTest.kt @@ -2,8 +2,7 @@ package kotlinx.coroutines.internal import kotlinx.atomicfu.* import kotlinx.coroutines.* -import org.jetbrains.kotlinx.lincheck.* -import org.jetbrains.kotlinx.lincheck.annotations.* +import org.jetbrains.lincheck.datastructures.* /** * Test that: diff --git a/kotlinx-coroutines-core/jvm/test/lincheck/ChannelsLincheckTest.kt b/kotlinx-coroutines-core/jvm/test/lincheck/ChannelsLincheckTest.kt index 96a8d13354..4da6429a1a 100644 --- a/kotlinx-coroutines-core/jvm/test/lincheck/ChannelsLincheckTest.kt +++ b/kotlinx-coroutines-core/jvm/test/lincheck/ChannelsLincheckTest.kt @@ -2,18 +2,13 @@ package kotlinx.coroutines.lincheck -import kotlinx.coroutines.testing.* import kotlinx.coroutines.* import kotlinx.coroutines.channels.* import kotlinx.coroutines.channels.Channel.Factory.CONFLATED import kotlinx.coroutines.channels.Channel.Factory.RENDEZVOUS import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED import kotlinx.coroutines.selects.* -import org.jetbrains.kotlinx.lincheck.* -import org.jetbrains.kotlinx.lincheck.annotations.* -import org.jetbrains.kotlinx.lincheck.annotations.Operation -import org.jetbrains.kotlinx.lincheck.paramgen.* -import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.* +import org.jetbrains.lincheck.datastructures.* class RendezvousChannelLincheckTest : ChannelLincheckTestBaseWithOnSend( c = Channel(RENDEZVOUS), @@ -80,7 +75,7 @@ abstract class ChannelLincheckTestBaseWithOnSend( sequentialSpecification: Class<*>, obstructionFree: Boolean = true ) : ChannelLincheckTestBase(c, sequentialSpecification, obstructionFree) { - @Operation(allowExtraSuspension = true, blocking = true) + @Operation(blocking = true) suspend fun sendViaSelect(@Param(name = "value") value: Int): Any = try { select { c.onSend(value) {} } } catch (e: NumberedCancellationException) { @@ -98,7 +93,7 @@ abstract class ChannelLincheckTestBase( private val obstructionFree: Boolean = true ) : AbstractLincheckTest() { - @Operation(allowExtraSuspension = true, blocking = true) + @Operation(blocking = true) suspend fun send(@Param(name = "value") value: Int): Any = try { c.send(value) } catch (e: NumberedCancellationException) { @@ -114,14 +109,14 @@ abstract class ChannelLincheckTestBase( else false } - @Operation(allowExtraSuspension = true, blocking = true) + @Operation(blocking = true) suspend fun receive(): Any = try { c.receive() } catch (e: NumberedCancellationException) { e.testResult } - @Operation(allowExtraSuspension = true, blocking = true) + @Operation(blocking = true) suspend fun receiveCatching(): Any = c.receiveCatching() .onSuccess { return it } .onClosed { e -> return (e as NumberedCancellationException).testResult } @@ -132,17 +127,17 @@ abstract class ChannelLincheckTestBase( .onSuccess { return it } .onFailure { return if (it is NumberedCancellationException) it.testResult else null } - @Operation(allowExtraSuspension = true, blocking = true) + @Operation(blocking = true) suspend fun receiveViaSelect(): Any = try { select { c.onReceive { it } } } catch (e: NumberedCancellationException) { e.testResult } - @Operation(causesBlocking = true, blocking = true) + @Operation(blocking = true) fun close(@Param(name = "closeToken") token: Int): Boolean = c.close(NumberedCancellationException(token)) - @Operation(causesBlocking = true, blocking = true) + @Operation(blocking = true) fun cancel(@Param(name = "closeToken") token: Int) = c.cancel(NumberedCancellationException(token)) // @Operation TODO non-linearizable in BufferedChannel @@ -154,9 +149,6 @@ abstract class ChannelLincheckTestBase( // @Operation TODO non-linearizable in BufferedChannel open fun isEmpty() = c.isEmpty - @StateRepresentation - fun state() = (c as? BufferedChannel<*>)?.toStringDebug() ?: c.toString() - @Validate fun validate() { (c as? BufferedChannel<*>)?.checkSegmentStructureInvariants() diff --git a/kotlinx-coroutines-core/jvm/test/lincheck/LockFreeTaskQueueLincheckTest.kt b/kotlinx-coroutines-core/jvm/test/lincheck/LockFreeTaskQueueLincheckTest.kt index 9a44891733..d647a8e979 100644 --- a/kotlinx-coroutines-core/jvm/test/lincheck/LockFreeTaskQueueLincheckTest.kt +++ b/kotlinx-coroutines-core/jvm/test/lincheck/LockFreeTaskQueueLincheckTest.kt @@ -4,12 +4,9 @@ package kotlinx.coroutines.lincheck import kotlinx.coroutines.* import kotlinx.coroutines.internal.* -import org.jetbrains.kotlinx.lincheck.* -import org.jetbrains.kotlinx.lincheck.annotations.* -import org.jetbrains.kotlinx.lincheck.annotations.Operation -import org.jetbrains.kotlinx.lincheck.paramgen.* -import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.* -import org.jetbrains.kotlinx.lincheck.verifier.quiescent.* +import org.jetbrains.lincheck.datastructures.* +import org.jetbrains.lincheck.datastructures.verifier.QuiescentConsistencyVerifier +import org.jetbrains.lincheck.datastructures.verifier.QuiescentConsistent @Param(name = "value", gen = IntGen::class, conf = "1:3") internal abstract class AbstractLockFreeTaskQueueWithoutRemoveLincheckTest( diff --git a/kotlinx-coroutines-core/jvm/test/lincheck/MutexLincheckTest.kt b/kotlinx-coroutines-core/jvm/test/lincheck/MutexLincheckTest.kt index 37051794b0..67aeccd72c 100644 --- a/kotlinx-coroutines-core/jvm/test/lincheck/MutexLincheckTest.kt +++ b/kotlinx-coroutines-core/jvm/test/lincheck/MutexLincheckTest.kt @@ -4,16 +4,13 @@ package kotlinx.coroutines.lincheck import kotlinx.coroutines.* import kotlinx.coroutines.selects.* import kotlinx.coroutines.sync.* -import org.jetbrains.kotlinx.lincheck.* -import org.jetbrains.kotlinx.lincheck.annotations.* -import org.jetbrains.kotlinx.lincheck.annotations.Operation -import org.jetbrains.kotlinx.lincheck.paramgen.* +import org.jetbrains.lincheck.datastructures.* @Param(name = "owner", gen = IntGen::class, conf = "0:2") class MutexLincheckTest : AbstractLincheckTest() { private val mutex = Mutex() - @Operation(handleExceptionsAsResult = [IllegalStateException::class]) + @Operation fun tryLock(@Param(name = "owner") owner: Int) = mutex.tryLock(owner.asOwnerOrNull) // TODO: `lock()` with non-null owner is non-linearizable @@ -22,10 +19,10 @@ class MutexLincheckTest : AbstractLincheckTest() { // TODO: `onLock` with non-null owner is non-linearizable // onLock may suspend in case of clause re-registration. - @Operation(allowExtraSuspension = true, promptCancellation = true) + @Operation(promptCancellation = true) suspend fun onLock() = select { mutex.onLock(null) {} } - @Operation(handleExceptionsAsResult = [IllegalStateException::class]) + @Operation fun unlock(@Param(name = "owner") owner: Int) = mutex.unlock(owner.asOwnerOrNull) @Operation diff --git a/kotlinx-coroutines-core/jvm/test/lincheck/ResizableAtomicArrayLincheckTest.kt b/kotlinx-coroutines-core/jvm/test/lincheck/ResizableAtomicArrayLincheckTest.kt index 5561a7dbf3..ac5be6c913 100644 --- a/kotlinx-coroutines-core/jvm/test/lincheck/ResizableAtomicArrayLincheckTest.kt +++ b/kotlinx-coroutines-core/jvm/test/lincheck/ResizableAtomicArrayLincheckTest.kt @@ -2,8 +2,7 @@ package kotlinx.coroutines.lincheck import kotlinx.coroutines.* import kotlinx.coroutines.internal.* -import org.jetbrains.kotlinx.lincheck.annotations.* -import org.jetbrains.kotlinx.lincheck.paramgen.* +import org.jetbrains.lincheck.datastructures.* @Param(name = "index", gen = IntGen::class, conf = "0:4") @Param(name = "value", gen = IntGen::class, conf = "1:5") diff --git a/kotlinx-coroutines-core/jvm/test/lincheck/SemaphoreLincheckTest.kt b/kotlinx-coroutines-core/jvm/test/lincheck/SemaphoreLincheckTest.kt index e99e8a185c..10b94a34a8 100644 --- a/kotlinx-coroutines-core/jvm/test/lincheck/SemaphoreLincheckTest.kt +++ b/kotlinx-coroutines-core/jvm/test/lincheck/SemaphoreLincheckTest.kt @@ -1,12 +1,9 @@ @file:Suppress("unused") package kotlinx.coroutines.lincheck -import kotlinx.coroutines.testing.* import kotlinx.coroutines.* import kotlinx.coroutines.sync.* -import org.jetbrains.kotlinx.lincheck.* -import org.jetbrains.kotlinx.lincheck.annotations.Operation -import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.* +import org.jetbrains.lincheck.datastructures.* abstract class SemaphoreLincheckTestBase(permits: Int) : AbstractLincheckTest() { private val semaphore = SemaphoreAndMutexImpl(permits = permits, acquiredPermits = 0) @@ -14,10 +11,10 @@ abstract class SemaphoreLincheckTestBase(permits: Int) : AbstractLincheckTest() @Operation fun tryAcquire() = semaphore.tryAcquire() - @Operation(promptCancellation = true, allowExtraSuspension = true) + @Operation(promptCancellation = true) suspend fun acquire() = semaphore.acquire() - @Operation(handleExceptionsAsResult = [IllegalStateException::class]) + @Operation fun release() = semaphore.release() override fun > O.customize(isStressTest: Boolean): O =