1 package kotlinx.coroutines.debug 2 3 import kotlinx.coroutines.testing.* 4 import kotlinx.coroutines.* 5 import kotlinx.coroutines.channels.* 6 import org.junit.Test 7 import kotlin.test.* 8 9 class StartModeProbesTest : DebugTestBase() { 10 11 @Test testUndispatchednull12 fun testUndispatched() = runTest { 13 expect(1) 14 val job = launch(start = CoroutineStart.UNDISPATCHED) { 15 expect(2) 16 undispatchedSleeping() 17 assertTrue(true) 18 } 19 20 yield() 21 expect(3) 22 verifyPartialDump(2, "StartModeProbesTest.undispatchedSleeping") 23 job.cancelAndJoin() 24 verifyPartialDump(1, "StartModeProbesTest\$testUndispatched") 25 finish(4) 26 } 27 undispatchedSleepingnull28 private suspend fun undispatchedSleeping() { 29 delay(Long.MAX_VALUE) 30 assertTrue(true) 31 } 32 33 @Test <lambda>null34 fun testWithTimeoutWithUndispatched() = runTest { 35 expect(1) 36 val job = launchUndispatched() 37 38 yield() 39 expect(3) 40 verifyPartialDump( 41 2, 42 "StartModeProbesTest\$launchUndispatched\$1.invokeSuspend", 43 "StartModeProbesTest.withTimeoutHelper", 44 "StartModeProbesTest\$withTimeoutHelper\$2.invokeSuspend" 45 ) 46 job.cancelAndJoin() 47 verifyPartialDump(1, "StartModeProbesTest\$testWithTimeoutWithUndispatched") 48 finish(4) 49 } 50 launchUndispatchednull51 private fun CoroutineScope.launchUndispatched(): Job { 52 return launch(start = CoroutineStart.UNDISPATCHED) { 53 withTimeoutHelper() 54 assertTrue(true) 55 } 56 } 57 withTimeoutHelpernull58 private suspend fun withTimeoutHelper() { 59 withTimeout(Long.MAX_VALUE) { 60 expect(2) 61 delay(Long.MAX_VALUE) 62 } 63 64 assertTrue(true) 65 } 66 67 @Test <lambda>null68 fun testWithTimeout() = runTest { 69 withTimeout(Long.MAX_VALUE) { 70 testActiveDump( 71 false, 72 "StartModeProbesTest\$testWithTimeout\$1.invokeSuspend", 73 "state: RUNNING" 74 ) 75 } 76 } 77 78 @Test <lambda>null79 fun testWithTimeoutAfterYield() = runTest { 80 withTimeout(Long.MAX_VALUE) { 81 testActiveDump( 82 true, 83 "StartModeProbesTest\$testWithTimeoutAfterYield\$1.invokeSuspend", 84 "StartModeProbesTest\$testWithTimeoutAfterYield\$1\$1.invokeSuspend", 85 "StartModeProbesTest.testActiveDump", 86 "state: RUNNING" 87 ) 88 } 89 } 90 testActiveDumpnull91 private suspend fun testActiveDump(shouldYield: Boolean, vararg expectedFrames: String) { 92 if (shouldYield) yield() 93 verifyPartialDump(1, *expectedFrames) 94 assertTrue(true) 95 } 96 97 @Test <lambda>null98 fun testWithTailCall() = runTest { 99 expect(1) 100 val job = tailCallMethod() 101 yield() 102 expect(3) 103 verifyPartialDump(2, "StartModeProbesTest\$launchFromTailCall\$2") 104 job.cancelAndJoin() 105 verifyPartialDump(1, "StartModeProbesTest\$testWithTailCall") 106 finish(4) 107 } 108 tailCallMethodnull109 private suspend fun CoroutineScope.tailCallMethod(): Job = launchFromTailCall() 110 private suspend fun CoroutineScope.launchFromTailCall(): Job = launch { 111 expect(2) 112 delay(Long.MAX_VALUE) 113 } 114 115 @Test <lambda>null116 fun testCoroutineScope() = runTest { 117 expect(1) 118 val job = launch(start = CoroutineStart.UNDISPATCHED) { 119 runScope() 120 } 121 122 yield() 123 expect(3) 124 verifyPartialDump( 125 2, 126 "StartModeProbesTest\$runScope\$2.invokeSuspend", 127 "StartModeProbesTest\$testCoroutineScope\$1\$job\$1.invokeSuspend") 128 job.cancelAndJoin() 129 finish(4) 130 } 131 runScopenull132 private suspend fun runScope() { 133 coroutineScope { 134 expect(2) 135 delay(Long.MAX_VALUE) 136 } 137 } 138 139 @Test <lambda>null140 fun testLazy() = runTest({ it is CancellationException }) { <lambda>null141 launch(start = CoroutineStart.LAZY) { } <lambda>null142 actor<Int>(start = CoroutineStart.LAZY) { } <lambda>null143 broadcast<Int>(start = CoroutineStart.LAZY) { } <lambda>null144 async(start = CoroutineStart.LAZY) { 1 } 145 verifyPartialDump(5, "BlockingCoroutine", 146 "LazyStandaloneCoroutine", "LazyActorCoroutine", 147 "LazyBroadcastCoroutine", "LazyDeferredCoroutine") 148 cancel() 149 } 150 } 151