Skip to content

Commit 82adfc4

Browse files
fix: update weaver instrumentation to handle both queue implementations
1 parent d8c29ca commit 82adfc4

File tree

6 files changed

+114
-47
lines changed

6 files changed

+114
-47
lines changed

dd-java-agent/instrumentation/weaver/build.gradle

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,32 @@ apply from: "$rootDir/gradle/java.gradle"
22
apply plugin: 'scala'
33

44
muzzle {
5+
pass {
6+
group = 'com.disneystreaming'
7+
module = 'weaver-cats_3'
8+
versions = '[0.8.4,)'
9+
}
10+
511
pass {
612
group = 'org.typelevel'
713
module = 'weaver-cats_3'
8-
versions = '[0.9.2,)'
14+
versions = '[0.9.0,)'
915
}
1016
}
1117

1218
addTestSuiteForDir('latestDepTest', 'test')
19+
// weaver 0.8.4 is the earliest supported version before the org migration
20+
addTestSuiteForDir('weaver084Test', 'test')
1321

1422
dependencies {
15-
compileOnly group: 'org.typelevel', name: 'weaver-cats_3', version: '0.9.2'
23+
compileOnly group: 'org.typelevel', name: 'weaver-cats_3', version: '0.9.0'
1624

1725
testImplementation testFixtures(project(':dd-java-agent:agent-ci-visibility'))
1826

1927
testImplementation group: 'org.scala-lang', name: 'scala-library', version: '2.12.20'
20-
testImplementation group: 'org.typelevel', name: 'weaver-cats_3', version: '0.9.2'
21-
22-
testImplementation group: 'org.typelevel', name: 'weaver-cats_3', version: '+'
28+
testImplementation group: 'org.typelevel', name: 'weaver-cats_3', version: '0.9.0'
29+
latestDepTestImplementation group: 'org.typelevel', name: 'weaver-cats_3', version: '+'
30+
weaver084TestImplementation group: 'com.disneystreaming', name: 'weaver-cats_3', version: '0.8.4'
2331
}
2432

2533
compileTestGroovy {
@@ -31,3 +39,8 @@ compileLatestDepTestGroovy {
3139
dependsOn compileLatestDepTestScala
3240
classpath += files(sourceSets.latestDepTest.scala.destinationDirectory)
3341
}
42+
43+
compileWeaver084TestGroovy {
44+
dependsOn compileWeaver084TestScala
45+
classpath += files(sourceSets.weaver084Test.scala.destinationDirectory)
46+
}

dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/DatadogWeaverReporter.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import sbt.testing.TaskDef;
1515
import weaver.Result;
1616
import weaver.TestOutcome;
17+
import weaver.framework.RunEvent;
1718
import weaver.framework.SuiteFinished;
1819
import weaver.framework.SuiteStarted;
1920
import weaver.framework.TestFinished;
@@ -42,6 +43,19 @@ public static synchronized void stop() {
4243
}
4344
}
4445

