Skip to content

Commit 5592838

Browse files
committed
Filter out "java.util.concurrent" frames from debugging test machinery
We do rely on java.util.concurrent primitives for rendezvous in tests, but we cannot rely on their internal stacktraces in tests, thus filtering them out from test data. Otherwise, tests outcome depends on the underlying JDK version Fixes #3700
1 parent c1cb323 commit 5592838

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

kotlinx-coroutines-debug/test/RunningThreadStackMergeTest.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/*
22
* Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
33
*/
4-
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
54
package kotlinx.coroutines.debug
65

76
import kotlinx.coroutines.*
@@ -170,7 +169,8 @@ class RunningThreadStackMergeTest : DebugTestBase() {
170169
assertTrue(true)
171170
}
172171

173-
@Test
172+
@Test // IDEA-specific debugger API test
173+
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
174174
fun testActiveThread() = runBlocking<Unit> {
175175
launchCoroutine()
176176
awaitCoroutineStarted()

kotlinx-coroutines-debug/test/StacktraceUtils.kt

+19-4
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ private fun cleanBlockHoundTraces(frames: List<String>): List<String> {
7474
return result
7575
}
7676

77+
/**
78+
* Removes all frames that contain "java.util.concurrent" in it.
79+
*
80+
* We do leverage Java's locks for proper rendezvous and to fix the coroutine stack's state,
81+
* but this API doesn't have (nor expected to) stable stacktrace, so we are filtering all such
82+
* frames out.
83+
*
84+
* See https://github.com/Kotlin/kotlinx.coroutines/issues/3700 for the example of failure
85+
*/
86+
private fun removeJavaUtilConcurrentTraces(frames: List<String>): List<String> =
87+
frames.filter { !it.contains("java.util.concurrent") }
88+
7789
private data class CoroutineDump(
7890
val header: CoroutineDumpHeader,
7991
val coroutineStackTrace: List<String>,
@@ -185,7 +197,9 @@ public fun verifyDump(vararg expectedTraces: String, ignoredCoroutine: String? =
185197
.drop(1)
186198
// Parse dumps and filter out ignored coroutines
187199
.mapNotNull { trace ->
188-
val dump = CoroutineDump.parse(trace, traceCleaner = ::cleanBlockHoundTraces)
200+
val dump = CoroutineDump.parse(trace, {
201+
removeJavaUtilConcurrentTraces(cleanBlockHoundTraces(it))
202+
})
189203
if (dump.header.className == ignoredCoroutine) {
190204
null
191205
} else {
@@ -194,9 +208,10 @@ public fun verifyDump(vararg expectedTraces: String, ignoredCoroutine: String? =
194208
}
195209

196210
assertEquals(expectedTraces.size, dumps.size)
197-
dumps.zip(expectedTraces.map(CoroutineDump::parse)).forEach { (dump, expectedDump) ->
198-
dump.verify(expectedDump)
199-
}
211+
dumps.zip(expectedTraces.map { CoroutineDump.parse(it, ::removeJavaUtilConcurrentTraces) })
212+
.forEach { (dump, expectedDump) ->
213+
dump.verify(expectedDump)
214+
}
200215
}
201216

202217
public fun String.trimPackage() = replace("kotlinx.coroutines.debug.", "")

0 commit comments

Comments
 (0)