Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add failing Kotlin coroutine tests #8238

Merged
merged 1 commit into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ class KotlinCoroutineTests(dispatcher: CoroutineDispatcher) : CoreKotlinCoroutin
return super.tracedWithLazyStarting()
}

@Trace
override fun traceAfterTimeout(): Int {
return super.traceAfterTimeout()
}

@Trace
override fun tracedChild(opName: String) {
super.tracedChild(opName)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import datadog.trace.core.DDSpan
import datadog.trace.instrumentation.kotlin.coroutines.AbstractKotlinCoroutineInstrumentationTest
import kotlinx.coroutines.CoroutineDispatcher
import spock.lang.Ignore

class KotlinCoroutineInstrumentationTest extends AbstractKotlinCoroutineInstrumentationTest<KotlinCoroutineTests> {

Expand Down Expand Up @@ -42,4 +43,33 @@ class KotlinCoroutineInstrumentationTest extends AbstractKotlinCoroutineInstrume
where:
[dispatcherName, dispatcher] << dispatchersToTest
}

@Ignore("Not working: disconnected trace")
def "kotlin trace consistent after flow"() {
setup:
KotlinCoroutineTests kotlinTest = new KotlinCoroutineTests(dispatcher)
int expectedNumberOfSpans = kotlinTest.traceAfterFlow()
TEST_WRITER.waitForTraces(1)

expect:
assertTraces(1) {
trace(expectedNumberOfSpans, true) {
span(2) {
operationName "trace.annotation"
parent()
}
span(1) {
operationName "outside-flow"
childOf span(2)
}
span(0) {
operationName "inside-flow"
childOf span(2)
}
}
}

where:
[dispatcherName, dispatcher] << dispatchersToTest
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import datadog.trace.api.Trace
import datadog.trace.instrumentation.kotlin.coroutines.CoreKotlinCoroutineTests
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.single
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeout

Expand Down Expand Up @@ -35,6 +37,23 @@ class KotlinCoroutineTests(dispatcher: CoroutineDispatcher) : CoreKotlinCoroutin
7
}

@Trace
fun traceAfterFlow(): Int = runTest {
val f = flow {
childSpan("inside-flow").activateAndUse {
println("insideFlowSpan")
}
emit(1)
}.flowOn(Dispatchers.IO)
val ff = f.single()
// FIXME: This span is detached
childSpan("outside-flow").activateAndUse {
println("hello $ff")
}

3
}

@Trace
override fun tracePreventedByCancellation(): Int {
return super.tracePreventedByCancellation()
Expand Down Expand Up @@ -65,6 +84,11 @@ class KotlinCoroutineTests(dispatcher: CoroutineDispatcher) : CoreKotlinCoroutin
return super.tracedWithLazyStarting()
}

@Trace
override fun traceAfterTimeout(): Int {
return super.traceAfterTimeout()
}

@Trace
override fun tracedChild(opName: String) {
super.tracedChild(opName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import datadog.trace.core.DDSpan
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ThreadPoolDispatcherKt
import spock.lang.Ignore
import spock.lang.Shared

abstract class AbstractKotlinCoroutineInstrumentationTest<T extends CoreKotlinCoroutineTests> extends AgentTestRunner {
Expand Down Expand Up @@ -365,6 +366,46 @@ abstract class AbstractKotlinCoroutineInstrumentationTest<T extends CoreKotlinCo
[dispatcherName, dispatcher] << dispatchersToTest
}

@Ignore("Not working: disconnected trace")
def "kotlin trace consistent with timeout"() {
setup:
CoreKotlinCoroutineTests kotlinTest = getCoreKotlinCoroutineTestsInstance(dispatcher)
int expectedNumberOfSpans = kotlinTest.traceAfterTimeout()

expect:
assertTraces(1) {
trace(expectedNumberOfSpans, true) {
span(5) {
operationName "top-level"
parent()
}
span(0) {
operationName "1-before-timeout"
childOf span(5)
}
span(1) {
operationName "2-inside-timeout"
childOf span(5)
}
span(2) {
operationName "3-after-timeout"
childOf span(5)
}
span(3) {
operationName "4-after-timeout-2"
childOf span(5)
}
span(4) {
operationName "5-after-timeout-3"
childOf span(5)
}
}
}

where:
[dispatcherName, dispatcher] << dispatchersToTest
}

protected static DDSpan findSpan(List<DDSpan> trace, String opName) {
for (DDSpan span : trace) {
if (span.getOperationName() == opName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,30 @@ abstract class CoreKotlinCoroutineTests(private val dispatcher: CoroutineDispatc
1
}

@Trace
open fun traceAfterTimeout(): Int = runTest {
childSpan("1-before-timeout").activateAndUse {
delay(10)
}
withTimeout(50) {
childSpan("2-inside-timeout").activateAndUse {
delay(10)
}
}
// FIXME: This span is detached
childSpan("3-after-timeout").activateAndUse {
delay(10)
}
childSpan("4-after-timeout-2").activateAndUse {
delay(10)
}
childSpan("5-after-timeout-3").activateAndUse {
delay(10)
}

6
}

@Trace
protected open fun tracedChild(opName: String) {
activeSpan().setSpanName(opName)
Expand Down
Loading