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