1 /*
2  * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 package kotlinx.coroutines
6 
7 import org.junit.*
8 import org.junit.Test
9 import java.util.concurrent.atomic.*
10 import kotlin.test.*
11 
12 /**
13  * Stress test for [runInterruptible].
14  * It does not pass on JDK 1.6 on Windows: [Thread.sleep] times out without being interrupted despite the
15  * fact that thread interruption flag is set.
16  */
17 class RunInterruptibleStressTest : TestBase() {
18     @get:Rule
19     val dispatcher = ExecutorRule(4)
20     private val repeatTimes = 1000 * stressTestMultiplier
21 
22     @Test
<lambda>null23     fun testStress() = runTest {
24         val enterCount = AtomicInteger(0)
25         val interruptedCount = AtomicInteger(0)
26 
27         repeat(repeatTimes) {
28             val job = launch(dispatcher) {
29                 try {
30                     runInterruptible {
31                         enterCount.incrementAndGet()
32                         try {
33                             Thread.sleep(10_000)
34                             error("Sleep was not interrupted, Thread.isInterrupted=${Thread.currentThread().isInterrupted}")
35                         } catch (e: InterruptedException) {
36                             interruptedCount.incrementAndGet()
37                             throw e
38                         }
39                     }
40                 } catch (e: CancellationException) {
41                     // Expected
42                 } finally {
43                     assertFalse(Thread.currentThread().isInterrupted, "Interrupt flag should not leak")
44                 }
45             }
46             // Add dispatch delay
47             val cancelJob = launch(dispatcher) {
48                 job.cancel()
49             }
50             joinAll(job, cancelJob)
51         }
52         println("Entered runInterruptible ${enterCount.get()} times")
53         assertTrue(enterCount.get() > 0) // ensure timing is Ok and we don't cancel it all prematurely
54         assertEquals(enterCount.get(), interruptedCount.get())
55     }
56 }
57