Skip to content

Commit f7ec25f

Browse files
Fix JUnit integration to work with JUnit 6
1 parent fa49f3f commit f7ec25f

File tree

22 files changed

+2228
-106
lines changed

22 files changed

+2228
-106
lines changed

dd-java-agent/instrumentation/junit-5.3/build.gradle

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ muzzle {
2222
}
2323
}
2424

25+
ext {
26+
latestDepTestMinJavaVersionForTests = JavaVersion.VERSION_17
27+
}
28+
29+
addTestSuiteForDir('latest5Test', 'test')
2530
addTestSuiteForDir('latestDepTest', 'test')
2631

2732
dependencies {
@@ -36,6 +41,10 @@ dependencies {
3641
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.12.0'
3742
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.12.0'
3843

44+
latest5TestImplementation group: 'org.junit.platform', name: 'junit-platform-launcher', version: '1.+'
45+
latest5TestImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.+'
46+
latest5TestImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.+'
47+
3948
latestDepTestImplementation group: 'org.junit.platform', name: 'junit-platform-launcher', version: '+'
4049
latestDepTestImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '+'
4150
latestDepTestImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '+'
@@ -48,3 +57,9 @@ configurations.matching({ it.name.startsWith('test') }).each({
4857
force group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.12.0'
4958
}
5059
})
60+
61+
tasks.named("compileLatestDepTestJava").configure {
62+
setJavaVersion(it, 17)
63+
sourceCompatibility = JavaVersion.VERSION_1_8
64+
targetCompatibility = JavaVersion.VERSION_1_8
65+
}

dd-java-agent/instrumentation/junit-5.3/gradle.lockfile

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -130,29 +130,30 @@ org.jctools:jctools-core:3.3.0=instrumentPluginClasspath,latestDepTestRuntimeCla
130130
org.jspecify:jspecify:1.0.0=latestDepTestCompileClasspath
131131
org.junit.jupiter:junit-jupiter-api:5.12.0=testCompileClasspath,testRuntimeClasspath
132132
org.junit.jupiter:junit-jupiter-api:5.3.0=compileClasspath
133-
org.junit.jupiter:junit-jupiter-api:5.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
133+
org.junit.jupiter:junit-jupiter-api:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
134134
org.junit.jupiter:junit-jupiter-engine:5.12.0=testCompileClasspath,testRuntimeClasspath
135-
org.junit.jupiter:junit-jupiter-engine:5.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
135+
org.junit.jupiter:junit-jupiter-engine:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
136136
org.junit.jupiter:junit-jupiter-params:5.12.0=testCompileClasspath,testRuntimeClasspath
137-
org.junit.jupiter:junit-jupiter-params:5.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
137+
org.junit.jupiter:junit-jupiter-params:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
138+
org.junit.jupiter:junit-jupiter:5.12.0=testCompileClasspath,testRuntimeClasspath
139+
org.junit.jupiter:junit-jupiter:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
138140
org.junit.platform:junit-platform-commons:1.12.0=testCompileClasspath,testRuntimeClasspath
139141
org.junit.platform:junit-platform-commons:1.3.0=compileClasspath
140-
org.junit.platform:junit-platform-commons:1.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
142+
org.junit.platform:junit-platform-commons:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
141143
org.junit.platform:junit-platform-engine:1.12.0=testCompileClasspath,testRuntimeClasspath
142144
org.junit.platform:junit-platform-engine:1.3.0=compileClasspath
143-
org.junit.platform:junit-platform-engine:1.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
145+
org.junit.platform:junit-platform-engine:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
144146
org.junit.platform:junit-platform-launcher:1.12.0=testCompileClasspath,testRuntimeClasspath
145147
org.junit.platform:junit-platform-launcher:1.3.0=compileClasspath
146-
org.junit.platform:junit-platform-launcher:1.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
148+
org.junit.platform:junit-platform-launcher:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
147149
org.junit.platform:junit-platform-runner:1.12.0=testRuntimeClasspath
148150
org.junit.platform:junit-platform-runner:1.9.0=latestDepTestRuntimeClasspath
149151
org.junit.platform:junit-platform-suite-api:1.12.0=testRuntimeClasspath
150-
org.junit.platform:junit-platform-suite-api:1.13.4=latestDepTestRuntimeClasspath
152+
org.junit.platform:junit-platform-suite-api:6.0.0-RC2=latestDepTestRuntimeClasspath
151153
org.junit.platform:junit-platform-suite-commons:1.12.0=testRuntimeClasspath
152154
org.junit.platform:junit-platform-suite-commons:1.9.0=latestDepTestRuntimeClasspath
153155
org.junit:junit-bom:5.12.0=testCompileClasspath,testRuntimeClasspath
154-
org.junit:junit-bom:5.9.1=spotbugs
155-
org.junit:junit-bom:5.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
156+
org.junit:junit-bom:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
156157
org.msgpack:jackson-dataformat-msgpack:0.9.6=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
157158
org.msgpack:msgpack-core:0.9.6=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
158159
org.objenesis:objenesis:3.3=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath

dd-java-agent/instrumentation/junit-5.3/junit-5.8/build.gradle

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ muzzle {
2323
}
2424
}
2525

