Improve config usage as instance based on CR
MODIFY
dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/decorator/BaseDecoratorTest.groovy
dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/decorator/BaseDecoratorTest.groovy
@@ -9,7 +9,6 @@ import io.opentracing.tag.Tags
import spock.lang.Shared
import spock.lang.Specification
-import static datadog.trace.agent.test.utils.ConfigUtils.withSystemProperty
import static io.opentracing.log.Fields.ERROR_OBJECT
class BaseDecoratorTest extends Specification {
@@ -168,19 +167,24 @@ class BaseDecoratorTest extends Specification {
false | true | 1.0
}
- def "test analytics rate enabled"() {
- when:
- BaseDecorator dec = withSystemProperty("dd.${integName}.analytics.enabled", "true") {
- withSystemProperty("dd.${integName}.analytics.sample-rate", "$sampleRate") {
- ConfigUtils.resetConfig()
- newDecorator(enabled)
- }
+ def "test analytics rate enabled:#enabled, integration:#integName, sampleRate:#sampleRate"() {
+ setup:
+ ConfigUtils.updateConfig {
+ System.properties.setProperty("dd.${integName}.analytics.enabled", "true")
+ System.properties.setProperty("dd.${integName}.analytics.sample-rate", "$sampleRate")
}
+ when:
+ BaseDecorator dec = newDecorator(enabled)
+
then:
dec.traceAnalyticsEnabled == expectedEnabled
dec.traceAnalyticsSampleRate == (Float) expectedRate
+ cleanup:
+ System.clearProperty("dd.${integName}.analytics.enabled")
+ System.clearProperty("dd.${integName}.analytics.sample-rate")
+
where:
enabled | integName | sampleRate | expectedEnabled | expectedRate
false | "" | "" | false | 1.0

MODIFY
dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/DefaultInstrumenterTest.groovy
dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/DefaultInstrumenterTest.groovy
@@ -80,8 +80,9 @@ class DefaultInstrumenterTest extends Specification {
def "configure default sys prop as #value"() {
setup:
+ ConfigUtils.updateConfig {
System.setProperty("dd.integrations.enabled", value)
- ConfigUtils.resetConfig()
+ }
def target = new TestDefaultInstrumenter("test")
target.instrument(new AgentBuilder.Default())

MODIFY
dd-java-agent/instrumentation/java-concurrent/src/test/groovy/ExecutorInstrumentationTest.groovy
dd-java-agent/instrumentation/java-concurrent/src/test/groovy/ExecutorInstrumentationTest.groovy
@@ -26,9 +26,9 @@ import java.util.concurrent.TimeoutException
class ExecutorInstrumentationTest extends AgentTestRunner {
static {
- ConfigUtils.makeConfigInstanceModifiable()
+ ConfigUtils.updateConfig {
System.setProperty("dd.trace.executors", "ExecutorInstrumentationTest\$CustomThreadPoolExecutor")
- ConfigUtils.resetConfig()
+ }
}
@Shared

MODIFY
dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy
dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy
@@ -9,9 +9,9 @@ import java.util.concurrent.atomic.AtomicReference
class Slf4jMDCTest extends AgentTestRunner {
static {
- ConfigUtils.makeConfigInstanceModifiable()
+ ConfigUtils.updateConfig {
System.setProperty("dd.logs.injection", "true")
- ConfigUtils.resetConfig()
+ }
}
def "mdc shows trace and span ids for active scope"() {

MODIFY
dd-java-agent/instrumentation/trace-annotation/src/test/groovy/ConfiguredTraceAnnotationsTest.groovy
dd-java-agent/instrumentation/trace-annotation/src/test/groovy/ConfiguredTraceAnnotationsTest.groovy
@@ -5,16 +5,14 @@ import dd.test.trace.annotation.SayTracedHello
import java.util.concurrent.Callable
-import static datadog.trace.agent.test.utils.ConfigUtils.withSystemProperty
import static datadog.trace.instrumentation.trace_annotation.TraceAnnotationsInstrumentation.DEFAULT_ANNOTATIONS
class ConfiguredTraceAnnotationsTest extends AgentTestRunner {
static {
- ConfigUtils.makeConfigInstanceModifiable()
- // nr annotation not included here, so should be disabled.
+ ConfigUtils.updateConfig {
System.setProperty("dd.trace.annotations", "package.Class\$Name;${OuterClass.InterestingMethod.name}")
- ConfigUtils.resetConfig()
+ }
}
def specCleanup() {
@@ -49,13 +47,16 @@ class ConfiguredTraceAnnotationsTest extends AgentTestRunner {
def "test configuration #value"() {
setup:
- def config = withSystemProperty("dd.trace.annotations", value) {
- ConfigUtils.resetConfig()
- new TraceAnnotationsInstrumentation().additionalTraceAnnotations
+ ConfigUtils.updateConfig {
+ if (value) {
+ System.properties.setProperty("dd.trace.annotations", value)
+ } else {
+ System.clearProperty("dd.trace.annotations")
+ }
}
expect:
- config == expected.toSet()
+ new TraceAnnotationsInstrumentation().additionalTraceAnnotations == expected.toSet()
where:
value | expected

MODIFY
dd-java-agent/instrumentation/trace-annotation/src/test/groovy/TraceAnnotationsTest.groovy
dd-java-agent/instrumentation/trace-annotation/src/test/groovy/TraceAnnotationsTest.groovy
@@ -10,9 +10,9 @@ import java.util.concurrent.Callable
class TraceAnnotationsTest extends AgentTestRunner {
static {
- ConfigUtils.makeConfigInstanceModifiable()
+ ConfigUtils.updateConfig {
System.clearProperty("dd.trace.annotations")
- ConfigUtils.resetConfig(true)
+ }
refreshTestTracer()
}

MODIFY
dd-java-agent/instrumentation/trace-annotation/src/test/groovy/TraceConfigTest.groovy
dd-java-agent/instrumentation/trace-annotation/src/test/groovy/TraceConfigTest.groovy
@@ -4,19 +4,18 @@ import datadog.trace.instrumentation.trace_annotation.TraceConfigInstrumentation
import java.util.concurrent.Callable
-import static datadog.trace.agent.test.utils.ConfigUtils.withSystemProperty
-
class TraceConfigTest extends AgentTestRunner {
static {
- ConfigUtils.makeConfigInstanceModifiable()
+ ConfigUtils.updateConfig {
System.setProperty("dd.trace.methods", "package.ClassName[method1,method2];${ConfigTracedCallable.name}[call]")
- ConfigUtils.resetConfig()
+ }
}
def specCleanup() {
+ ConfigUtils.updateConfig {
System.clearProperty("dd.trace.methods")
- ConfigUtils.resetConfig()
+ }
}
class ConfigTracedCallable implements Callable<String> {
@@ -46,15 +45,19 @@ class TraceConfigTest extends AgentTestRunner {
def "test configuration #value"() {
setup:
- def config = null
- withSystemProperty("dd.trace.methods", value) {
- ConfigUtils.resetConfig()
- def instrumentation = new TraceConfigInstrumentation()
- config = instrumentation.classMethodsToTrace
+ ConfigUtils.updateConfig {
+ if (value) {
+ System.properties.setProperty("dd.trace.methods", value)
+ } else {
+ System.clearProperty("dd.trace.methods")
}
+ }
+
expect:
+ new TraceConfigInstrumentation().classMethodsToTrace == expected
- config == expected
+ cleanup:
+ System.clearProperty("dd.trace.methods")
where:
value | expected

MODIFY
dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/ConfigUtils.groovy
dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/ConfigUtils.groovy
@@ -23,22 +23,6 @@ class ConfigUtils {
static final RUNTIME_ID_FIELD = Config.getDeclaredField("runtimeId")
}
- // TODO: ideally all users of this should switch to using Config object (and withConfigOverride) instead.
- @Deprecated
- @SneakyThrows
- static <T extends Object> Object withSystemProperty(final String name, final String value, final Callable<T> r) {
- if (value == null) {
- System.clearProperty(name)
- } else {
- System.setProperty(name, value)
- }
- try {
- return r.call()
- } finally {
- System.clearProperty(name)
- }
- }
-
@SneakyThrows
synchronized static <T extends Object> Object withConfigOverride(final String name, final String value, final Callable<T> r) {
// Ensure the class was retransformed properly in AgentTestRunner.makeConfigInstanceModifiable()
@@ -59,13 +43,25 @@ class ConfigUtils {
}
}
+ /**
+ * Provides an callback to set up the testing environment and reset the global configuration after system properties and envs are set.
+ *
+ * @param r
+ * @return
+ */
+ static updateConfig(final Callable r) {
+ makeConfigInstanceModifiable()
+ r.call()
+ resetConfig()
+ }
+
/**
* Calling will reset the runtimeId too, so it might cause problems around runtimeId verification.
* If you are testing runtimeId provide <code>preserveRuntimeId = false</code> to copy the previous runtimeId
* to the new config instance.
*/
- static void resetConfig(preserveRuntimeId = false) {
- // Ensure the class was retransformed properly in AgentTestRunner.makeConfigInstanceModifiable()
+ static void resetConfig(preserveRuntimeId = true) {
+ // Ensure the class was re-transformed properly in AgentTestRunner.makeConfigInstanceModifiable()
assert Modifier.isPublic(ConfigInstance.FIELD.getModifiers())
assert Modifier.isStatic(ConfigInstance.FIELD.getModifiers())
assert Modifier.isVolatile(ConfigInstance.FIELD.getModifiers())

MODIFY
dd-java-agent/testing/src/test/groovy/AgentTestRunnerTest.groovy
dd-java-agent/testing/src/test/groovy/AgentTestRunnerTest.groovy
@@ -2,6 +2,7 @@ import com.google.common.reflect.ClassPath
import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.SpockRunner
import datadog.trace.agent.test.utils.ClasspathUtils
+import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.agent.test.utils.GlobalTracerUtils
import datadog.trace.agent.tooling.Constants
import io.opentracing.Span
@@ -10,7 +11,6 @@ import spock.lang.Shared
import java.lang.reflect.Field
-import static datadog.trace.agent.test.utils.ConfigUtils.resetConfig
import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace
import static datadog.trace.api.Config.TRACE_CLASSES_EXCLUDE
@@ -23,8 +23,9 @@ class AgentTestRunnerTest extends AgentTestRunner {
private Class sharedSpanClass
static {
+ ConfigUtils.updateConfig {
System.setProperty("dd." + TRACE_CLASSES_EXCLUDE, "config.exclude.packagename.*, config.exclude.SomeClass,config.exclude.SomeClass\$NestedClass")
- resetConfig()
+ }
// when test class initializes, opentracing should be set up, but not the agent.
OT_LOADER = io.opentracing.Tracer.getClassLoader()

MODIFY
dd-trace-api/src/main/java/datadog/trace/api/Config.java
dd-trace-api/src/main/java/datadog/trace/api/Config.java
@@ -467,6 +467,17 @@ public class Config {
public boolean isIntegrationEnabled(
final SortedSet<String> integrationNames, final boolean defaultEnabled) {
+ return integrationEnabled(integrationNames, defaultEnabled);
+ }
+
+ /**
+ * @deprecated This method should only be used internally. Use the instance getter instead {@link #isIntegrationEnabled(SortedSet, boolean)}.
+ * @param integrationNames
+ * @param defaultEnabled
+ * @return
+ */
+ public static boolean integrationEnabled(
+ final SortedSet<String> integrationNames, final boolean defaultEnabled) {
// If default is enabled, we want to enable individually,
// if default is disabled, we want to disable individually.
boolean anyEnabled = defaultEnabled;
@@ -484,6 +495,17 @@ public class Config {
public boolean isJmxFetchIntegrationEnabled(
final SortedSet<String> integrationNames, final boolean defaultEnabled) {
+ return jmxFetchIntegrationEnabled(integrationNames, defaultEnabled);
+ }
+
+ /**
+ * @deprecated This method should only be used internally. Use the instance getter instead {@link #isJmxFetchIntegrationEnabled(SortedSet, boolean)}.
+ * @param integrationNames
+ * @param defaultEnabled
+ * @return
+ */
+ public static boolean jmxFetchIntegrationEnabled(
+ final SortedSet<String> integrationNames, final boolean defaultEnabled) {
// If default is enabled, we want to enable individually,
// if default is disabled, we want to disable individually.
boolean anyEnabled = defaultEnabled;
@@ -501,6 +523,17 @@ public class Config {
public boolean isTraceAnalyticsIntegrationEnabled(
final SortedSet<String> integrationNames, final boolean defaultEnabled) {
+ return traceAnalyticsIntegrationEnabled(integrationNames, defaultEnabled);
+ }
+
+ /**
+ * @deprecated This method should only be used internally. Use the instance getter instead {@link #isTraceAnalyticsIntegrationEnabled(SortedSet, boolean)}.
+ * @param integrationNames
+ * @param defaultEnabled
+ * @return
+ */
+ public static boolean traceAnalyticsIntegrationEnabled(
+ final SortedSet<String> integrationNames, final boolean defaultEnabled) {
// If default is enabled, we want to enable individually,
// if default is disabled, we want to disable individually.
boolean anyEnabled = defaultEnabled;

Improve config usage as instance based on CR