1 /* <lambda>null2 * 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.* 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 }