26+
ext {
27+
latestDepTestMinJavaVersionForTests = JavaVersion.VERSION_17
28+
}
29+
2630
addTestSuiteForDir('latestDepTest', 'test')
2731

2832
dependencies {
@@ -52,3 +56,10 @@ configurations.matching({ it.name.startsWith('test') }).each({
5256
force group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.12.0'
5357
}
5458
})
59+
60+
tasks.named("compileLatestDepTestJava").configure {
61+
setJavaVersion(it, 17)
62+
sourceCompatibility = JavaVersion.VERSION_1_8
63+
targetCompatibility = JavaVersion.VERSION_1_8
64+
}
65+

dd-java-agent/instrumentation/junit-5.3/junit-5.8/gradle.lockfile

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,31 +129,32 @@ org.jctools:jctools-core:3.3.0=instrumentPluginClasspath,latestDepTestRuntimeCla
129129
org.jspecify:jspecify:1.0.0=latestDepTestCompileClasspath
130130
org.junit.jupiter:junit-jupiter-api:5.12.0=testCompileClasspath,testRuntimeClasspath
131131
org.junit.jupiter:junit-jupiter-api:5.8.0=compileClasspath
132-
org.junit.jupiter:junit-jupiter-api:5.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
132+
org.junit.jupiter:junit-jupiter-api:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
133133
org.junit.jupiter:junit-jupiter-engine:5.12.0=testCompileClasspath,testRuntimeClasspath
134134
org.junit.jupiter:junit-jupiter-engine:5.8.0=compileClasspath
135-
org.junit.jupiter:junit-jupiter-engine:5.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
135+
org.junit.jupiter:junit-jupiter-engine:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
136136
org.junit.jupiter:junit-jupiter-params:5.12.0=testCompileClasspath,testRuntimeClasspath
137-
org.junit.jupiter:junit-jupiter-params:5.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
137+
org.junit.jupiter:junit-jupiter-params:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
138+
org.junit.jupiter:junit-jupiter:5.12.0=testCompileClasspath,testRuntimeClasspath
139+
org.junit.jupiter:junit-jupiter:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
138140
org.junit.platform:junit-platform-commons:1.12.0=testCompileClasspath,testRuntimeClasspath
139141
org.junit.platform:junit-platform-commons:1.8.0=compileClasspath
140-
org.junit.platform:junit-platform-commons:1.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
142+
org.junit.platform:junit-platform-commons:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
141143
org.junit.platform:junit-platform-engine:1.12.0=testCompileClasspath,testRuntimeClasspath
142144
org.junit.platform:junit-platform-engine:1.8.0=compileClasspath
143-
org.junit.platform:junit-platform-engine:1.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
145+
org.junit.platform:junit-platform-engine:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
144146
org.junit.platform:junit-platform-launcher:1.12.0=testCompileClasspath,testRuntimeClasspath
145147
org.junit.platform:junit-platform-launcher:1.8.0=compileClasspath
146-
org.junit.platform:junit-platform-launcher:1.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
148+
org.junit.platform:junit-platform-launcher:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
147149
org.junit.platform:junit-platform-runner:1.12.0=testRuntimeClasspath
148150
org.junit.platform:junit-platform-runner:1.9.0=latestDepTestRuntimeClasspath
149151
org.junit.platform:junit-platform-suite-api:1.12.0=testRuntimeClasspath
150-
org.junit.platform:junit-platform-suite-api:1.13.4=latestDepTestRuntimeClasspath
152+
org.junit.platform:junit-platform-suite-api:6.0.0-RC2=latestDepTestRuntimeClasspath
151153
org.junit.platform:junit-platform-suite-commons:1.12.0=testRuntimeClasspath
152154
org.junit.platform:junit-platform-suite-commons:1.9.0=latestDepTestRuntimeClasspath
153155
org.junit:junit-bom:5.12.0=testCompileClasspath,testRuntimeClasspath
154156
org.junit:junit-bom:5.8.0=compileClasspath
155-
org.junit:junit-bom:5.9.1=spotbugs
156-
org.junit:junit-bom:1.13.4=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
157+
org.junit:junit-bom:6.0.0-RC2=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath
157158
org.msgpack:jackson-dataformat-msgpack:0.9.6=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
158159
org.msgpack:msgpack-core:0.9.6=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
159160
org.objenesis:objenesis:3.3=latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package datadog.trace.instrumentation.junit5;
2+
3+
import datadog.trace.util.MethodHandles;
4+
import java.lang.invoke.MethodHandle;
5+
import java.util.Arrays;
6+
import java.util.function.BiFunction;
7+
import org.junit.platform.commons.util.ClassLoaderUtils;
8+
import org.junit.platform.engine.ConfigurationParameters;
9+
import org.junit.platform.engine.EngineExecutionListener;
10+
import org.junit.platform.engine.ExecutionRequest;
11+
import org.junit.platform.engine.TestDescriptor;
12+
13+
public class ExecutionRequestFactory {
14+
15+
private static final MethodHandles METHOD_HANDLES =
16+
new MethodHandles(ClassLoaderUtils.getDefaultClassLoader());
17+
18+
/*
19+
* From 5.13.0-RC1 onwards ExecutionRequest requires two additional arguments on creation.
20+
* - OutputDirectoryProvider outputDirectoryProvider
21+
* - NamespacedHierarchicalStore<Namespace> requestLevelStore
22+
*/
23+
private static final MethodHandle GET_OUTPUT_DIRECTORY_PROVIDER =
24+
METHOD_HANDLES.method(ExecutionRequest.class, "getOutputDirectoryProvider");
25+
private static final MethodHandle GET_STORE =
26+
METHOD_HANDLES.method(ExecutionRequest.class, "getStore");
27+
/*
28+
* From 6.0.0-M2 onwards CancellationToken is also required.
29+
*/
30+
private static final MethodHandle GET_CANCELLATION_TOKEN =
31+
METHOD_HANDLES.method(ExecutionRequest.class, "getCancellationToken");
32+
33+
private static final String[] CREATE_PARAMETER_TYPES =
34+
new String[] {
35+
"org.junit.platform.engine.TestDescriptor",
36+
"org.junit.platform.engine.EngineExecutionListener",
37+
"org.junit.platform.engine.ConfigurationParameters",
38+
"org.junit.platform.engine.reporting.OutputDirectoryProvider",
39+
"org.junit.platform.engine.support.store.NamespacedHierarchicalStore",
40+
"org.junit.platform.engine.CancellationToken"
41+
};
42+
43+
private static final BiFunction<ExecutionRequest, EngineExecutionListener, ExecutionRequest>
44+
EXECUTION_REQUEST_CREATE = createExecutionRequestHandle();
45+
46+
private static BiFunction<ExecutionRequest, EngineExecutionListener, ExecutionRequest>
47+
createExecutionRequestHandle() {
48+
// 6.0.0-M2 and later
49+
if (GET_CANCELLATION_TOKEN != null) {
50+
MethodHandle createMethod =
51+
METHOD_HANDLES.method(
52+
ExecutionRequest.class,
53+
m ->
54+
"create".equals(m.getName())
55+
&& m.getParameterCount() == 6
56+
&& Arrays.equals(
57+
Arrays.stream(m.getParameterTypes()).map(Class::getName).toArray(),
58+
CREATE_PARAMETER_TYPES));
59+
60+
return (request, listener) -> {
61+
Object provider = METHOD_HANDLES.invoke(GET_OUTPUT_DIRECTORY_PROVIDER, request);
62+
Object store = METHOD_HANDLES.invoke(GET_STORE, request);
63+
Object cancellationToken = METHOD_HANDLES.invoke(GET_CANCELLATION_TOKEN, request);
64+
return METHOD_HANDLES.invoke(
65+
createMethod,
66+
request.getRootTestDescriptor(),
67+
listener,
68+
request.getConfigurationParameters(),
69+
provider,
70+
store,
71+
cancellationToken);
72+
};
73+
}
74+
75+
// 5.13.0-RC1 and later
76+
if (GET_STORE != null && GET_OUTPUT_DIRECTORY_PROVIDER != null) {
77+
MethodHandle createMethod =
78+
METHOD_HANDLES.method(
79+
ExecutionRequest.class,
80+
m ->
81+
"create".equals(m.getName())
82+
&& m.getParameterCount() == 5
83+
&& Arrays.equals(
84+
Arrays.stream(m.getParameterTypes()).map(Class::getName).toArray(),
85+
Arrays.copyOf(CREATE_PARAMETER_TYPES, 5)));
86+
87+
return (request, listener) -> {
88+
Object provider = METHOD_HANDLES.invoke(GET_OUTPUT_DIRECTORY_PROVIDER, request);
89+
Object store = METHOD_HANDLES.invoke(GET_STORE, request);
90+
return METHOD_HANDLES.invoke(
91+
createMethod,
92+
request.getRootTestDescriptor(),
93+
listener,
94+
request.getConfigurationParameters(),
95+
provider,
96+
store);
97+
};
98+
}
99+
100+
MethodHandle constructor =
101+
METHOD_HANDLES.constructor(
102+
ExecutionRequest.class,
103+
TestDescriptor.class,
104+
EngineExecutionListener.class,
105+
ConfigurationParameters.class);
106+
return (request, listener) ->
107+
METHOD_HANDLES.invoke(
108+
constructor,
109+
request.getRootTestDescriptor(),
110+
listener,
111+
request.getConfigurationParameters());
112+
}
113+
114+
public static ExecutionRequest createExecutionRequest(
115+
ExecutionRequest request, EngineExecutionListener listener) {
116+
return EXECUTION_REQUEST_CREATE.apply(request, listener);
117+
}
118+
}

dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/JUnit5Instrumentation.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public ElementMatcher<TypeDescription> hierarchyMatcher() {
4949
public String[] helperClassNames() {
5050
return new String[] {
5151
packageName + ".JUnitPlatformUtils",
52+
packageName + ".ExecutionRequestFactory",
5253
packageName + ".TestEventsHandlerHolder",
5354
packageName + ".TracingListener",
5455
packageName + ".CompositeEngineListener",
@@ -117,7 +118,7 @@ public static void addTracingListener(
117118
EngineExecutionListener compositeListener =
118119
new CompositeEngineListener(tracingListener, originalListener);
119120
executionRequest =
120-
JUnitPlatformUtils.createExecutionRequest(executionRequest, compositeListener);
121+
ExecutionRequestFactory.createExecutionRequest(executionRequest, compositeListener);
121122
}
122123

123124
// JUnit 5.3.0 and above

dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/JUnitPlatformUtils.java

Lines changed: 5 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222
import org.junit.platform.commons.JUnitException;
2323
import org.junit.platform.commons.util.ClassLoaderUtils;
2424
import org.junit.platform.commons.util.ReflectionUtils;
25-
import org.junit.platform.engine.ConfigurationParameters;
26-
import org.junit.platform.engine.EngineExecutionListener;
27-
import org.junit.platform.engine.ExecutionRequest;
2825
import org.junit.platform.engine.TestDescriptor;
2926
import org.junit.platform.engine.TestEngine;
3027
import org.junit.platform.engine.TestSource;
@@ -112,71 +109,16 @@ private JUnitPlatformUtils() {}
112109
private static final MethodHandle GET_JAVA_METHOD =
113110
METHOD_HANDLES.method(MethodSource.class, "getJavaMethod");
114111

115-
/*
116-
* From 5.13.0-RC1 onwards ExecutionRequest requires two additional arguments on creation.
117-
* - OutputDirectoryProvider outputDirectoryProvider
118-
* - NamespacedHierarchicalStore<Namespace> requestLevelStore
119-
*/
120-
private static final MethodHandle GET_OUTPUT_DIRECTORY_PROVIDER =
121-
METHOD_HANDLES.method(ExecutionRequest.class, "getOutputDirectoryProvider");
122-
private static final MethodHandle GET_STORE =
123-
METHOD_HANDLES.method(ExecutionRequest.class, "getStore");
124-
private static final String[] CREATE_PARAMETER_TYPES =
125-
new String[] {
126-
"org.junit.platform.engine.TestDescriptor",
127-
"org.junit.platform.engine.EngineExecutionListener",
128-
"org.junit.platform.engine.ConfigurationParameters",
129-
"org.junit.platform.engine.reporting.OutputDirectoryProvider",
130-
"org.junit.platform.engine.support.store.NamespacedHierarchicalStore"
131-
};
132-
private static final MethodHandle EXECUTION_REQUEST_CREATE = createExecutionRequestHandle();
133-
134-
private static MethodHandle createExecutionRequestHandle() {
135-
if (GET_STORE != null && GET_OUTPUT_DIRECTORY_PROVIDER != null) {
136-
return METHOD_HANDLES.method(
137-
ExecutionRequest.class,
138-
m ->
139-
"create".equals(m.getName())
140-
&& m.getParameterCount() == 5
141-
&& Arrays.equals(
142-
Arrays.stream(m.getParameterTypes()).map(Class::getName).toArray(),
143-
CREATE_PARAMETER_TYPES));
144-
} else {
145-
return METHOD_HANDLES.constructor(
146-
ExecutionRequest.class,
147-
TestDescriptor.class,
148-
EngineExecutionListener.class,
149-
ConfigurationParameters.class);
150-
}
151-
}
152-
153-
public static ExecutionRequest createExecutionRequest(
154-
ExecutionRequest request, EngineExecutionListener listener) {
155-
if (GET_STORE != null && GET_OUTPUT_DIRECTORY_PROVIDER != null) {
156-
Object provider = METHOD_HANDLES.invoke(GET_OUTPUT_DIRECTORY_PROVIDER, request);
157-
Object store = METHOD_HANDLES.invoke(GET_STORE, request);
158-
return METHOD_HANDLES.invoke(
159-
EXECUTION_REQUEST_CREATE,
160-
request.getRootTestDescriptor(),
161-
listener,
162-
request.getConfigurationParameters(),
163-
provider,
164-
store);
165-
} else {
166-
return METHOD_HANDLES.invoke(
167-
EXECUTION_REQUEST_CREATE,
168-
request.getRootTestDescriptor(),
169-
listener,
170-
request.getConfigurationParameters());
171-
}
172-
}
173-
174112
private static Class<?> getTestClass(MethodSource methodSource) {
175113
Class<?> javaClass = METHOD_HANDLES.invoke(GET_JAVA_CLASS, methodSource);
176114
if (javaClass != null) {
177115
return javaClass;
178116
}
179-
return ReflectionUtils.loadClass(methodSource.getClassName()).orElse(null);
117+
try {
118+
return ClassLoaderUtils.getDefaultClassLoader().loadClass(methodSource.getClassName());
119+
} catch (ClassNotFoundException e) {
120+
return null;
121+
}
180122
}
181123

182124
private static Method getTestMethod(MethodSource methodSource) {

0 commit comments

Comments
 (0)