Skip to content
Draft
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
21 changes: 5 additions & 16 deletions dd-smoke-tests/concurrent/java-25/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ plugins {
}

testJvmConstraints {
// This smoke test should be limited to Java 25 and above
// But the groovy testing framework cannot run on Java 25
// Using Java 8 for now and runs a JVM 25 when forking tests process.
// Relying on forked JVM 25 is hardcoded in the test suites (see createProcessBuilder()).
minJavaVersion = JavaVersion.VERSION_1_8
maxJavaVersion = JavaVersion.VERSION_1_8
// Only runs on Temurin build as it spawns a Temurin 25 for test process.
excludeJdk = ['IBM8', 'SEMERU8']
minJavaVersion = JavaVersion.VERSION_25
// Newer JVMs can run ordinary Java 25 bytecode, but these are tests for preview of StructuredTaskScope API.
// Preview bytecode runs only on the Java release that compiled it.
// Even with --enable-preview, Java 27 accepts only Java 27 preview bytecode, not Java 25's.
maxJavaVersion = JavaVersion.VERSION_25
}

description = 'JDK 25 Concurrent Integration Tests'
Expand All @@ -32,13 +29,6 @@ tasks.named('compileJava', JavaCompile) {
options.compilerArgs.add("--enable-preview")
}

// TODO: drop Groovy here at all
// The Groovy test framework can't run on Java 25 (the module's default toolchain), so pin the
// Groovy test compiler back to JDK 8 — matches the Java 8 test JVM that forks a Java 25 subprocess.
tasks.named('compileTestGroovy') {
configureCompiler(it, 8, JavaVersion.VERSION_1_8, "Groovy test framework cannot run on JDK 25")
}

application {
mainClass = 'datadog.smoketest.concurrent.ConcurrentApp'
}
Expand All @@ -51,7 +41,6 @@ dependencies {
tasks.withType(Test).configureEach {
def shadowJarTask = tasks.named('shadowJar', ShadowJar)
dependsOn shadowJarTask
environment("JAVA_HOME", getLazyJavaHomeFor(25))
jvmArgumentProviders.add(new CommandLineArgumentProvider() {
@Override
Iterable<String> asArguments() {
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package datadog.smoketest.concurrent;

import static datadog.smoketest.backend.AgentBackend.mockAgent;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import datadog.smoketest.SmokeCliApp;
import datadog.trace.test.agent.decoder.DecodedSpan;
import datadog.trace.test.agent.decoder.DecodedTrace;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.RegisterExtension;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
abstract class AbstractStructuredConcurrencyTest {
@RegisterExtension
final SmokeCliApp app =
SmokeCliApp.named(testCaseName())
.jar(System.getProperty("datadog.smoketest.shadowJar.path"))
.jvmArgs("--enable-preview", "-Ddd.trace.otel.enabled=true")
.args(testCaseName())
.backend(mockAgent())
.build();

protected abstract String testCaseName();

protected abstract Predicate<DecodedTrace> checkTrace();

protected void receivedCorrectTrace() {
app.assertCompletesWithValue(10, SECONDS, 0);
app.traces().waitForTraceCount(1);
List<DecodedTrace> traces = app.traces().getTraces();
assertEquals(1, traces.size());
assertTrue(checkTrace().test(traces.get(0)), "Unexpected structured concurrency trace");
}

protected Optional<DecodedSpan> findRootSpan(DecodedTrace trace, String resource) {
return trace.getSpans().stream()
.filter(span -> Objects.equals(resource, span.getResource()) && span.getParentId() == 0)
.findFirst();
}

protected Optional<DecodedSpan> findChildSpan(
DecodedTrace trace, String resource, long parentSpanId) {
return trace.getSpans().stream()
.filter(span ->
Objects.equals(resource, span.getResource()) && span.getParentId() == parentSpanId)
.findFirst();
}

protected boolean hasChildSpan(DecodedTrace trace, String resource, long parentSpanId) {
return findChildSpan(trace, resource, parentSpanId).isPresent();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package datadog.smoketest.concurrent;

import datadog.trace.test.agent.decoder.DecodedTrace;
import java.util.function.Predicate;
import org.junit.jupiter.api.Test;

/**
* Tests the structured task scope with multiple tasks. Here is the expected task/span structure:
*
* <pre>
* parent
* |-- child1
* |-- child2
* \-- child3
* </pre>
*/
class MultipleTasksTest extends AbstractStructuredConcurrencyTest {
@Override
protected String testCaseName() {
return "MultipleTasks";
}

@Override
protected Predicate<DecodedTrace> checkTrace() {
// 'parent' with 'child1', 'child2', and 'child3' as direct children
return trace ->
trace.getSpans().size() == 4
&& findRootSpan(trace, "parent")
.filter(parent ->
hasChildSpan(trace, "child1", parent.getSpanId())
&& hasChildSpan(trace, "child2", parent.getSpanId())
&& hasChildSpan(trace, "child3", parent.getSpanId()))
.isPresent();
}

@Test
void testMultipleTasks() throws Exception {
receivedCorrectTrace();
}
}
Loading
Loading