1 import kotlinx.coroutines.testing.* 2 import kotlinx.coroutines.* 3 import kotlinx.coroutines.debug.* 4 import kotlinx.coroutines.debug.internal.* 5 import org.junit.* 6 7 /** 8 * This is fast but fragile version of [DebugLeaksStressTest] that check reachability of a captured object 9 * in [DebugProbesImpl] via [FieldWalker]. 10 */ 11 @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") 12 class DebugLeaksTest : DebugTestBase() { 13 private class Captured 14 15 @Test testIteratorLeaknull16 fun testIteratorLeak() { 17 val captured = Captured() 18 iterator { yield(captured) } 19 assertNoCapturedReference() 20 } 21 22 @Test testLazyGlobalCoroutineLeaknull23 fun testLazyGlobalCoroutineLeak() { 24 val captured = Captured() 25 GlobalScope.launch(start = CoroutineStart.LAZY) { println(captured) } 26 assertNoCapturedReference() 27 } 28 29 @Test <lambda>null30 fun testLazyCancelledChildCoroutineLeak() = runTest { 31 val captured = Captured() 32 coroutineScope { 33 val child = launch(start = CoroutineStart.LAZY) { println(captured) } 34 child.cancel() 35 } 36 assertNoCapturedReference() 37 } 38 39 @Test testAbandonedGlobalCoroutineLeaknull40 fun testAbandonedGlobalCoroutineLeak() { 41 val captured = Captured() 42 GlobalScope.launch { 43 suspendForever() 44 println(captured) 45 } 46 assertNoCapturedReference() 47 } 48 <lambda>null49 private suspend fun suspendForever() = suspendCancellableCoroutine<Unit> { } 50 assertNoCapturedReferencenull51 private fun assertNoCapturedReference() { 52 FieldWalker.assertReachableCount(0, DebugProbesImpl, rootStatics = true) { it is Captured } 53 } 54 } 55