46+
public static void processEvent(Object event, TaskDef taskDef) {
47+
if (event instanceof RunEvent) {
48+
// handle event here, using taskDef reference to get suite details
49+
if (event instanceof SuiteStarted) {
50+
onSuiteStart((SuiteStarted) event);
51+
} else if (event instanceof SuiteFinished) {
52+
onSuiteFinish((SuiteFinished) event);
53+
} else if (event instanceof TestFinished) {
54+
onTestFinished((TestFinished) event, taskDef);
55+
}
56+
}
57+
}
58+
4559
public static void onSuiteStart(SuiteStarted event) {
4660
String testSuiteName = event.name();
4761
Class<?> testClass = WeaverUtils.getClass(testSuiteName);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package datadog.trace.instrumentation.weaver;
2+
3+
import java.util.concurrent.ConcurrentLinkedQueue;
4+
import sbt.testing.TaskDef;
5+
6+
public final class TaskDefAwareConcurrentLinkedQueueProxy<T> extends ConcurrentLinkedQueue<T> {
7+
8+
private final TaskDef taskDef;
9+
private final ConcurrentLinkedQueue<T> delegate;
10+
11+
public TaskDefAwareConcurrentLinkedQueueProxy(TaskDef taskDef, ConcurrentLinkedQueue<T> delegate) {
12+
super();
13+
this.taskDef = taskDef;
14+
this.delegate = delegate;
15+
DatadogWeaverReporter.start();
16+
}
17+
18+
@Override
19+
public T poll() {
20+
T event = delegate.poll();
21+
DatadogWeaverReporter.processEvent(event, taskDef);
22+
return event;
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package datadog.trace.instrumentation.weaver;
2+
3+
import java.util.concurrent.LinkedBlockingQueue;
4+
import java.util.concurrent.TimeUnit;
5+
import sbt.testing.TaskDef;
6+
7+
public final class TaskDefAwareLinkedBlockingQueueProxy<T> extends LinkedBlockingQueue<T> {
8+
9+
private final TaskDef taskDef;
10+
private final LinkedBlockingQueue<T> delegate;
11+
12+
public TaskDefAwareLinkedBlockingQueueProxy(TaskDef taskDef, LinkedBlockingQueue<T> delegate) {
13+
super();
14+
this.taskDef = taskDef;
15+
this.delegate = delegate;
16+
DatadogWeaverReporter.start();
17+
}
18+
19+
@Override
20+
public T poll() {
21+
T event = delegate.poll();
22+
DatadogWeaverReporter.processEvent(event, taskDef);
23+
return event;
24+
}
25+
26+
@Override
27+
public T poll(long timeout, TimeUnit unit) throws InterruptedException {
28+
T event = delegate.poll(timeout, unit);
29+
if (event != null) {
30+
DatadogWeaverReporter.processEvent(event, taskDef);
31+
}
32+
return event;
33+
}
34+
}

dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareQueueProxy.java

Lines changed: 0 additions & 37 deletions
This file was deleted.

dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/WeaverInstrumentation.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import com.google.auto.service.AutoService;
66
import datadog.trace.agent.tooling.Instrumenter;
77
import datadog.trace.agent.tooling.InstrumenterModule;
8+
import java.lang.reflect.Field;
89
import java.util.concurrent.ConcurrentLinkedQueue;
10+
import java.util.concurrent.LinkedBlockingQueue;
911
import net.bytebuddy.asm.Advice;
1012
import sbt.testing.TaskDef;
1113
import weaver.framework.SuiteEvent;
@@ -28,7 +30,8 @@ public String[] helperClassNames() {
2830
return new String[] {
2931
packageName + ".WeaverUtils",
3032
packageName + ".DatadogWeaverReporter",
31-
packageName + ".TaskDefAwareQueueProxy",
33+
packageName + ".TaskDefAwareLinkedBlockingQueueProxy",
34+
packageName + ".TaskDefAwareConcurrentLinkedQueueProxy",
3235
};
3336
}
3437

@@ -41,10 +44,26 @@ public void methodAdvice(MethodTransformer transformer) {
4144
public static class SbtTaskCreationAdvice {
4245
@Advice.OnMethodExit(suppress = Throwable.class)
4346
public static void onTaskCreation(
44-
@Advice.FieldValue(value = "queue", readOnly = false)
45-
ConcurrentLinkedQueue<SuiteEvent> queue,
46-
@Advice.FieldValue("taskDef") TaskDef taskDef) {
47-
queue = new TaskDefAwareQueueProxy<SuiteEvent>(taskDef, queue);
47+
@Advice.This Object sbtTask, @Advice.FieldValue("taskDef") TaskDef taskDef) {
48+
try {
49+
Field queueField = sbtTask.getClass().getDeclaredField("queue");
50+
queueField.setAccessible(true);
51+
Object queue = queueField.get(sbtTask);
52+
if (queue instanceof ConcurrentLinkedQueue) {
53+
// disney's implementation (0.8.4+) uses a ConcurrentLinkedQueue for the field
54+
queueField.set(
55+
sbtTask,
56+
new TaskDefAwareConcurrentLinkedQueueProxy<SuiteEvent>(
57+
taskDef, (ConcurrentLinkedQueue<SuiteEvent>) queue));
58+
} else if (queue instanceof LinkedBlockingQueue) {
59+
// typelevel's implementation (0.9+) uses a LinkedBlockingQueue for the field
60+
queueField.set(
61+
sbtTask,
62+
new TaskDefAwareLinkedBlockingQueueProxy<SuiteEvent>(
63+
taskDef, (LinkedBlockingQueue<SuiteEvent>) queue));
64+
}
65+
} catch (Exception ignored) {
66+
}
4867
}
4968
}
5069
}

0 commit comments

Comments
 (0)