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 @file:Suppress("PackageDirectoryMismatch") 6 package definitely.not.kotlinx.coroutines 7 8 import kotlinx.coroutines.* 9 import kotlinx.coroutines.debug.* 10 import kotlinx.coroutines.selects.* 11 import org.junit.* 12 import org.junit.Test 13 import java.util.concurrent.* 14 import kotlin.test.* 15 16 class SanitizedProbesTest : DebugTestBase() { 17 @Before setUpnull18 override fun setUp() { 19 super.setUp() 20 DebugProbes.sanitizeStackTraces = true 21 } 22 23 @Test <lambda>null24 fun testRecoveredStackTrace() = runTest { 25 val deferred = createDeferred() 26 val traces = listOf( 27 "java.util.concurrent.ExecutionException\n" + 28 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest\$createDeferredNested\$1.invokeSuspend(SanitizedProbesTest.kt:97)\n" + 29 "\tat _COROUTINE._BOUNDARY._(CoroutineDebugging.kt)\n" + 30 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest.oneMoreNestedMethod(SanitizedProbesTest.kt:67)\n" + 31 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest.nestedMethod(SanitizedProbesTest.kt:61)\n" + 32 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest\$testRecoveredStackTrace\$1.invokeSuspend(SanitizedProbesTest.kt:50)\n" + 33 "\tat _COROUTINE._CREATION._(CoroutineDebugging.kt)\n" + 34 "\tat kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt.createCoroutineUnintercepted(IntrinsicsJvm.kt:116)\n" + 35 "\tat kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:23)\n" + 36 "\tat kotlinx.coroutines.TestBase.runTest\$default(TestBase.kt:141)\n" + 37 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest.testRecoveredStackTrace(SanitizedProbesTest.kt:33)", 38 "Caused by: java.util.concurrent.ExecutionException\n" + 39 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest\$createDeferredNested\$1.invokeSuspend(SanitizedProbesTest.kt:57)\n" + 40 "\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)\n" 41 ) 42 nestedMethod(deferred, traces) 43 deferred.join() 44 } 45 46 @Test <lambda>null47 fun testCoroutinesDump() = runTest { 48 val deferred = createActiveDeferred() 49 yield() 50 verifyDump( 51 "Coroutine \"coroutine#3\":BlockingCoroutine{Active}@7d68ef40, state: RUNNING\n" + 52 "\tat java.lang.Thread.getStackTrace(Thread.java)\n" + 53 "\tat _COROUTINE._CREATION._(CoroutineDebugging.kt)\n" + 54 "\tat kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt.createCoroutineUnintercepted(IntrinsicsJvm.kt:116)\n" + 55 "\tat kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:23)\n" + 56 "\tat kotlinx.coroutines.TestBase.runTest\$default(TestBase.kt:141)\n" + 57 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest.testCoroutinesDump(SanitizedProbesTest.kt:56)", 58 59 "Coroutine \"coroutine#4\":DeferredCoroutine{Active}@75c072cb, state: SUSPENDED\n" + 60 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest\$createActiveDeferred\$1.invokeSuspend(SanitizedProbesTest.kt:63)\n" + 61 "\tat _COROUTINE._CREATION._(CoroutineDebugging.kt)\n" + 62 "\tat kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt.createCoroutineUnintercepted(IntrinsicsJvm.kt:116)\n" + 63 "\tat kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:23)\n" + 64 "\tat kotlinx.coroutines.BuildersKt__Builders_commonKt.async\$default(Builders.common.kt)\n" + 65 "\tat kotlinx.coroutines.BuildersKt.async\$default(Unknown Source)\n" + 66 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest.createActiveDeferred(SanitizedProbesTest.kt:62)\n" + 67 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest.access\$createActiveDeferred(SanitizedProbesTest.kt:16)\n" + 68 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest\$testCoroutinesDump\$1.invokeSuspend(SanitizedProbesTest.kt:57)\n" + 69 "\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)\n" + 70 "\tat kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:237)\n" + 71 "\tat kotlinx.coroutines.TestBase.runTest\$default(TestBase.kt:141)\n" + 72 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest.testCoroutinesDump(SanitizedProbesTest.kt:56)" 73 ) 74 deferred.cancelAndJoin() 75 } 76 77 @Test <lambda>null78 fun testSelectBuilder() = runTest { 79 val selector = launchSelector() 80 expect(1) 81 yield() 82 expect(3) 83 verifyDump("Coroutine \"coroutine#1\":BlockingCoroutine{Active}@35fc6dc4, state: RUNNING\n" + 84 "\tat java.lang.Thread.getStackTrace(Thread.java:1552)\n" + // Skip the rest 85 "\tat _COROUTINE._CREATION._(CoroutineDebugging.kt)\n" + 86 "\tat kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt.createCoroutineUnintercepted(IntrinsicsJvm.kt:116)", 87 88 "Coroutine \"coroutine#2\":StandaloneCoroutine{Active}@1b68b9a4, state: SUSPENDED\n" + 89 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest\$launchSelector\$1\$1\$1.invokeSuspend(SanitizedProbesTest.kt)\n" + 90 "\tat _COROUTINE._CREATION._(CoroutineDebugging.kt)\n" + 91 "\tat kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt.createCoroutineUnintercepted(IntrinsicsJvm.kt:116)\n" + 92 "\tat kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:25)\n" + 93 "\tat kotlinx.coroutines.BuildersKt__Builders_commonKt.launch\$default(Builders.common.kt)\n" + 94 "\tat kotlinx.coroutines.BuildersKt.launch\$default(Unknown Source)\n" + 95 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest.launchSelector(SanitizedProbesTest.kt:100)\n" + 96 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest.access\$launchSelector(SanitizedProbesTest.kt:16)\n" + 97 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest\$testSelectBuilder\$1.invokeSuspend(SanitizedProbesTest.kt:89)\n" + 98 "\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)\n" + 99 "\tat kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:233)\n" + 100 "\tat kotlinx.coroutines.TestBase.runTest\$default(TestBase.kt:154)\n" + 101 "\tat definitely.not.kotlinx.coroutines.SanitizedProbesTest.testSelectBuilder(SanitizedProbesTest.kt:88)") 102 finish(4) 103 selector.cancelAndJoin() 104 } 105 launchSelectornull106 private fun CoroutineScope.launchSelector(): Job { 107 val job = CompletableDeferred(Unit) 108 return launch { 109 select<Int> { 110 job.onJoin { 111 expect(2) 112 delay(Long.MAX_VALUE) 113 1 114 } 115 } 116 } 117 } 118 <lambda>null119 private fun CoroutineScope.createActiveDeferred(): Deferred<*> = async { 120 suspendingMethod() 121 assertTrue(true) 122 } 123 suspendingMethodnull124 private suspend fun suspendingMethod() { 125 delay(Long.MAX_VALUE) 126 } 127 createDeferrednull128 private fun CoroutineScope.createDeferred(): Deferred<*> = createDeferredNested() 129 130 private fun CoroutineScope.createDeferredNested(): Deferred<*> = async(NonCancellable) { 131 throw ExecutionException(null) 132 } 133 nestedMethodnull134 private suspend fun nestedMethod(deferred: Deferred<*>, traces: List<String>) { 135 oneMoreNestedMethod(deferred, traces) 136 assertTrue(true) // Prevent tail-call optimization 137 } 138 oneMoreNestedMethodnull139 private suspend fun oneMoreNestedMethod(deferred: Deferred<*>, traces: List<String>) { 140 try { 141 deferred.await() 142 expectUnreached() 143 } catch (e: ExecutionException) { 144 verifyStackTrace(e, traces) 145 } 146 } 147 } 148