blob: 06957ff733fabcc7344e31fb99166b8acdd43d11 [file] [log] [blame]
Vsevolod Tolstopyatov3ac73f62018-07-26 16:09:33 +03001package kotlinx.coroutines.experimental.scheduling
2
3import kotlinx.coroutines.experimental.*
4import org.junit.*
5import java.util.concurrent.atomic.*
6
7class BlockingCoroutineDispatcherRaceStressTest : SchedulerTestBase() {
8 private val concurrentWorkers = AtomicInteger(0)
9
10 @Before
11 fun setUp() {
12 // In case of starvation test will hang
13 idleWorkerKeepAliveNs = Long.MAX_VALUE
14 }
15
16 @Test
17 fun testAddPollRace() = runBlocking {
18 val limitingDispatcher = blockingDispatcher(1)
19 val iterations = 25_000 * stressTestMultiplier
20 // Stress test for specific case (race #2 from LimitingDispatcher). Shouldn't hang.
21 for (i in 1..iterations) {
22 val tasks = (1..2).map {
23 async(limitingDispatcher) {
24 try {
25 val currentlyExecuting = concurrentWorkers.incrementAndGet()
26 require(currentlyExecuting == 1)
27 } finally {
28 concurrentWorkers.decrementAndGet()
29 }
30 }
31 }
32
33 tasks.forEach { it.await() }
34 }
35
Vsevolod Tolstopyatov68391512018-08-13 12:46:53 +030036 checkPoolThreadsCreated(2..4)
Vsevolod Tolstopyatov3ac73f62018-07-26 16:09:33 +030037 }
38
39 @Test
40 fun testPingPongThreadsCount() = runBlocking {
41 corePoolSize = CORES_COUNT
42 val iterations = 100_000 * stressTestMultiplier
43 // Stress test for specific case (race #2 from LimitingDispatcher). Shouldn't hang.
44 for (i in 1..iterations) {
45 val tasks = (1..2).map {
46 async(dispatcher) {
47 // Useless work
48 concurrentWorkers.incrementAndGet()
49 concurrentWorkers.decrementAndGet()
50 }
51 }
52
53 tasks.forEach { it.await() }
54 }
55
56 checkPoolThreadsCreated(CORES_COUNT)
57 }
58}