blob: 7a59783c58df9f5233ec54645d091de54c662555 [file] [log] [blame]
import kotlinx.coroutines.testing.*
import kotlinx.coroutines.*
import kotlinx.coroutines.debug.*
import kotlinx.coroutines.debug.internal.*
import org.junit.*
/**
* This is fast but fragile version of [DebugLeaksStressTest] that check reachability of a captured object
* in [DebugProbesImpl] via [FieldWalker].
*/
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
class DebugLeaksTest : DebugTestBase() {
private class Captured
@Test
fun testIteratorLeak() {
val captured = Captured()
iterator { yield(captured) }
assertNoCapturedReference()
}
@Test
fun testLazyGlobalCoroutineLeak() {
val captured = Captured()
GlobalScope.launch(start = CoroutineStart.LAZY) { println(captured) }
assertNoCapturedReference()
}
@Test
fun testLazyCancelledChildCoroutineLeak() = runTest {
val captured = Captured()
coroutineScope {
val child = launch(start = CoroutineStart.LAZY) { println(captured) }
child.cancel()
}
assertNoCapturedReference()
}
@Test
fun testAbandonedGlobalCoroutineLeak() {
val captured = Captured()
GlobalScope.launch {
suspendForever()
println(captured)
}
assertNoCapturedReference()
}
private suspend fun suspendForever() = suspendCancellableCoroutine<Unit> { }
private fun assertNoCapturedReference() {
FieldWalker.assertReachableCount(0, DebugProbesImpl, rootStatics = true) { it is Captured }
}
}