Skip to content

Commit 407e5c7

Browse files
add tracing for junit4 setup/teardown actions
1 parent ff8ee85 commit 407e5c7

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package datadog.trace.instrumentation.junit4;
2+
3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
4+
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
5+
6+
import com.google.auto.service.AutoService;
7+
import datadog.trace.agent.tooling.Instrumenter;
8+
import datadog.trace.agent.tooling.InstrumenterModule;
9+
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
10+
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
11+
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
12+
import datadog.trace.bootstrap.instrumentation.api.Tags;
13+
import net.bytebuddy.asm.Advice;
14+
import org.junit.After;
15+
import org.junit.AfterClass;
16+
import org.junit.Before;
17+
import org.junit.BeforeClass;
18+
import org.junit.runners.model.FrameworkMethod;
19+
20+
@AutoService(InstrumenterModule.class)
21+
public class JUnit4BeforeAfterInstrumentation extends InstrumenterModule.CiVisibility
22+
implements Instrumenter.ForKnownTypes {
23+
24+
public JUnit4BeforeAfterInstrumentation() {
25+
super("ci-visibility", "junit-4", "setup-teardown");
26+
}
27+
28+
@Override
29+
public String[] knownMatchingTypes() {
30+
return new String[] {
31+
"org.junit.internal.runners.statements.RunBefores",
32+
"org.junit.internal.runners.statements.RunAfters"
33+
};
34+
}
35+
36+
@Override
37+
public void methodAdvice(MethodTransformer transformer) {
38+
transformer.applyAdvice(
39+
named("invokeMethod")
40+
.and(takesArgument(0, named("org.junit.runners.model.FrameworkMethod"))),
41+
JUnit4BeforeAfterInstrumentation.class.getName() + "$RunBeforesAftersAdvice");
42+
}
43+
44+
public static class RunBeforesAftersAdvice {
45+
@Advice.OnMethodEnter(suppress = Throwable.class)
46+
public static AgentScope startCallSpan(@Advice.Argument(0) final FrameworkMethod method) {
47+
final AgentSpan span = AgentTracer.startSpan("junit", method.getMethod().getName());
48+
if (method.getMethod().isAnnotationPresent(Before.class)) {
49+
span.setTag(Tags.TEST_CALLBACK, "Before");
50+
} else if (method.getMethod().isAnnotationPresent(After.class)) {
51+
span.setTag(Tags.TEST_CALLBACK, "After");
52+
} else if (method.getMethod().isAnnotationPresent(BeforeClass.class)) {
53+
span.setTag(Tags.TEST_CALLBACK, "BeforeClass");
54+
} else if (method.getMethod().isAnnotationPresent(AfterClass.class)) {
55+
span.setTag(Tags.TEST_CALLBACK, "AfterClass");
56+
}
57+
return AgentTracer.activateSpan(span);
58+
}
59+
60+
@Advice.OnMethodExit(suppress = Throwable.class)
61+
public static void finishCallSpan(@Advice.Enter final AgentScope scope) {
62+
AgentSpan span = scope.span();
63+
scope.close();
64+
span.finish();
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)