Skip to content

Commit aba8f42

Browse files
Fix JUnit 4 integration to support PowerMock (#7046)
1 parent 79c19b1 commit aba8f42

File tree

3 files changed

+26
-11
lines changed

3 files changed

+26
-11
lines changed

dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/JUnit4Instrumentation.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package datadog.trace.instrumentation.junit4;
22

33
import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.extendsClass;
4+
import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface;
45
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
56
import static net.bytebuddy.matcher.ElementMatchers.not;
67
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
@@ -50,7 +51,14 @@ public ElementMatcher<TypeDescription> hierarchyMatcher() {
5051
.and(not(extendsClass(named("datadog.trace.agent.test.SpockRunner"))))
5152
// do not instrument Karate JUnit 4 runner
5253
// since Karate has a dedicated instrumentation
53-
.and(not(extendsClass(named("com.intuit.karate.junit4.Karate"))));
54+
.and(not(extendsClass(named("com.intuit.karate.junit4.Karate"))))
55+
// PowerMock runner is being instrumented,
56+
// so do not instrument its internal delegates
57+
.and(
58+
not(
59+
implementsInterface(
60+
named(
61+
"org.powermock.modules.junit4.common.internal.PowerMockJUnitRunnerDelegate"))));
5462
}
5563

5664
@Override

dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/JUnit4Utils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@ public static TestDescriptor toTestDescriptor(Description description) {
310310
public static TestSuiteDescriptor toSuiteDescriptor(Description description) {
311311
Class<?> testClass = description.getTestClass();
312312
String testSuiteName = JUnit4Utils.getSuiteName(testClass, description);
313-
return new TestSuiteDescriptor(testSuiteName, testClass);
313+
// relying exclusively on class name: some runners (such as PowerMock) may redefine test classes
314+
return new TestSuiteDescriptor(testSuiteName, null);
314315
}
315316

316317
/**
Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,24 @@
1414
import org.junit.runner.notification.RunListener;
1515
import org.junit.runner.notification.RunNotifier;
1616

17-
/** Supports suite started/finished events for {@link TestCase} subclasses. */
17+
/**
18+
* Supports suite started/finished events for {@link TestCase} subclasses and Powermock-enabled test
19+
* suites.
20+
*/
1821
@AutoService(InstrumenterModule.class)
19-
public class JUnit38SuiteEventsInstrumentation extends InstrumenterModule.CiVisibility
20-
implements Instrumenter.ForSingleType {
22+
public class JUnitLegacySuiteEventsInstrumentation extends InstrumenterModule.CiVisibility
23+
implements Instrumenter.ForKnownTypes {
2124

22-
public JUnit38SuiteEventsInstrumentation() {
23-
super("ci-visibility", "junit-4", "junit-38");
25+
public JUnitLegacySuiteEventsInstrumentation() {
26+
super("ci-visibility", "junit-4", "junit-38", "powermock");
2427
}
2528

2629
@Override
27-
public String instrumentedType() {
28-
return "org.junit.internal.runners.JUnit38ClassRunner";
30+
public String[] knownMatchingTypes() {
31+
return new String[] {
32+
"org.junit.internal.runners.JUnit38ClassRunner",
33+
"org.powermock.modules.junit4.PowerMockRunner"
34+
};
2935
}
3036

3137
@Override
@@ -50,10 +56,10 @@ public int order() {
5056
public void methodAdvice(MethodTransformer transformer) {
5157
transformer.applyAdvice(
5258
named("run").and(takesArgument(0, named("org.junit.runner.notification.RunNotifier"))),
53-
JUnit38SuiteEventsInstrumentation.class.getName() + "$JUnit38SuiteEventsAdvice");
59+
JUnitLegacySuiteEventsInstrumentation.class.getName() + "$JUnitLegacySuiteEventsAdvice");
5460
}
5561

56-
public static class JUnit38SuiteEventsAdvice {
62+
public static class JUnitLegacySuiteEventsAdvice {
5763
@Advice.OnMethodEnter(suppress = Throwable.class)
5864
public static void fireSuiteStartedEvent(
5965
@Advice.Argument(0) final RunNotifier runNotifier, @Advice.This final Runner runner) {

0 commit comments

Comments
 (0)