Repository: JetBrains/lincheck
Pull request #648: Move guide tests into integration tests category
Author: login: eupp
Created: 2025-05-15T12:08:56Z | Merged: 2025-05-15T17:50:17Z



Diff:
diff --git a/docs/topics/constraints.md b/docs/topics/constraints.md
index b6ecdf8cef..75e8b719f8 100644
--- a/docs/topics/constraints.md
+++ b/docs/topics/constraints.md
@@ -96,7 +96,7 @@ Here is an example of the scenario generated for this test:
 Note that all consuming `poll()` and `peek()` invocations are performed from a single thread, thus satisfying the
 "single-consumer" restriction.
 
-> [Get the full code](https://github.com/JetBrains/lincheck/blob/master/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/MPSCQueueTest.kt).
+> [Get the full code](https://github.com/JetBrains/lincheck/blob/master/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/MPSCQueueTest.kt).
 >
 {style="note"}
 
diff --git a/docs/topics/introduction.md b/docs/topics/introduction.md
index 2df365c45f..4cd362fc56 100644
--- a/docs/topics/introduction.md
+++ b/docs/topics/introduction.md
@@ -170,7 +170,7 @@ The updated `BasicCounterTest` class will look like this:
    * **T2**: The second thread resumes and increments the previously obtained counter value, incorrectly updating the
    counter to `1`.
 
-> [Get the full code](https://github.com/JetBrains/lincheck/blob/master/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/BasicCounterTest.kt).
+> [Get the full code](https://github.com/JetBrains/lincheck/blob/master/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/BasicCounterTest.kt).
 >
 {style="note"}
 
@@ -252,7 +252,7 @@ The following interleaving leads to the error:
 | --------------------------------------------------------------------------------------------------------------------------------- |
 ```
 
-> [Get the full code](https://github.com/JetBrains/lincheck/blob/master/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentLinkedDequeTest.kt).
+> [Get the full code](https://github.com/JetBrains/lincheck/blob/master/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentLinkedDequeTest.kt).
 >
 {style="note"}
 
diff --git a/docs/topics/progress-guarantees.md b/docs/topics/progress-guarantees.md
index b7bff7afd8..4312c68be6 100644
--- a/docs/topics/progress-guarantees.md
+++ b/docs/topics/progress-guarantees.md
@@ -103,8 +103,8 @@ class ConcurrentSkipListMapTest {
 At the moment, Lincheck supports only the obstruction-freedom progress guarantees. However, most real-life liveness bugs
 add unexpected blocking code, so the obstruction-freedom check will also help with lock-free and wait-free algorithms.
 
-> * Get the [full code of the example](https://github.com/JetBrains/lincheck/blob/master/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentMapTest.kt).
-> * See [another example](https://github.com/JetBrains/lincheck/blob/master/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ObstructionFreedomViolationTest.kt)
+> * Get the [full code of the example](https://github.com/JetBrains/lincheck/blob/master/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentMapTest.kt).
+> * See [another example](https://github.com/JetBrains/lincheck/blob/master/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ObstructionFreedomViolationTest.kt)
 >   where the Michael-Scott queue implementation is tested for progress guarantees.
 >
 {style="note"}
diff --git a/docs/topics/sequential-specification.md b/docs/topics/sequential-specification.md
index 213d952736..1ae5862742 100644
--- a/docs/topics/sequential-specification.md
+++ b/docs/topics/sequential-specification.md
@@ -49,6 +49,6 @@ class SequentialQueue {
 }
 ```
 
-> Get the [full code of the examples](https://github.com/JetBrains/lincheck/blob/master/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentLinkedQueueTest.kt).
+> Get the [full code of the examples](https://github.com/JetBrains/lincheck/blob/master/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentLinkedQueueTest.kt).
 >
 {style="note"}
\ No newline at end of file
diff --git a/docs/topics/testing-strategies.md b/docs/topics/testing-strategies.md
index cc5017925c..fecb25f970 100644
--- a/docs/topics/testing-strategies.md
+++ b/docs/topics/testing-strategies.md
@@ -267,7 +267,7 @@ states in the trace, add the `stateRepresentation()` function to the `CounterTes
 In case of stress testing, Lincheck prints the state representation right before and after the parallel part of the scenario,
 as well as at the end.
 
-> * Get the [full code of these examples](https://github.com/JetBrains/lincheck/tree/master/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/CounterTest.kt)
+> * Get the [full code of these examples](https://github.com/JetBrains/lincheck/tree/master/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/CounterTest.kt)
 > * See more [test examples](https://github.com/JetBrains/lincheck/tree/master/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide)
 >
 {style="note"}
diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/BasicCounterTest.kt b/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/BasicCounterTest.kt
similarity index 100%
rename from src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/BasicCounterTest.kt
rename to src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/BasicCounterTest.kt
diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentLinkedDequeTest.kt b/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentLinkedDequeTest.kt
similarity index 100%
rename from src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentLinkedDequeTest.kt
rename to src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentLinkedDequeTest.kt
diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentLinkedQueueTest.kt b/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentLinkedQueueTest.kt
similarity index 100%
rename from src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentLinkedQueueTest.kt
rename to src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentLinkedQueueTest.kt
diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentMapTest.kt b/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentMapTest.kt
similarity index 100%
rename from src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentMapTest.kt
rename to src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ConcurrentMapTest.kt
diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/CounterTest.kt b/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/CounterTest.kt
similarity index 100%
rename from src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/CounterTest.kt
rename to src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/CounterTest.kt
diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/MPSCQueueTest.kt b/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/MPSCQueueTest.kt
similarity index 100%
rename from src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/MPSCQueueTest.kt
rename to src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/MPSCQueueTest.kt
diff --git a/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ObstructionFreedomViolationTest.kt b/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ObstructionFreedomViolationTest.kt
new file mode 100644
index 0000000000..6b4e9e8f31
--- /dev/null
+++ b/src/jvm/test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ObstructionFreedomViolationTest.kt
@@ -0,0 +1,33 @@
+/*
+ * Lincheck
+ *
+ * Copyright (C) 2019 - 2023 JetBrains s.r.o.
+ *
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
+ * with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package org.jetbrains.kotlinx.lincheck_test.guide
+
+import org.jetbrains.kotlinx.lincheck.*
+import org.jetbrains.kotlinx.lincheck.annotations.*
+import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.*
+import org.jetbrains.kotlinx.lincheck_test.datastructures.MSQueueBlocking
+import org.junit.*
+
+class ObstructionFreedomViolationTest  {
+    private val q = MSQueueBlocking()
+
+    @Operation
+    fun enqueue(x: Int) = q.enqueue(x)
+
+    @Operation
+    fun dequeue(): Int? = q.dequeue()
+
+    //@Test // TODO: Please, uncomment me and comment the line below to run the test and get the output
+    @Test(expected = AssertionError::class)
+    fun runModelCheckingTest() = ModelCheckingOptions()
+        .checkObstructionFreedom(true)
+        .check(this::class)
+}
\ No newline at end of file
diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ObstructionFreedomViolationTest.kt b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/datastructures/MSQueueBlocking.kt
similarity index 63%
rename from src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ObstructionFreedomViolationTest.kt
rename to src/jvm/test/org/jetbrains/kotlinx/lincheck_test/datastructures/MSQueueBlocking.kt
index 789b640575..c9b89b8baf 100644
--- a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/guide/ObstructionFreedomViolationTest.kt
+++ b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/datastructures/MSQueueBlocking.kt
@@ -1,20 +1,16 @@
 /*
  * Lincheck
  *
- * Copyright (C) 2019 - 2023 JetBrains s.r.o.
+ * Copyright (C) 2019 - 2025 JetBrains s.r.o.
  *
  * This Source Code Form is subject to the terms of the
  * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
  * with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-package org.jetbrains.kotlinx.lincheck_test.guide
+package org.jetbrains.kotlinx.lincheck_test.datastructures
 
-import org.jetbrains.kotlinx.lincheck.*
-import org.jetbrains.kotlinx.lincheck.annotations.*
-import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.*
-import org.junit.*
-import java.util.concurrent.atomic.*
+import java.util.concurrent.atomic.AtomicReference
 
 class MSQueueBlocking {
     private val DUMMY_NODE = Node(0)
@@ -51,19 +47,3 @@ class MSQueueBlocking {
         val next: AtomicReference<Node?> = AtomicReference(null)
     )
 }
-
-class ObstructionFreedomViolationTest  {
-    private val q = MSQueueBlocking()
-
-    @Operation
-    fun enqueue(x: Int) = q.enqueue(x)
-
-    @Operation
-    fun dequeue(): Int? = q.dequeue()
-
-    //@Test // TODO: Please, uncomment me and comment the line below to run the test and get the output
-    @Test(expected = AssertionError::class)
-    fun runModelCheckingTest() = ModelCheckingOptions()
-        .checkObstructionFreedom(true)
-        .check(this::class)
-}
\ No newline at end of file
diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/SpinlockEventsCutTests.kt b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/SpinlockEventsCutTests.kt
index e8a8178af0..c13e469213 100644
--- a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/SpinlockEventsCutTests.kt
+++ b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/SpinlockEventsCutTests.kt
@@ -15,7 +15,7 @@ import org.jetbrains.kotlinx.lincheck.*
 import org.jetbrains.kotlinx.lincheck.annotations.Operation
 import org.jetbrains.kotlinx.lincheck.execution.*
 import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.ModelCheckingOptions
-import org.jetbrains.kotlinx.lincheck_test.guide.MSQueueBlocking
+import org.jetbrains.kotlinx.lincheck_test.datastructures.MSQueueBlocking
 import org.jetbrains.kotlinx.lincheck_test.util.checkLincheckOutput
 import org.junit.Assume.assumeFalse
 import org.junit.Before
@@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicInteger
 import java.util.concurrent.atomic.AtomicReferenceArray
 import kotlin.reflect.jvm.*
 
+
 /**
  * Checks that spin-cycle repeated events are cut in case of obstruction freedom violation
  */
@@ -47,7 +48,6 @@ class ObstructionFreedomViolationEventsCutTest {
         .checkObstructionFreedom(true)
         .checkImpl(this::class.java)
         .checkLincheckOutput("obstruction_freedom_violation_events_cut")
-
 }
 
 /**
diff --git a/src/jvm/test/resources/expected_logs/obstruction_freedom_violation_events_cut.txt b/src/jvm/test/resources/expected_logs/obstruction_freedom_violation_events_cut.txt
index 00c7536b41..8cdecc7c7c 100644
--- a/src/jvm/test/resources/expected_logs/obstruction_freedom_violation_events_cut.txt
+++ b/src/jvm/test/resources/expected_logs/obstruction_freedom_violation_events_cut.txt
@@ -6,35 +6,35 @@
 | ------------------------ |
 
 The following interleaving leads to the error:
-| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-|                                                       Thread 1                                                        |                                                       Thread 2                                                       |
-| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-|                                                                                                                       | enqueue(-1)                                                                                                          |
-|                                                                                                                       |   q.enqueue(-1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:39)                    |
-|                                                                                                                       |     tail.get(): Node#1 at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:27)                             |
-|                                                                                                                       |     curTail.next.compareAndSet(null, Node#2): true at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:28) |
-|                                                                                                                       |     switch                                                                                                           |
-| enqueue(1)                                                                                                            |                                                                                                                      |
-|   q.enqueue(1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:39)                      |                                                                                                                      |
-|     /* The following events repeat infinitely: */                                                                     |                                                                                                                      |
-| ┌╶> tail.get(): Node#1 at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:27)                              |                                                                                                                      |
-| |   curTail.next.compareAndSet(null, Node#3): false at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:28) |                                                                                                                      |
-| └╶╶ /* An active lock was detected */                                                                                 |                                                                                                                      |
-| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+|                                               Thread 1                                                |                                               Thread 2                                               |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+|                                                                                                       | enqueue(-1)                                                                                          |
+|                                                                                                       |   q.enqueue(-1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:41)    |
+|                                                                                                       |     tail.get(): Node#1 at MSQueueBlocking.enqueue(MSQueueBlocking.kt:23)                             |
+|                                                                                                       |     curTail.next.compareAndSet(null, Node#2): true at MSQueueBlocking.enqueue(MSQueueBlocking.kt:24) |
+|                                                                                                       |     switch                                                                                           |
+| enqueue(1)                                                                                            |                                                                                                      |
+|   q.enqueue(1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:41)      |                                                                                                      |
+|     /* The following events repeat infinitely: */                                                     |                                                                                                      |
+| ┌╶> tail.get(): Node#1 at MSQueueBlocking.enqueue(MSQueueBlocking.kt:23)                              |                                                                                                      |
+| |   curTail.next.compareAndSet(null, Node#3): false at MSQueueBlocking.enqueue(MSQueueBlocking.kt:24) |                                                                                                      |
+| └╶╶ /* An active lock was detected */                                                                 |                                                                                                      |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
 
 Detailed trace:
-| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-|                                                       Thread 1                                                        |                                                       Thread 2                                                       |
-| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-|                                                                                                                       | enqueue(-1)                                                                                                          |
-|                                                                                                                       |   q.enqueue(-1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:39)                    |
-|                                                                                                                       |     tail.get(): Node#1 at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:27)                             |
-|                                                                                                                       |     curTail.next.compareAndSet(null, Node#2): true at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:28) |
-|                                                                                                                       |     switch                                                                                                           |
-| enqueue(1)                                                                                                            |                                                                                                                      |
-|   q.enqueue(1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:39)                      |                                                                                                                      |
-|     /* The following events repeat infinitely: */                                                                     |                                                                                                                      |
-| ┌╶> tail.get(): Node#1 at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:27)                              |                                                                                                                      |
-| |   curTail.next.compareAndSet(null, Node#3): false at MSQueueBlocking.enqueue(ObstructionFreedomViolationTest.kt:28) |                                                                                                                      |
-| └╶╶ /* An active lock was detected */                                                                                 |                                                                                                                      |
-| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+|                                               Thread 1                                                |                                               Thread 2                                               |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+|                                                                                                       | enqueue(-1)                                                                                          |
+|                                                                                                       |   q.enqueue(-1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:41)    |
+|                                                                                                       |     tail.get(): Node#1 at MSQueueBlocking.enqueue(MSQueueBlocking.kt:23)                             |
+|                                                                                                       |     curTail.next.compareAndSet(null, Node#2): true at MSQueueBlocking.enqueue(MSQueueBlocking.kt:24) |
+|                                                                                                       |     switch                                                                                           |
+| enqueue(1)                                                                                            |                                                                                                      |
+|   q.enqueue(1) at ObstructionFreedomViolationEventsCutTest.enqueue(SpinlockEventsCutTests.kt:41)      |                                                                                                      |
+|     /* The following events repeat infinitely: */                                                     |                                                                                                      |
+| ┌╶> tail.get(): Node#1 at MSQueueBlocking.enqueue(MSQueueBlocking.kt:23)                              |                                                                                                      |
+| |   curTail.next.compareAndSet(null, Node#3): false at MSQueueBlocking.enqueue(MSQueueBlocking.kt:24) |                                                                                                      |
+| └╶╶ /* An active lock was detected */                                                                 |                                                                                                      |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
diff --git a/src/jvm/test/resources/expected_logs/spin_lock/infinite_spin_loop_events_cut.txt b/src/jvm/test/resources/expected_logs/spin_lock/infinite_spin_loop_events_cut.txt
index d9f8d395bd..8fa845fded 100644
--- a/src/jvm/test/resources/expected_logs/spin_lock/infinite_spin_loop_events_cut.txt
+++ b/src/jvm/test/resources/expected_logs/spin_lock/infinite_spin_loop_events_cut.txt
@@ -34,27 +34,27 @@ The following interleaving leads to the error:
 |                                                                                                                        | two(): 2                                                                                                       |
 |                                                                                                                        | two(): 2                                                                                                       |
 |                                                                                                                        | one(): 1                                                                                                       |
-|                                                                                                                        |   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:295) |
-|                                                                                                                        |   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:298) |
+|                                                                                                                        |   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:296) |
+|                                                                                                                        |   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:299) |
 |                                                                                                                        |   switch                                                                                                       |
 | two(): <hung>                                                                                                          |                                                                                                                |
-|   sharedState2.compareAndSet(false, true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:309)        |                                                                                                                |
-|   meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:310)                                  |                                                                                                                |
+|   sharedState2.compareAndSet(false, true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:310)        |                                                                                                                |
+|   meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:311)                                  |                                                                                                                |
 |     /* The following events repeat infinitely: */                                                                      |                                                                                                                |
-| ┌╶> sharedStateAny.get(): false at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:106) |                                                                                                                |
-| |   sharedStateAny.set(true) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107)    |                                                                                                                |
-| |   sharedStateAny.get(): true at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:106)  |                                                                                                                |
-| |   sharedStateAny.set(false) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107)   |                                                                                                                |
+| ┌╶> sharedStateAny.get(): false at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107) |                                                                                                                |
+| |   sharedStateAny.set(true) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:108)    |                                                                                                                |
+| |   sharedStateAny.get(): true at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107)  |                                                                                                                |
+| |   sharedStateAny.set(false) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:108)   |                                                                                                                |
 | └╶╶ switch (reason: active lock detected)                                                                              |                                                                                                                |
-|                                                                                                                        |   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:301)                       |
-|                                                                                                                        |   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                       |
+|                                                                                                                        |   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                       |
+|                                                                                                                        |   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:303)                       |
 |                                                                                                                        |   result: 1                                                                                                    |
 |                                                                                                                        | one(): 1                                                                                                       |
 |     /* The following events repeat infinitely: */                                                                      |                                                                                                                |
-| ┌╶> sharedStateAny.get(): false at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:106) |                                                                                                                |
-| |   sharedStateAny.set(true) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107)    |                                                                                                                |
-| |   sharedStateAny.get(): true at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:106)  |                                                                                                                |
-| |   sharedStateAny.set(false) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107)   |                                                                                                                |
+| ┌╶> sharedStateAny.get(): false at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107) |                                                                                                                |
+| |   sharedStateAny.set(true) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:108)    |                                                                                                                |
+| |   sharedStateAny.get(): true at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107)  |                                                                                                                |
+| |   sharedStateAny.set(false) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:108)   |                                                                                                                |
 | └╶╶ switch (reason: active lock detected)                                                                              |                                                                                                                |
 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
 All unfinished threads are in deadlock
@@ -64,81 +64,81 @@ Detailed trace:
 |                                                        Thread 1                                                        |                                                    Thread 2                                                    |
 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
 | one(): 1                                                                                                               |                                                                                                                |
-|   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:295)         |                                                                                                                |
-|   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:298)         |                                                                                                                |
-|   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:301)                               |                                                                                                                |
-|   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                               |                                                                                                                |
+|   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:296)         |                                                                                                                |
+|   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:299)         |                                                                                                                |
+|   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                               |                                                                                                                |
+|   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:303)                               |                                                                                                                |
 |   result: 1                                                                                                            |                                                                                                                |
 | one(): 1                                                                                                               |                                                                                                                |
-|   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:295)         |                                                                                                                |
-|   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:298)         |                                                                                                                |
-|   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:301)                               |                                                                                                                |
-|   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                               |                                                                                                                |
+|   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:296)         |                                                                                                                |
+|   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:299)         |                                                                                                                |
+|   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                               |                                                                                                                |
+|   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:303)                               |                                                                                                                |
 |   result: 1                                                                                                            |                                                                                                                |
 | one(): 1                                                                                                               |                                                                                                                |
-|   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:295)         |                                                                                                                |
-|   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:298)         |                                                                                                                |
-|   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:301)                               |                                                                                                                |
-|   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                               |                                                                                                                |
+|   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:296)         |                                                                                                                |
+|   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:299)         |                                                                                                                |
+|   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                               |                                                                                                                |
+|   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:303)                               |                                                                                                                |
 |   result: 1                                                                                                            |                                                                                                                |
 | one(): 1                                                                                                               |                                                                                                                |
-|   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:295)         |                                                                                                                |
-|   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:298)         |                                                                                                                |
-|   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:301)                               |                                                                                                                |
-|   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                               |                                                                                                                |
+|   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:296)         |                                                                                                                |
+|   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:299)         |                                                                                                                |
+|   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                               |                                                                                                                |
+|   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:303)                               |                                                                                                                |
 |   result: 1                                                                                                            |                                                                                                                |
 | two(): 2                                                                                                               |                                                                                                                |
-|   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:309)         |                                                                                                                |
-|   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:312)         |                                                                                                                |
-|   sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:315)                               |                                                                                                                |
-|   sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:316)                               |                                                                                                                |
+|   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:310)         |                                                                                                                |
+|   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:313)         |                                                                                                                |
+|   sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:316)                               |                                                                                                                |
+|   sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:317)                               |                                                                                                                |
 |   result: 2                                                                                                            |                                                                                                                |
 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
 |                                                                                                                        | two(): 2                                                                                                       |
-|                                                                                                                        |   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:309) |
-|                                                                                                                        |   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:312) |
-|                                                                                                                        |   sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:315)                       |
-|                                                                                                                        |   sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:316)                       |
+|                                                                                                                        |   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:310) |
+|                                                                                                                        |   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:313) |
+|                                                                                                                        |   sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:316)                       |
+|                                                                                                                        |   sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:317)                       |
 |                                                                                                                        |   result: 2                                                                                                    |
 |                                                                                                                        | two(): 2                                                                                                       |
-|                                                                                                                        |   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:309) |
-|                                                                                                                        |   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:312) |
-|                                                                                                                        |   sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:315)                       |
-|                                                                                                                        |   sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:316)                       |
+|                                                                                                                        |   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:310) |
+|                                                                                                                        |   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:313) |
+|                                                                                                                        |   sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:316)                       |
+|                                                                                                                        |   sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:317)                       |
 |                                                                                                                        |   result: 2                                                                                                    |
 |                                                                                                                        | two(): 2                                                                                                       |
-|                                                                                                                        |   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:309) |
-|                                                                                                                        |   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:312) |
-|                                                                                                                        |   sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:315)                       |
-|                                                                                                                        |   sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:316)                       |
+|                                                                                                                        |   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:310) |
+|                                                                                                                        |   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:313) |
+|                                                                                                                        |   sharedState2.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:316)                       |
+|                                                                                                                        |   sharedState1.set(false) at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:317)                       |
 |                                                                                                                        |   result: 2                                                                                                    |
 |                                                                                                                        | one(): 1                                                                                                       |
-|                                                                                                                        |   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:295) |
-|                                                                                                                        |   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:298) |
+|                                                                                                                        |   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:296) |
+|                                                                                                                        |   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:299) |
 |                                                                                                                        |   switch                                                                                                       |
 | two(): <hung>                                                                                                          |                                                                                                                |
-|   sharedState2.compareAndSet(false, true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:309)        |                                                                                                                |
-|   meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:310)                                  |                                                                                                                |
+|   sharedState2.compareAndSet(false, true): false at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:310)        |                                                                                                                |
+|   meaninglessActions() at AbstractSpinLivelockTest.two(SpinlockEventsCutTests.kt:311)                                  |                                                                                                                |
 |     /* The following events repeat infinitely: */                                                                      |                                                                                                                |
-| ┌╶> sharedStateAny.get(): false at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:106) |                                                                                                                |
-| |   sharedStateAny.set(true) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107)    |                                                                                                                |
-| |   sharedStateAny.get(): true at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:106)  |                                                                                                                |
-| |   sharedStateAny.set(false) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107)   |                                                                                                                |
+| ┌╶> sharedStateAny.get(): false at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107) |                                                                                                                |
+| |   sharedStateAny.set(true) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:108)    |                                                                                                                |
+| |   sharedStateAny.get(): true at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107)  |                                                                                                                |
+| |   sharedStateAny.set(false) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:108)   |                                                                                                                |
 | └╶╶ switch (reason: active lock detected)                                                                              |                                                                                                                |
-|                                                                                                                        |   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:301)                       |
-|                                                                                                                        |   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                       |
+|                                                                                                                        |   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                       |
+|                                                                                                                        |   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:303)                       |
 |                                                                                                                        |   result: 1                                                                                                    |
 |                                                                                                                        | one(): 1                                                                                                       |
-|                                                                                                                        |   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:295) |
-|                                                                                                                        |   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:298) |
-|                                                                                                                        |   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:301)                       |
-|                                                                                                                        |   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                       |
+|                                                                                                                        |   sharedState1.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:296) |
+|                                                                                                                        |   sharedState2.compareAndSet(false, true): true at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:299) |
+|                                                                                                                        |   sharedState1.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:302)                       |
+|                                                                                                                        |   sharedState2.set(false) at AbstractSpinLivelockTest.one(SpinlockEventsCutTests.kt:303)                       |
 |                                                                                                                        |   result: 1                                                                                                    |
 |     /* The following events repeat infinitely: */                                                                      |                                                                                                                |
-| ┌╶> sharedStateAny.get(): false at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:106) |                                                                                                                |
-| |   sharedStateAny.set(true) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107)    |                                                                                                                |
-| |   sharedStateAny.get(): true at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:106)  |                                                                                                                |
-| |   sharedStateAny.set(false) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107)   |                                                                                                                |
+| ┌╶> sharedStateAny.get(): false at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107) |                                                                                                                |
+| |   sharedStateAny.set(true) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:108)    |                                                                                                                |
+| |   sharedStateAny.get(): true at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:107)  |                                                                                                                |
+| |   sharedStateAny.set(false) at SpinlockEventsCutInfiniteLoopTest.meaninglessActions(SpinlockEventsCutTests.kt:108)   |                                                                                                                |
 | └╶╶ switch (reason: active lock detected)                                                                              |                                                                                                                |
 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
 All unfinished threads are in deadlock


Reviews:
user: login: dmitrii-artuhov
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-05-15T14:28:47Z
user: login: dmitrii-artuhov
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-15T15:29:22Z

Review comments:
diff_hunk: @@ -0,0 +1,81 @@
+/*
+ * Lincheck
+ *
+ * Copyright (C) 2019 - 2025 JetBrains s.r.o.
+ *
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
+ * with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package org.jetbrains.kotlinx.lincheck_test.representation
+
+import org.jetbrains.kotlinx.lincheck.annotations.Operation
+import org.jetbrains.kotlinx.lincheck.checkImpl
+import org.jetbrains.kotlinx.lincheck.isInTraceDebuggerMode
+import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.ModelCheckingOptions
+import org.jetbrains.kotlinx.lincheck_test.util.checkLincheckOutput
+import org.junit.Assume.assumeFalse
+import org.junit.Before
+import org.junit.Test
+import java.util.concurrent.atomic.AtomicReference
+
+/**
+ * Checks that spin-cycle repeated events are cut in case of obstruction freedom violation
+ */
+class ObstructionFreedomViolationEventsCutTest {
+
+    @Before // spin-loop detection is unsupported in trace debugger mode
+    fun setUp() = assumeFalse(isInTraceDebuggerMode)
+
+    private val q = MSQueueBlocking()
+
+    @Operation
+    fun enqueue(x: Int) = q.enqueue(x)
+
+    @Operation
+    fun dequeue(): Int? = q.dequeue()
+
+    @Test
+    fun runModelCheckingTest() = ModelCheckingOptions()
+        .checkObstructionFreedom(true)
+        .checkImpl(this::class.java)
+        .checkLincheckOutput("obstruction_freedom_violation_events_cut")
+}
+
+class MSQueueBlocking {
path: src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/ObstructionFreedomViolationEventsCutTest.kt
user: login: dmitrii-artuhov
body: Now implementation of `MSQueueBlocking` is added to this file, but from where was it taken from? I don't see it in the diff as removed. Is there a duplicate of class `MSQueueBlocking` right now in the source code?
created_at: 2025-05-15T14:06:49Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,81 @@
+/*
+ * Lincheck
+ *
+ * Copyright (C) 2019 - 2025 JetBrains s.r.o.
+ *
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
+ * with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package org.jetbrains.kotlinx.lincheck_test.representation
+
+import org.jetbrains.kotlinx.lincheck.annotations.Operation
+import org.jetbrains.kotlinx.lincheck.checkImpl
+import org.jetbrains.kotlinx.lincheck.isInTraceDebuggerMode
+import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.ModelCheckingOptions
+import org.jetbrains.kotlinx.lincheck_test.util.checkLincheckOutput
+import org.junit.Assume.assumeFalse
+import org.junit.Before
+import org.junit.Test
+import java.util.concurrent.atomic.AtomicReference
+
+/**
+ * Checks that spin-cycle repeated events are cut in case of obstruction freedom violation
+ */
+class ObstructionFreedomViolationEventsCutTest {
+
+    @Before // spin-loop detection is unsupported in trace debugger mode
+    fun setUp() = assumeFalse(isInTraceDebuggerMode)
+
+    private val q = MSQueueBlocking()
+
+    @Operation
+    fun enqueue(x: Int) = q.enqueue(x)
+
+    @Operation
+    fun dequeue(): Int? = q.dequeue()
+
+    @Test
+    fun runModelCheckingTest() = ModelCheckingOptions()
+        .checkObstructionFreedom(true)
+        .checkImpl(this::class.java)
+        .checkLincheckOutput("obstruction_freedom_violation_events_cut")
+}
+
+class MSQueueBlocking {
path: src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/ObstructionFreedomViolationEventsCutTest.kt
user: login: dmitrii-artuhov
body: Tests from `test-integration` can include classes from `test` module. You can define `MSQueueBlocking` in `test` and just include in guide test, because there is the same class defined in `test-integration/org/jetbrains/kotlinx/lincheck_test/guide/ObstructionFreedomViolationTest.kt`
created_at: 2025-05-15T14:21:45Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,81 @@
+/*
+ * Lincheck
+ *
+ * Copyright (C) 2019 - 2025 JetBrains s.r.o.
+ *
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
+ * with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package org.jetbrains.kotlinx.lincheck_test.representation
+
+import org.jetbrains.kotlinx.lincheck.annotations.Operation
+import org.jetbrains.kotlinx.lincheck.checkImpl
+import org.jetbrains.kotlinx.lincheck.isInTraceDebuggerMode
+import org.jetbrains.kotlinx.lincheck.strategy.managed.modelchecking.ModelCheckingOptions
+import org.jetbrains.kotlinx.lincheck_test.util.checkLincheckOutput
+import org.junit.Assume.assumeFalse
+import org.junit.Before
+import org.junit.Test
+import java.util.concurrent.atomic.AtomicReference
+
+/**
+ * Checks that spin-cycle repeated events are cut in case of obstruction freedom violation
+ */
+class ObstructionFreedomViolationEventsCutTest {
path: src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/ObstructionFreedomViolationEventsCutTest.kt
user: login: dmitrii-artuhov
body: why this is required to be put outside of `SpinlockEventsCutTests.kt` file? It logically belongs to other `events cut` tests
created_at: 2025-05-15T14:24:35Z
author_association: COLLABORATOR

PR comments:
user: login: dmitrii-artuhov
created_at: 2025-05-15T15:26:50Z
body: also links to guide tests in docs should be updated (here or as a second PR after merging this one)
author_association: COLLABORATOR
user: login: dmitrii-artuhov
created_at: 2025-05-15T15:31:49Z
body: @eupp please rebase on `develop` and let's merge 
author_association: COLLABORATOR
user: login: eupp
created_at: 2025-05-15T15:37:27Z
body: > also links to guide tests in docs should be updated (here or as a second PR after merging this one)

~~Where are these links mentioned?~~
Nevermind, I've already found and fixed them.
author_association: COLLABORATOR