Skip to content

Commit 4f536b7

Browse files
deejgregoramarziali
authored andcommitted
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 2ab845d commit 4f536b7

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

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,14 +3,19 @@
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.Collections;
67
import java.util.List;
8+
import java.util.concurrent.CopyOnWriteArrayList;
79
import net.bytebuddy.matcher.ElementMatcher;
810
import org.slf4j.Logger;
911
import org.slf4j.LoggerFactory;
1012

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 = new CopyOnWriteArrayList<>();
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
@@ -39,6 +39,7 @@ import datadog.trace.agent.tooling.InstrumenterModule
3939
import datadog.trace.agent.tooling.TracerInstaller
4040
import datadog.trace.agent.tooling.bytebuddy.matcher.ClassLoaderMatchers
4141
import datadog.trace.agent.tooling.bytebuddy.matcher.GlobalIgnores
42+
import datadog.trace.agent.tooling.muzzle.MuzzleCheck
4243
import datadog.trace.api.Config
4344
import datadog.trace.api.IdGenerationStrategy
4445
import datadog.trace.api.Pair
@@ -478,6 +479,7 @@ abstract class InstrumentationSpecification extends DDSpecification implements A
478479
ActiveSubsystems.APPSEC_ACTIVE = true
479480
}
480481
InstrumentationErrors.enableRecordingAndReset()
482+
MuzzleCheck.enableRecordingAndReset()
481483
ProcessTags.reset()
482484
}
483485

@@ -521,6 +523,8 @@ abstract class InstrumentationSpecification extends DDSpecification implements A
521523
}
522524
def instrumentationErrorCount = InstrumentationErrors.getErrors().size()
523525
assert instrumentationErrorCount == 0, "${instrumentationErrorCount} instrumentation errors were seen:\n${InstrumentationErrors.getErrors().join("\n---\n")}"
526+
def muzzleErrorCount = MuzzleCheck.getErrors().size()
527+
assert muzzleErrorCount == 0, "${muzzleErrorCount} muzzle errors were seen:\n${MuzzleCheck.getErrors().join("\n---\n")}"
524528
}
525529

526530
private void doCheckRepeatedFinish() {

0 commit comments

Comments
 (0)