Add tests to verify that fields are not injected when feature is disabled
MODIFY
dd-java-agent/testing/src/test/groovy/context/FieldBackedProviderTest.groovy
dd-java-agent/testing/src/test/groovy/context/FieldBackedProviderTest.groovy
@@ -2,8 +2,10 @@ package context
import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.TestUtils
+import datadog.trace.api.Config
import net.bytebuddy.agent.ByteBuddyAgent
import net.bytebuddy.utility.JavaModule
+import spock.lang.Requires
import java.lang.instrument.ClassDefinition
import java.lang.ref.WeakReference
@@ -150,3 +152,43 @@ class FieldBackedProviderTest extends AgentTestRunner {
!new IncorrectCallUsageKeyClass().isInstrumented()
}
}
+
+/**
+ * Make sure that fields not get injected into the class if it is disabled via system properties.
+ *
+ * Unfortunately we cannot set system properties here early enough for AgentTestRunner to see.
+ * Instead we have to configure this via Gradle. Ideally we should not have to do this.
+ */
+@Requires({ "true" == System.getProperty(Config.PREFIX + Config.RUNTIME_CONTEXT_FIELD_INJECTION) })
+class FieldBackedProviderFieldInjectionDisabledTest extends AgentTestRunner {
+ def "Check that structure is not modified when structure modification is disabled"() {
+ setup:
+ def keyClass = ContextTestInstrumentation.DisabledKeyClass
+ boolean hasField = false
+ for (Field field : keyClass.getDeclaredFields()) {
+ if (field.getName().startsWith("__datadog")) {
+ hasField = true
+ break
+ }
+ }
+
+ boolean hasMarkerInterface = false
+ boolean hasAccessorInterface = false
+ for (Class inter : keyClass.getInterfaces()) {
+ if (inter.getName() == 'datadog.trace.bootstrap.FieldBackedContextStoreAppliedMarker') {
+ hasMarkerInterface = true
+ }
+ if (inter.getName().startsWith('datadog.trace.agent.tooling.context.FieldBackedProvider$ContextAccessor')) {
+ hasAccessorInterface = true
+ }
+ }
+
+ expect:
+ Config.get().isPrioritySamplingEnabled() == false
+ hasField == false
+ hasMarkerInterface == false
+ hasAccessorInterface == false
+ keyClass.newInstance().isInstrumented() == true
+ }
+
+}

MODIFY
dd-java-agent/testing/src/test/java/context/ContextTestInstrumentation.java
dd-java-agent/testing/src/test/java/context/ContextTestInstrumentation.java
@@ -52,6 +52,7 @@ public class ContextTestInstrumentation extends Instrumenter.Default {
final Map<String, String> store = new HashMap<>(2);
store.put(getClass().getName() + "$KeyClass", getClass().getName() + "$Context");
store.put(getClass().getName() + "$UntransformableKeyClass", getClass().getName() + "$Context");
+ store.put(getClass().getName() + "$DisabledKeyClass", getClass().getName() + "$Context");
return store;
}
@@ -176,6 +177,14 @@ public class ContextTestInstrumentation extends Instrumenter.Default {
}
}
+ /** A class that is used that field injection can be disabled. */
+ public static class DisabledKeyClass extends KeyClass {
+ @Override
+ public boolean isInstrumented() {
+ return false;
+ }
+ }
+
public static class IncorrectKeyClassUsageKeyClass {
public boolean isInstrumented() {
return false;

MODIFY
dd-java-agent/testing/testing.gradle
dd-java-agent/testing/testing.gradle
@@ -39,3 +39,16 @@ dependencies {
testAnnotationProcessor deps.autoservice
testImplementation deps.autoservice
}
+
+// See comment for FieldBackedProviderFieldInjectionDisabledTest about why this hack is here
+tasks.withType(Test) {
+ if (name != "testDisabledFieldInjection") {
+ exclude "context/FieldBackedProviderFieldInjectionDisabledTest.class"
+ }
+}
+
+task testDisabledFieldInjection(type: Test) {
+ systemProperties "dd.trace.runtime.context.field.injection": "false"
+ include "context/FieldBackedProviderFieldInjectionDisabledTest.class"
+}
+test.dependsOn(testDisabledFieldInjection)

Add tests to verify that fields are not injected when feature is disabled