blob: c2656d346b73b06c439915c67fc2b6fcedf0983f [file] [log] [blame]
/*
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.coroutines.debug
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
import org.junit.Test
import kotlin.test.*
class StartModeProbesTest : DebugTestBase() {
@Test
fun testUndispatched() = runTest {
expect(1)
val job = launch(start = CoroutineStart.UNDISPATCHED) {
expect(2)
undispatchedSleeping()
assertTrue(true)
}
yield()
expect(3)
verifyPartialDump(2, "StartModeProbesTest.undispatchedSleeping")
job.cancelAndJoin()
verifyPartialDump(1, "StartModeProbesTest\$testUndispatched")
finish(4)
}
private suspend fun undispatchedSleeping() {
delay(Long.MAX_VALUE)
assertTrue(true)
}
@Test
fun testWithTimeoutWithUndispatched() = runTest {
expect(1)
val job = launchUndispatched()
yield()
expect(3)
verifyPartialDump(
2,
"StartModeProbesTest\$launchUndispatched\$1.invokeSuspend",
"StartModeProbesTest.withTimeoutHelper",
"StartModeProbesTest\$withTimeoutHelper\$2.invokeSuspend"
)
job.cancelAndJoin()
verifyPartialDump(1, "StartModeProbesTest\$testWithTimeoutWithUndispatched")
finish(4)
}
private fun CoroutineScope.launchUndispatched(): Job {
return launch(start = CoroutineStart.UNDISPATCHED) {
withTimeoutHelper()
assertTrue(true)
}
}
private suspend fun withTimeoutHelper() {
withTimeout(Long.MAX_VALUE) {
expect(2)
delay(Long.MAX_VALUE)
}
assertTrue(true)
}
@Test
fun testWithTimeout() = runTest {
withTimeout(Long.MAX_VALUE) {
testActiveDump(
false,
"StartModeProbesTest\$testWithTimeout\$1.invokeSuspend",
"state: RUNNING"
)
}
}
@Test
fun testWithTimeoutAfterYield() = runTest {
withTimeout(Long.MAX_VALUE) {
testActiveDump(
true,
"StartModeProbesTest\$testWithTimeoutAfterYield\$1.invokeSuspend",
"StartModeProbesTest\$testWithTimeoutAfterYield\$1\$1.invokeSuspend",
"StartModeProbesTest.testActiveDump",
"state: RUNNING"
)
}
}
private suspend fun testActiveDump(shouldYield: Boolean, vararg expectedFrames: String) {
if (shouldYield) yield()
verifyPartialDump(1, *expectedFrames)
assertTrue(true)
}
@Test
fun testWithTailCall() = runTest {
expect(1)
val job = tailCallMethod()
yield()
expect(3)
verifyPartialDump(2, "StartModeProbesTest\$launchFromTailCall\$2")
job.cancelAndJoin()
verifyPartialDump(1, "StartModeProbesTest\$testWithTailCall")
finish(4)
}
private suspend fun CoroutineScope.tailCallMethod(): Job = launchFromTailCall()
private suspend fun CoroutineScope.launchFromTailCall(): Job = launch {
expect(2)
delay(Long.MAX_VALUE)
}
@Test
fun testCoroutineScope() = runTest {
expect(1)
val job = launch(start = CoroutineStart.UNDISPATCHED) {
runScope()
}
yield()
expect(3)
verifyPartialDump(
2,
"StartModeProbesTest\$runScope\$2.invokeSuspend",
"StartModeProbesTest\$testCoroutineScope\$1\$job\$1.invokeSuspend")
job.cancelAndJoin()
finish(4)
}
private suspend fun runScope() {
coroutineScope {
expect(2)
delay(Long.MAX_VALUE)
}
}
@Test
fun testLazy() = runTest({ it is CancellationException }) {
launch(start = CoroutineStart.LAZY) { }
actor<Int>(start = CoroutineStart.LAZY) { }
broadcast<Int>(start = CoroutineStart.LAZY) { }
async(start = CoroutineStart.LAZY) { 1 }
verifyPartialDump(5, "BlockingCoroutine",
"LazyStandaloneCoroutine", "LazyActorCoroutine",
"LazyBroadcastCoroutine", "LazyDeferredCoroutine")
cancel()
}
}