Skip to content

Commit e4971bf

Browse files
committed
Check for blocked instrumentation in tests
If there is a blocked instrumentation, the test will fail and the failure message will include the same information that is logged from MuzzleCheck.
1 parent 4ec4990 commit e4971bf

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/muzzle/MuzzleCheck.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import datadog.trace.agent.tooling.InstrumenterModule;
44
import datadog.trace.agent.tooling.InstrumenterState;
55
import datadog.trace.agent.tooling.Utils;
6+
import java.util.ArrayList;
7+
import java.util.Collections;
68
import java.util.List;
79
import net.bytebuddy.matcher.ElementMatcher;
810
import org.slf4j.Logger;
@@ -11,6 +13,9 @@
1113
public class MuzzleCheck implements ElementMatcher<ClassLoader> {
1214
private static final Logger log = LoggerFactory.getLogger(MuzzleCheck.class);
1315

16+
private static final List<String> ERRORS = Collections.synchronizedList(new ArrayList<>());
17+
private static volatile boolean recordErrors = false;
18+
1419
private final int instrumentationId;
1520
private final String instrumentationClass;
1621
private final ReferenceProvider runtimeMuzzleReferences;
@@ -33,9 +38,13 @@ public boolean matches(ClassLoader classLoader) {
3338
InstrumenterState.applyInstrumentation(classLoader, instrumentationId);
3439
} else {
3540
InstrumenterState.blockInstrumentation(classLoader, instrumentationId);
36-
if (log.isDebugEnabled()) {
41+
if (recordErrors || log.isDebugEnabled()) {
3742
final List<Reference.Mismatch> mismatches =
3843
muzzle.getMismatchedReferenceSources(classLoader);
44+
if (recordErrors) {
45+
recordMuzzleMismatch(
46+
InstrumenterState.describe(instrumentationId), classLoader, mismatches);
47+
}
3948
log.debug(
4049
"Muzzled - {} instrumentation.target.classloader={}",
4150
InstrumenterState.describe(instrumentationId),
@@ -61,4 +70,38 @@ private ReferenceMatcher muzzle() {
6170
}
6271
return muzzle;
6372
}
73+
74+
/**
75+
* Record a muzzle mismatch error for test visibility.
76+
*
77+
* @param instrumentationDescription the description of the instrumentation that was blocked
78+
* @param classLoader the classloader where the instrumentation was blocked
79+
* @param mismatches the list of mismatch details
80+
*/
81+
private static void recordMuzzleMismatch(
82+
String instrumentationDescription,
83+
ClassLoader classLoader,
84+
List<Reference.Mismatch> mismatches) {
85+
StringBuilder sb = new StringBuilder();
86+
sb.append("Muzzled - ")
87+
.append(instrumentationDescription)
88+
.append(" instrumentation.target.classloader=")
89+
.append(classLoader)
90+
.append("\n");
91+
for (Reference.Mismatch mismatch : mismatches) {
92+
sb.append(" Mismatch: ").append(mismatch).append("\n");
93+
}
94+
ERRORS.add(sb.toString());
95+
}
96+
97+
// Visible for testing
98+
public static void enableRecordingAndReset() {
99+
recordErrors = true;
100+
ERRORS.clear();
101+
}
102+
103+
// Visible for testing
104+
public static List<String> getErrors() {
105+
return Collections.unmodifiableList(ERRORS);
106+
}
64107
}

dd-java-agent/instrumentation-testing/src/main/groovy/datadog/trace/agent/test/InstrumentationSpecification.groovy

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import datadog.trace.agent.tooling.InstrumenterModule
2525
import datadog.trace.agent.tooling.TracerInstaller
2626
import datadog.trace.agent.tooling.bytebuddy.matcher.ClassLoaderMatchers
2727
import datadog.trace.agent.tooling.bytebuddy.matcher.GlobalIgnores
28+
import datadog.trace.agent.tooling.muzzle.MuzzleCheck
2829
import datadog.trace.api.Config
2930
import datadog.trace.api.IdGenerationStrategy
3031
import datadog.trace.api.ProcessTags
@@ -462,6 +463,7 @@ abstract class InstrumentationSpecification extends DDSpecification implements A
462463
ActiveSubsystems.APPSEC_ACTIVE = true
463464
}
464465
InstrumentationErrors.enableRecordingAndReset()
466+
MuzzleCheck.enableRecordingAndReset()
465467
ProcessTags.reset()
466468
}
467469

@@ -505,6 +507,8 @@ abstract class InstrumentationSpecification extends DDSpecification implements A
505507
}
506508
def instrumentationErrorCount = InstrumentationErrors.getErrors().size()
507509
assert instrumentationErrorCount == 0, instrumentationErrorCount + " instrumentation errors were seen:\n" + InstrumentationErrors.getErrors().join("\n---\n")
510+
def muzzleErrorCount = MuzzleCheck.getErrors().size()
511+
assert muzzleErrorCount == 0, muzzleErrorCount + " muzzle errors were seen:\n" + MuzzleCheck.getErrors().join("\n---\n")
508512
}
509513

510514
private void doCheckRepeatedFinish() {

0 commit comments

Comments
 (0)