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