• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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