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.experimental
6
+
7
+ import org.junit.*
8
+ import org.junit.Test
9
+ import java.util.concurrent.*
10
+ import kotlin.test.*
11
+
12
+ class JobChildStressTest : TestBase () {
13
+ private val N_ITERATIONS = 10_000 * stressTestMultiplier
14
+ private val pool = newFixedThreadPoolContext(3 , " JobChildStressTest" )
15
+
16
+ @After
17
+ fun tearDown () {
18
+ pool.close()
19
+ }
20
+
21
+ /* *
22
+ * Perform concurrent launch of a child job & cancellation of the explicit parent job
23
+ */
24
+ @Test
25
+ @Suppress(" PLATFORM_CLASS_MAPPED_TO_KOTLIN" )
26
+ fun testChild () = runTest {
27
+ val barrier = CyclicBarrier (3 )
28
+ repeat(N_ITERATIONS ) {
29
+ var wasLaunched = false
30
+ var unhandledException: Throwable ? = null
31
+ val handler = CoroutineExceptionHandler { _, ex ->
32
+ unhandledException = ex
33
+ }
34
+ val scope = CoroutineScope (pool + handler)
35
+ val parent = CompletableDeferred <Unit >()
36
+ // concurrent child launcher
37
+ val launcher = scope.launch {
38
+ barrier.await()
39
+ // A: launch child for a parent job
40
+ launch(parent) {
41
+ wasLaunched = true
42
+ throw TestException ()
43
+ }
44
+ }
45
+ // concurrent cancel
46
+ val canceller = scope.launch {
47
+ barrier.await()
48
+ // B: cancel parent job of a child
49
+ parent.cancel()
50
+ }
51
+ barrier.await()
52
+ joinAll(launcher, canceller, parent)
53
+ assertNull(unhandledException)
54
+ if (wasLaunched) {
55
+ val exception = parent.getCompletionExceptionOrNull()
56
+ assertTrue(exception is TestException , " exception=$exception " )
57
+ }
58
+ }
59
+ }
60
+
61
+ private class TestException : Exception ()
62
+ }
0 commit comments