1 package kotlinx.coroutines 2 3 import kotlinx.coroutines.testing.* 4 import kotlin.test.* 5 6 class NonCancellableTest : TestBase() { 7 @Test <lambda>null8 fun testNonCancellable() = runTest { 9 expect(1) 10 val job = async { 11 withContext(NonCancellable) { 12 expect(2) 13 yield() 14 expect(4) 15 } 16 17 expect(5) 18 yield() 19 expectUnreached() 20 } 21 22 yield() 23 job.cancel() 24 expect(3) 25 assertTrue(job.isCancelled) 26 try { 27 job.await() 28 expectUnreached() 29 } catch (e: JobCancellationException) { 30 if (RECOVER_STACK_TRACES) { 31 val cause = e.cause as JobCancellationException // shall be recovered JCE 32 assertNull(cause.cause) 33 } else { 34 assertNull(e.cause) 35 } 36 finish(6) 37 } 38 } 39 40 @Test <lambda>null41 fun testNonCancellableWithException() = runTest { 42 expect(1) 43 val deferred = async(NonCancellable) { 44 withContext(NonCancellable) { 45 expect(2) 46 yield() 47 expect(4) 48 } 49 50 expect(5) 51 yield() 52 expectUnreached() 53 } 54 55 yield() 56 deferred.cancel(TestCancellationException("TEST")) 57 expect(3) 58 assertTrue(deferred.isCancelled) 59 try { 60 deferred.await() 61 expectUnreached() 62 } catch (e: TestCancellationException) { 63 assertEquals("TEST", e.message) 64 finish(6) 65 } 66 } 67 68 @Test <lambda>null69 fun testNonCancellableFinally() = runTest { 70 expect(1) 71 val job = async { 72 try { 73 expect(2) 74 yield() 75 expectUnreached() 76 } finally { 77 withContext(NonCancellable) { 78 expect(4) 79 yield() 80 expect(5) 81 } 82 } 83 84 expectUnreached() 85 } 86 87 yield() 88 job.cancel() 89 expect(3) 90 assertTrue(job.isCancelled) 91 92 try { 93 job.await() 94 expectUnreached() 95 } catch (e: CancellationException) { 96 finish(6) 97 } 98 } 99 100 @Test <lambda>null101 fun testNonCancellableTwice() = runTest { 102 expect(1) 103 val job = async { 104 withContext(NonCancellable) { 105 expect(2) 106 yield() 107 expect(4) 108 } 109 110 withContext(NonCancellable) { 111 expect(5) 112 yield() 113 expect(6) 114 } 115 } 116 117 yield() 118 job.cancel() 119 expect(3) 120 assertTrue(job.isCancelled) 121 try { 122 job.await() 123 expectUnreached() 124 } catch (e: JobCancellationException) { 125 if (RECOVER_STACK_TRACES) { 126 val cause = e.cause as JobCancellationException // shall be recovered JCE 127 assertNull(cause.cause) 128 } else { 129 assertNull(e.cause) 130 } 131 finish(7) 132 } 133 } 134 } 135