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 6 7 import kotlin.coroutines.* 8 import kotlin.test.* 9 10 class RunBlockingTest : TestBase() { 11 12 @Test <lambda>null13 fun testWithTimeoutBusyWait() = runBlocking { 14 val value = withTimeoutOrNull(10) { 15 while (isActive) { 16 // Busy wait 17 } 18 "value" 19 } 20 21 assertEquals("value", value) 22 } 23 24 @Test testPrivateEventLoopnull25 fun testPrivateEventLoop() { 26 expect(1) 27 runBlocking { 28 expect(2) 29 assertTrue(coroutineContext[ContinuationInterceptor] is EventLoop) 30 yield() // is supported! 31 expect(3) 32 } 33 finish(4) 34 } 35 36 @Test testOuterEventLoopnull37 fun testOuterEventLoop() { 38 expect(1) 39 runBlocking { 40 expect(2) 41 val outerEventLoop = coroutineContext[ContinuationInterceptor] as EventLoop 42 runBlocking(coroutineContext) { 43 expect(3) 44 // still same event loop 45 assertSame(coroutineContext[ContinuationInterceptor], outerEventLoop) 46 yield() // still works 47 expect(4) 48 } 49 expect(5) 50 } 51 finish(6) 52 } 53 54 @Test testOtherDispatchernull55 fun testOtherDispatcher() { 56 expect(1) 57 val name = "RunBlockingTest.testOtherDispatcher" 58 val thread = newSingleThreadContext(name) 59 runBlocking(thread) { 60 expect(2) 61 assertSame(coroutineContext[ContinuationInterceptor], thread) 62 assertTrue(Thread.currentThread().name.contains(name)) 63 yield() // should work 64 expect(3) 65 } 66 finish(4) 67 thread.close() 68 } 69 70 71 @Test testCancellationnull72 fun testCancellation() = newFixedThreadPoolContext(2, "testCancellation").use { 73 val job = GlobalScope.launch(it) { 74 runBlocking(coroutineContext) { 75 while (true) { 76 yield() 77 } 78 } 79 } 80 81 runBlocking { 82 job.cancelAndJoin() 83 } 84 } 85 86 @Test testCancelWithDelaynull87 fun testCancelWithDelay() { 88 // see https://github.com/Kotlin/kotlinx.coroutines/issues/586 89 try { 90 runBlocking { 91 expect(1) 92 coroutineContext.cancel() 93 expect(2) 94 try { 95 delay(1) 96 expectUnreached() 97 } finally { 98 expect(3) 99 } 100 } 101 expectUnreached() 102 } catch (e: CancellationException) { 103 finish(4) 104 } 105 } 106 107 @Test(expected = CancellationException::class) <lambda>null108 fun testDispatchOnShutdown() = runBlocking<Unit> { 109 expect(1) 110 val job = launch(NonCancellable) { 111 try { 112 expect(2) 113 delay(Long.MAX_VALUE) 114 } finally { 115 finish(4) 116 } 117 } 118 119 yield() 120 expect(3) 121 coroutineContext.cancel() 122 job.cancel() 123 } 124 125 @Test(expected = CancellationException::class) <lambda>null126 fun testDispatchOnShutdown2() = runBlocking<Unit> { 127 coroutineContext.cancel() 128 expect(1) 129 val job = launch(NonCancellable, start = CoroutineStart.UNDISPATCHED) { 130 try { 131 expect(2) 132 delay(Long.MAX_VALUE) 133 } finally { 134 finish(4) 135 } 136 } 137 138 expect(3) 139 job.cancel() 140 } 141 142 @Test <lambda>null143 fun testNestedRunBlocking() = runBlocking { 144 delay(100) 145 val value = runBlocking { 146 delay(100) 147 runBlocking { 148 delay(100) 149 1 150 } 151 } 152 153 assertEquals(1, value) 154 } 155 156 @Test testIncompleteStatenull157 fun testIncompleteState() { 158 val handle = runBlocking { 159 // See #835 160 coroutineContext[Job]!!.invokeOnCompletion { } 161 } 162 163 handle.dispose() 164 } 165 166 @Test testContractnull167 fun testContract() { 168 val rb: Int 169 runBlocking { 170 rb = 42 171 } 172 rb.hashCode() // unused 173 } 174 } 175