• 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.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