1 /* <lambda>null2 * Copyright 2016-2021 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 kotlin.coroutines.* 8 import kotlin.test.* 9 10 /** 11 * Test a race between job failure and join. 12 * 13 * See [#1123](https://github.com/Kotlin/kotlinx.coroutines/issues/1123). 14 */ 15 class JobStructuredJoinStressTest : TestBase() { 16 private val nRepeats = 10_000 * stressTestMultiplier 17 18 @Test 19 fun testStressRegularJoin() = runMtTest { 20 stress(Job::join) 21 } 22 23 @Test 24 fun testStressSuspendCancellable() = runMtTest { 25 stress { job -> 26 suspendCancellableCoroutine { cont -> 27 job.invokeOnCompletion { cont.resume(Unit) } 28 } 29 } 30 } 31 32 @Test 33 fun testStressSuspendCancellableReusable() = runMtTest { 34 stress { job -> 35 suspendCancellableCoroutineReusable { cont -> 36 job.invokeOnCompletion { cont.resume(Unit) } 37 } 38 } 39 } 40 41 private fun stress(join: suspend (Job) -> Unit) { 42 expect(1) 43 repeat(nRepeats) { index -> 44 assertFailsWith<TestException> { 45 runBlocking { 46 // launch in background 47 val job = launch(Dispatchers.Default) { 48 throw TestException("OK") // crash 49 } 50 try { 51 join(job) 52 error("Should not complete successfully") 53 } catch (e: CancellationException) { 54 // must always crash with cancellation exception 55 expect(2 + index) 56 } catch (e: Throwable) { 57 error("Unexpected exception", e) 58 } 59 } 60 } 61 } 62 finish(2 + nRepeats) 63 } 64 } 65