diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/decorator/BaseDecoratorTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/decorator/BaseDecoratorTest.groovy index 1ab17dc14c..80d2f83a91 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/decorator/BaseDecoratorTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/decorator/BaseDecoratorTest.groovy @@ -1,21 +1,16 @@ package datadog.trace.agent.decorator - import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.api.DDTags +import datadog.trace.util.test.DDSpecification import io.opentracing.Scope import io.opentracing.Span import io.opentracing.tag.Tags import spock.lang.Shared -import spock.lang.Specification import static io.opentracing.log.Fields.ERROR_OBJECT -class BaseDecoratorTest extends Specification { - - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class BaseDecoratorTest extends DDSpecification { @Shared def decorator = newDecorator() diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ClassLoaderMatcherTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ClassLoaderMatcherTest.groovy index 4b2178bdb7..db2271382e 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ClassLoaderMatcherTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ClassLoaderMatcherTest.groovy @@ -2,9 +2,9 @@ package datadog.trace.agent.test import datadog.trace.agent.tooling.ClassLoaderMatcher import datadog.trace.bootstrap.DatadogClassLoader -import spock.lang.Specification +import datadog.trace.util.test.DDSpecification -class ClassLoaderMatcherTest extends Specification { +class ClassLoaderMatcherTest extends DDSpecification { def "skip non-delegating classloader"() { setup: diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/DefaultInstrumenterTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/DefaultInstrumenterTest.groovy index 2d3c83e02d..63273f798c 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/DefaultInstrumenterTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/DefaultInstrumenterTest.groovy @@ -2,18 +2,15 @@ package datadog.trace.agent.test import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.agent.tooling.Instrumenter +import datadog.trace.util.test.DDSpecification import net.bytebuddy.agent.builder.AgentBuilder import net.bytebuddy.description.type.TypeDescription import net.bytebuddy.matcher.ElementMatcher import org.junit.Rule import org.junit.contrib.java.lang.system.EnvironmentVariables import org.junit.contrib.java.lang.system.RestoreSystemProperties -import spock.lang.Specification -class DefaultInstrumenterTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class DefaultInstrumenterTest extends DDSpecification { @Rule public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties() diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ExceptionHandlerTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ExceptionHandlerTest.groovy index 37c15dfc56..cedafaea29 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ExceptionHandlerTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ExceptionHandlerTest.groovy @@ -5,18 +5,18 @@ import ch.qos.logback.classic.Logger import ch.qos.logback.core.read.ListAppender import datadog.trace.agent.tooling.ExceptionHandlers import datadog.trace.bootstrap.ExceptionLogger +import datadog.trace.util.test.DDSpecification import net.bytebuddy.agent.ByteBuddyAgent import net.bytebuddy.agent.builder.AgentBuilder import net.bytebuddy.agent.builder.ResettableClassFileTransformer import net.bytebuddy.dynamic.ClassFileLocator import org.slf4j.LoggerFactory import spock.lang.Shared -import spock.lang.Specification import static net.bytebuddy.matcher.ElementMatchers.isMethod import static net.bytebuddy.matcher.ElementMatchers.named -class ExceptionHandlerTest extends Specification { +class ExceptionHandlerTest extends DDSpecification { @Shared ListAppender testAppender = new ListAppender() @Shared diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/HelperInjectionTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/HelperInjectionTest.groovy index 9445ee2e42..fa7c97ccf0 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/HelperInjectionTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/HelperInjectionTest.groovy @@ -1,14 +1,14 @@ package datadog.trace.agent.test -import datadog.trace.agent.test.utils.ConfigUtils + import datadog.trace.agent.tooling.AgentInstaller import datadog.trace.agent.tooling.HelperInjector import datadog.trace.agent.tooling.Utils +import datadog.trace.util.test.DDSpecification import net.bytebuddy.agent.ByteBuddyAgent import net.bytebuddy.description.type.TypeDescription import net.bytebuddy.dynamic.ClassFileLocator import net.bytebuddy.dynamic.loading.ClassInjector -import spock.lang.Specification import spock.lang.Timeout import java.lang.ref.WeakReference @@ -18,10 +18,7 @@ import static datadog.trace.agent.test.utils.ClasspathUtils.isClassLoaded import static datadog.trace.agent.tooling.ClassLoaderMatcher.BOOTSTRAP_CLASSLOADER import static datadog.trace.util.gc.GCUtils.awaitGC -class HelperInjectionTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class HelperInjectionTest extends DDSpecification { @Timeout(10) def "helpers injected to non-delegating classloader"() { diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ResourceLocatingTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ResourceLocatingTest.groovy index 2297b1ffea..6b4a33c9d2 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ResourceLocatingTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/test/ResourceLocatingTest.groovy @@ -1,12 +1,13 @@ package datadog.trace.agent.test import datadog.trace.agent.tooling.DDLocationStrategy -import java.util.concurrent.atomic.AtomicReference +import datadog.trace.util.test.DDSpecification import net.bytebuddy.agent.builder.AgentBuilder import spock.lang.Shared -import spock.lang.Specification -class ResourceLocatingTest extends Specification { +import java.util.concurrent.atomic.AtomicReference + +class ResourceLocatingTest extends DDSpecification { @Shared def lastLookup = new AtomicReference() @Shared diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/CleanerTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/CleanerTest.groovy index 853246797f..9611fd01e2 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/CleanerTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/CleanerTest.groovy @@ -1,7 +1,7 @@ package datadog.trace.agent.tooling import datadog.trace.util.gc.GCUtils -import spock.lang.Specification +import datadog.trace.util.test.DDSpecification import spock.lang.Subject import java.lang.ref.WeakReference @@ -10,7 +10,7 @@ import java.util.concurrent.atomic.AtomicInteger import static java.util.concurrent.TimeUnit.MILLISECONDS -class CleanerTest extends Specification { +class CleanerTest extends DDSpecification { @Subject def cleaner = new Cleaner() diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/EvictingCacheProviderTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/EvictingCacheProviderTest.groovy index 836063e745..57e64e2483 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/EvictingCacheProviderTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/EvictingCacheProviderTest.groovy @@ -1,9 +1,9 @@ package datadog.trace.agent.tooling import datadog.trace.util.gc.GCUtils +import datadog.trace.util.test.DDSpecification import net.bytebuddy.description.type.TypeDescription import net.bytebuddy.pool.TypePool -import spock.lang.Specification import spock.lang.Timeout import java.lang.ref.WeakReference @@ -13,7 +13,7 @@ import java.util.concurrent.atomic.AtomicReference import static datadog.trace.agent.tooling.AgentTooling.CLEANER @Timeout(5) -class EvictingCacheProviderTest extends Specification { +class EvictingCacheProviderTest extends DDSpecification { def "test provider"() { setup: diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/UtilsTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/UtilsTest.groovy index ced8174f61..a1c47e9116 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/UtilsTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/UtilsTest.groovy @@ -1,9 +1,8 @@ package datadog.trace.agent.tooling -import spock.lang.Specification +import datadog.trace.util.test.DDSpecification - -class UtilsTest extends Specification { +class UtilsTest extends DDSpecification { def "getStackTraceAsString() returns the stack trace as a single new line separated string"() { setup: diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/WeakConcurrentSupplierTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/WeakConcurrentSupplierTest.groovy index c355a217e9..d3b268acef 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/WeakConcurrentSupplierTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/WeakConcurrentSupplierTest.groovy @@ -2,9 +2,9 @@ package datadog.trace.agent.tooling import datadog.trace.bootstrap.WeakMap import datadog.trace.util.gc.GCUtils +import datadog.trace.util.test.DDSpecification import spock.lang.Retry import spock.lang.Shared -import spock.lang.Specification import java.lang.ref.WeakReference import java.util.concurrent.TimeUnit @@ -13,7 +13,7 @@ import static datadog.trace.agent.tooling.AgentTooling.CLEANER @Retry // These tests fail sometimes in CI. -class WeakConcurrentSupplierTest extends Specification { +class WeakConcurrentSupplierTest extends DDSpecification { @Shared def weakConcurrentSupplier = new WeakMapSuppliers.WeakConcurrent(CLEANER) @Shared diff --git a/dd-java-agent/instrumentation/jdbc/src/test/groovy/JDBCConnectionUrlParserTest.groovy b/dd-java-agent/instrumentation/jdbc/src/test/groovy/JDBCConnectionUrlParserTest.groovy index b3a662ef55..dab8483029 100644 --- a/dd-java-agent/instrumentation/jdbc/src/test/groovy/JDBCConnectionUrlParserTest.groovy +++ b/dd-java-agent/instrumentation/jdbc/src/test/groovy/JDBCConnectionUrlParserTest.groovy @@ -1,10 +1,10 @@ import datadog.trace.instrumentation.jdbc.DBInfo +import datadog.trace.util.test.DDSpecification import spock.lang.Shared -import spock.lang.Specification import static datadog.trace.instrumentation.jdbc.JDBCConnectionUrlParser.parse -class JDBCConnectionUrlParserTest extends Specification { +class JDBCConnectionUrlParserTest extends DDSpecification { @Shared def stdProps = { diff --git a/dd-java-agent/instrumentation/twilio/twilio.gradle b/dd-java-agent/instrumentation/twilio/twilio.gradle index 4e6a5a55ee..86465e983e 100644 --- a/dd-java-agent/instrumentation/twilio/twilio.gradle +++ b/dd-java-agent/instrumentation/twilio/twilio.gradle @@ -20,7 +20,6 @@ dependencies { testCompile group: 'com.twilio.sdk', name: 'twilio', version: '0.0.1' testCompile project(':dd-java-agent:instrumentation:apache-httpclient-4') testCompile project(':dd-java-agent:instrumentation:java-concurrent') - testCompile group: 'org.objenesis', name: 'objenesis', version: '2.6' // Last version to support Java7 testCompile group: 'nl.jqno.equalsverifier', name: 'equalsverifier', version: '2.5.2' // Last version to support Java7 latestDepTestCompile group: 'com.twilio.sdk', name: 'twilio', version: '+' diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/AgentTestRunner.java b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/AgentTestRunner.java index ade1181f9b..894caba16f 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/AgentTestRunner.java +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/AgentTestRunner.java @@ -7,13 +7,13 @@ import datadog.opentracing.DDSpan; import datadog.opentracing.DDTracer; import datadog.opentracing.PendingTrace; import datadog.trace.agent.test.asserts.ListWriterAssert; -import datadog.trace.agent.test.utils.ConfigUtils; import datadog.trace.agent.test.utils.GlobalTracerUtils; import datadog.trace.agent.tooling.AgentInstaller; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.api.GlobalTracer; import datadog.trace.common.writer.ListWriter; import datadog.trace.common.writer.Writer; +import datadog.trace.util.test.DDSpecification; import groovy.lang.Closure; import groovy.lang.DelegatesTo; import groovy.transform.stc.ClosureParams; @@ -41,7 +41,6 @@ import org.junit.BeforeClass; import org.junit.runner.RunWith; import org.slf4j.LoggerFactory; import org.spockframework.runtime.model.SpecMetadata; -import spock.lang.Specification; /** * A spock test runner which automatically applies instrumentation and exposes a global trace @@ -61,7 +60,7 @@ import spock.lang.Specification; @RunWith(SpockRunner.class) @SpecMetadata(filename = "AgentTestRunner.java", line = 0) @Slf4j -public abstract class AgentTestRunner extends Specification { +public abstract class AgentTestRunner extends DDSpecification { private static final long TIMEOUT_MILLIS = 10 * 1000; /** * For test runs, agent's global tracer will report to this list writer. @@ -88,8 +87,6 @@ public abstract class AgentTestRunner extends Specification { ((Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)).setLevel(Level.WARN); ((Logger) LoggerFactory.getLogger("datadog")).setLevel(Level.DEBUG); - ConfigUtils.makeConfigInstanceModifiable(); - TEST_WRITER = new ListWriter() { @Override diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/ConfigUtils.groovy b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/ConfigUtils.groovy index ee9cb9412a..c1e31efa69 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/ConfigUtils.groovy +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/ConfigUtils.groovy @@ -2,44 +2,32 @@ package datadog.trace.agent.test.utils import datadog.trace.api.Config import lombok.SneakyThrows -import net.bytebuddy.agent.ByteBuddyAgent -import net.bytebuddy.agent.builder.AgentBuilder -import net.bytebuddy.dynamic.ClassFileLocator -import net.bytebuddy.dynamic.Transformer import java.lang.reflect.Modifier import java.util.concurrent.Callable -import static net.bytebuddy.description.modifier.FieldManifestation.VOLATILE -import static net.bytebuddy.description.modifier.Ownership.STATIC -import static net.bytebuddy.description.modifier.Visibility.PUBLIC -import static net.bytebuddy.matcher.ElementMatchers.named -import static net.bytebuddy.matcher.ElementMatchers.none - class ConfigUtils { - private static class ConfigInstance { - // Wrapped in a static class to lazy load. - static final FIELD = Config.getDeclaredField("INSTANCE") - static final RUNTIME_ID_FIELD = Config.getDeclaredField("runtimeId") - } + + static final CONFIG_INSTANCE_FIELD = Config.getDeclaredField("INSTANCE") + static final RUNTIME_ID_FIELD = Config.getDeclaredField("runtimeId") @SneakyThrows synchronized static Object withConfigOverride(final String name, final String value, final Callable r) { - // Ensure the class was retransformed properly in AgentTestRunner.makeConfigInstanceModifiable() - assert Modifier.isPublic(ConfigInstance.FIELD.getModifiers()) - assert Modifier.isStatic(ConfigInstance.FIELD.getModifiers()) - assert Modifier.isVolatile(ConfigInstance.FIELD.getModifiers()) - assert !Modifier.isFinal(ConfigInstance.FIELD.getModifiers()) + // Ensure the class was retransformed properly in DDSpecification.makeConfigInstanceModifiable() + assert Modifier.isPublic(CONFIG_INSTANCE_FIELD.getModifiers()) + assert Modifier.isStatic(CONFIG_INSTANCE_FIELD.getModifiers()) + assert Modifier.isVolatile(CONFIG_INSTANCE_FIELD.getModifiers()) + assert !Modifier.isFinal(CONFIG_INSTANCE_FIELD.getModifiers()) def existingConfig = Config.get() Properties properties = new Properties() properties.put(name, value) - ConfigInstance.FIELD.set(null, new Config(properties, existingConfig)) + CONFIG_INSTANCE_FIELD.set(null, new Config(properties, existingConfig)) assert Config.get() != existingConfig try { return r.call() } finally { - ConfigInstance.FIELD.set(null, existingConfig) + CONFIG_INSTANCE_FIELD.set(null, existingConfig) } } @@ -50,7 +38,6 @@ class ConfigUtils { * @return */ static updateConfig(final Callable r) { - makeConfigInstanceModifiable() r.call() resetConfig() } @@ -59,71 +46,22 @@ class ConfigUtils { * Reset the global configuration. Please note that Runtime ID is preserved to the pre-existing value. */ static void resetConfig() { - // 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()) - assert !Modifier.isFinal(ConfigInstance.FIELD.getModifiers()) + // Ensure the class was re-transformed properly in DDSpecification.makeConfigInstanceModifiable() + assert Modifier.isPublic(CONFIG_INSTANCE_FIELD.getModifiers()) + assert Modifier.isStatic(CONFIG_INSTANCE_FIELD.getModifiers()) + assert Modifier.isVolatile(CONFIG_INSTANCE_FIELD.getModifiers()) + assert !Modifier.isFinal(CONFIG_INSTANCE_FIELD.getModifiers()) - assert Modifier.isPublic(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) - assert !Modifier.isStatic(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) - assert Modifier.isVolatile(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) - assert !Modifier.isFinal(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) + assert Modifier.isPublic(RUNTIME_ID_FIELD.getModifiers()) + assert !Modifier.isStatic(RUNTIME_ID_FIELD.getModifiers()) + assert Modifier.isVolatile(RUNTIME_ID_FIELD.getModifiers()) + assert !Modifier.isFinal(RUNTIME_ID_FIELD.getModifiers()) - def previousConfig = ConfigInstance.FIELD.get(null) + def previousConfig = CONFIG_INSTANCE_FIELD.get(null) def newConfig = new Config() - ConfigInstance.FIELD.set(null, newConfig) + CONFIG_INSTANCE_FIELD.set(null, newConfig) if (previousConfig != null) { - ConfigInstance.RUNTIME_ID_FIELD.set(newConfig, ConfigInstance.RUNTIME_ID_FIELD.get(previousConfig)) + RUNTIME_ID_FIELD.set(newConfig, RUNTIME_ID_FIELD.get(previousConfig)) } } - - // Keep track of config instance already made modifiable - private static isConfigInstanceModifiable = false - - static void makeConfigInstanceModifiable() { - if (isConfigInstanceModifiable) { - return - } - - def instrumentation = ByteBuddyAgent.install() - final transformer = - new AgentBuilder.Default() - .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) - .with(AgentBuilder.RedefinitionStrategy.Listener.ErrorEscalating.FAIL_FAST) - // Config is injected into the bootstrap, so we need to provide a locator. - .with( - new AgentBuilder.LocationStrategy.Simple( - ClassFileLocator.ForClassLoader.ofSystemLoader())) - .ignore(none()) // Allow transforming bootstrap classes - .type(named("datadog.trace.api.Config")) - .transform { builder, typeDescription, classLoader, module -> - builder - .field(named("INSTANCE")) - .transform(Transformer.ForField.withModifiers(PUBLIC, STATIC, VOLATILE)) - } - // Making runtimeId modifiable so that it can be preserved when resetting config in tests - .transform { builder, typeDescription, classLoader, module -> - builder - .field(named("runtimeId")) - .transform(Transformer.ForField.withModifiers(PUBLIC, VOLATILE)) - } - .installOn(instrumentation) - isConfigInstanceModifiable = true - - final field = ConfigInstance.FIELD - assert Modifier.isPublic(field.getModifiers()) - assert Modifier.isStatic(field.getModifiers()) - assert Modifier.isVolatile(field.getModifiers()) - assert !Modifier.isFinal(field.getModifiers()) - - final runtimeIdField = ConfigInstance.RUNTIME_ID_FIELD - assert Modifier.isPublic(runtimeIdField.getModifiers()) - assert !Modifier.isStatic(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) - assert Modifier.isVolatile(runtimeIdField.getModifiers()) - assert !Modifier.isFinal(runtimeIdField.getModifiers()) - - // No longer needed (Unless class gets retransformed somehow). - instrumentation.removeTransformer(transformer) - } } diff --git a/dd-java-agent/testing/testing.gradle b/dd-java-agent/testing/testing.gradle index 5fe8b9f022..594f938af7 100644 --- a/dd-java-agent/testing/testing.gradle +++ b/dd-java-agent/testing/testing.gradle @@ -24,6 +24,7 @@ dependencies { compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.0.0.v20110901' compile project(':dd-java-agent:agent-tooling') + compile project(':utils:test-utils') annotationProcessor deps.autoservice implementation deps.autoservice @@ -31,6 +32,7 @@ dependencies { compile deps.groovy testCompile project(':utils:gc-utils') + testCompile project(':utils:test-utils') testCompile project(':dd-java-agent:instrumentation:trace-annotation') testCompile group: 'cglib', name: 'cglib', version: '3.2.5' diff --git a/dd-trace-api/dd-trace-api.gradle b/dd-trace-api/dd-trace-api.gradle index 55eaef01f4..583ca23fb8 100644 --- a/dd-trace-api/dd-trace-api.gradle +++ b/dd-trace-api/dd-trace-api.gradle @@ -15,5 +15,5 @@ excludedClassesCoverage += [ description = 'dd-trace-api' dependencies { compile deps.slf4j - testCompile deps.junit + testCompile project(':utils:test-utils') } diff --git a/dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy b/dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy index 4a3b6bd6b5..af8c1000f3 100644 --- a/dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy +++ b/dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy @@ -1,9 +1,9 @@ package datadog.trace.api +import datadog.trace.util.test.DDSpecification import org.junit.Rule import org.junit.contrib.java.lang.system.EnvironmentVariables import org.junit.contrib.java.lang.system.RestoreSystemProperties -import spock.lang.Specification import static datadog.trace.api.Config.AGENT_HOST import static datadog.trace.api.Config.AGENT_PORT_LEGACY @@ -41,7 +41,7 @@ import static datadog.trace.api.Config.TRACE_REPORT_HOSTNAME import static datadog.trace.api.Config.TRACE_RESOLVER_ENABLED import static datadog.trace.api.Config.WRITER_TYPE -class ConfigTest extends Specification { +class ConfigTest extends DDSpecification { @Rule public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties() @Rule diff --git a/dd-trace-ot/dd-trace-ot.gradle b/dd-trace-ot/dd-trace-ot.gradle index 88421e524e..21a9e75ab6 100644 --- a/dd-trace-ot/dd-trace-ot.gradle +++ b/dd-trace-ot/dd-trace-ot.gradle @@ -44,10 +44,7 @@ dependencies { testCompile project(":dd-java-agent:testing") testCompile project(':utils:gc-utils') - testCompile group: 'org.assertj', name: 'assertj-core', version: '2.9.+' - testCompile group: 'org.mockito', name: 'mockito-core', version: '2.19.0' - testCompile group: 'org.objenesis', name: 'objenesis', version: '2.6' // Last version to support Java7 - testCompile group: 'cglib', name: 'cglib-nodep', version: '3.2.5' +// testCompile group: 'cglib', name: 'cglib-nodep', version: '3.2.5' testCompile group: 'com.github.stefanbirkner', name: 'system-rules', version: '1.17.1' traceAgentTestCompile deps.testcontainers diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/ContainerInfoTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/ContainerInfoTest.groovy index 051ab2c9c1..047eb583d5 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/ContainerInfoTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/ContainerInfoTest.groovy @@ -1,10 +1,9 @@ package datadog.opentracing -import spock.lang.Specification +import datadog.trace.util.test.DDSpecification import spock.lang.Unroll - -class ContainerInfoTest extends Specification { +class ContainerInfoTest extends DDSpecification { @Unroll def "CGroupInfo is parsed from individual lines"() { diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanBuilderTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanBuilderTest.groovy index af1aa74b89..9c5bc8946c 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanBuilderTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanBuilderTest.groovy @@ -2,24 +2,18 @@ package datadog.opentracing import datadog.opentracing.propagation.ExtractedContext import datadog.opentracing.propagation.TagContext -import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.api.Config import datadog.trace.api.DDTags import datadog.trace.api.sampling.PrioritySampling import datadog.trace.common.writer.ListWriter +import datadog.trace.util.test.DDSpecification import io.opentracing.Scope import io.opentracing.noop.NoopSpan -import spock.lang.Specification import static datadog.opentracing.DDSpanContext.ORIGIN_KEY import static java.util.concurrent.TimeUnit.MILLISECONDS -import static org.mockito.Mockito.mock -import static org.mockito.Mockito.when -class DDSpanBuilderTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class DDSpanBuilderTest extends DDSpecification { def writer = new ListWriter() def config = Config.get() @@ -158,11 +152,12 @@ class DDSpanBuilderTest extends Specification { final String spanId = "1" final long expectedParentId = spanId - final DDSpanContext mockedContext = mock(DDSpanContext) - when(mockedContext.getTraceId()).thenReturn(spanId) - when(mockedContext.getSpanId()).thenReturn(spanId) - when(mockedContext.getServiceName()).thenReturn("foo") - when(mockedContext.getTrace()).thenReturn(new PendingTrace(tracer, "1", [:])) + final DDSpanContext mockedContext = Mock() + 1 * mockedContext.getTraceId() >> spanId + 1 * mockedContext.getSpanId() >> spanId + _ * mockedContext.getServiceName() >> "foo" + 1 * mockedContext.getBaggageItems() >> [:] + 1 * mockedContext.getTrace() >> new PendingTrace(tracer, "1", [:]) final String expectedName = "fakeName" diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy index cab3819ef9..0dfeee5c63 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy @@ -2,20 +2,16 @@ package datadog.opentracing import com.fasterxml.jackson.databind.ObjectMapper import com.google.common.collect.Maps -import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.api.DDTags import datadog.trace.api.sampling.PrioritySampling import datadog.trace.common.writer.ListWriter +import datadog.trace.util.test.DDSpecification import org.msgpack.core.MessagePack import org.msgpack.core.buffer.ArrayBufferInput import org.msgpack.jackson.dataformat.MessagePackFactory import org.msgpack.value.ValueType -import spock.lang.Specification -class DDSpanSerializationTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class DDSpanSerializationTest extends DDSpecification { def "serialize spans with sampling #samplingPriority"() throws Exception { setup: diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy index 3f52e13058..e5bc5cf6a2 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy @@ -1,26 +1,21 @@ package datadog.opentracing - import com.fasterxml.jackson.databind.ObjectMapper import datadog.opentracing.propagation.ExtractedContext import datadog.opentracing.propagation.TagContext -import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.api.DDTags import datadog.trace.api.sampling.PrioritySampling import datadog.trace.common.sampling.RateByServiceSampler import datadog.trace.common.writer.ListWriter +import datadog.trace.util.test.DDSpecification import io.opentracing.SpanContext import spock.lang.Shared -import spock.lang.Specification import java.util.concurrent.TimeUnit import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME -class DDSpanTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class DDSpanTest extends DDSpecification { def writer = new ListWriter() def sampler = new RateByServiceSampler() diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy index c6915d0f65..5a1e3c6dc9 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy @@ -1,10 +1,10 @@ package datadog.opentracing -import datadog.trace.agent.test.utils.ConfigUtils + import datadog.trace.api.Config import datadog.trace.common.writer.ListWriter import datadog.trace.util.gc.GCUtils -import spock.lang.Specification +import datadog.trace.util.test.DDSpecification import spock.lang.Subject import spock.lang.Timeout @@ -14,10 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger import static datadog.trace.api.Config.PARTIAL_FLUSH_MIN_SPANS -class PendingTraceTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class PendingTraceTest extends DDSpecification { def traceCount = new AtomicInteger() def writer = new ListWriter() { diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/SpanFactory.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/SpanFactory.groovy index 8dd005d0b4..0aeb2743c5 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/SpanFactory.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/SpanFactory.groovy @@ -1,13 +1,10 @@ package datadog.opentracing -import datadog.trace.agent.test.utils.ConfigUtils + import datadog.trace.api.sampling.PrioritySampling import datadog.trace.common.writer.ListWriter class SpanFactory { - static { - ConfigUtils.makeConfigInstanceModifiable() - } static DDSpan newSpanOf(long timestampMicro, String threadName = Thread.currentThread().name) { def writer = new ListWriter() diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceCorrelationTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceCorrelationTest.groovy index ab6e97cbf2..b0b372015f 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceCorrelationTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceCorrelationTest.groovy @@ -1,14 +1,11 @@ package datadog.opentracing -import datadog.trace.agent.test.utils.ConfigUtils -import datadog.trace.common.writer.ListWriter -import spock.lang.Shared -import spock.lang.Specification -class TraceCorrelationTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +import datadog.trace.common.writer.ListWriter +import datadog.trace.util.test.DDSpecification +import spock.lang.Shared + +class TraceCorrelationTest extends DDSpecification { static final WRITER = new ListWriter() diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceInterceptorTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceInterceptorTest.groovy index efa414e0c4..afc47d5cd4 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceInterceptorTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceInterceptorTest.groovy @@ -1,18 +1,15 @@ package datadog.opentracing -import datadog.trace.agent.test.utils.ConfigUtils + import datadog.trace.api.GlobalTracer import datadog.trace.api.interceptor.MutableSpan import datadog.trace.api.interceptor.TraceInterceptor import datadog.trace.common.writer.ListWriter -import spock.lang.Specification +import datadog.trace.util.test.DDSpecification import java.util.concurrent.atomic.AtomicBoolean -class TraceInterceptorTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class TraceInterceptorTest extends DDSpecification { def writer = new ListWriter() def tracer = new DDTracer(writer) diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/SpanDecoratorTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/SpanDecoratorTest.groovy index 941316bf43..38eb6a57f9 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/SpanDecoratorTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/SpanDecoratorTest.groovy @@ -9,17 +9,16 @@ import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDTags import datadog.trace.common.sampling.AllSampler import datadog.trace.common.writer.LoggingWriter +import datadog.trace.util.test.DDSpecification import io.opentracing.tag.StringTag import io.opentracing.tag.Tags -import spock.lang.Specification import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME import static datadog.trace.api.DDTags.EVENT_SAMPLE_RATE import static java.util.Collections.emptyMap -class SpanDecoratorTest extends Specification { +class SpanDecoratorTest extends DDSpecification { static { - ConfigUtils.makeConfigInstanceModifiable() ConfigUtils.updateConfig { System.setProperty("dd.$Config.SPLIT_BY_TAGS", "sn.tag1,sn.tag2") } diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/URLAsResourceNameTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/URLAsResourceNameTest.groovy index aa917ed790..8735e8bb3d 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/URLAsResourceNameTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/URLAsResourceNameTest.groovy @@ -3,17 +3,13 @@ package datadog.opentracing.decorators import datadog.opentracing.DDSpanContext import datadog.opentracing.DDTracer import datadog.opentracing.PendingTrace -import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.api.sampling.PrioritySampling import datadog.trace.common.writer.ListWriter +import datadog.trace.util.test.DDSpecification import io.opentracing.tag.Tags -import spock.lang.Specification import spock.lang.Subject -class URLAsResourceNameTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class URLAsResourceNameTest extends DDSpecification { def writer = new ListWriter() def tracer = new DDTracer(writer) diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/B3HttpExtractorTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/B3HttpExtractorTest.groovy index 333ad49579..38af09be29 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/B3HttpExtractorTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/B3HttpExtractorTest.groovy @@ -1,16 +1,16 @@ package datadog.opentracing.propagation import datadog.trace.api.sampling.PrioritySampling +import datadog.trace.util.test.DDSpecification import io.opentracing.SpanContext import io.opentracing.propagation.TextMapExtractAdapter -import spock.lang.Specification import static datadog.opentracing.propagation.B3HttpCodec.SAMPLING_PRIORITY_KEY import static datadog.opentracing.propagation.B3HttpCodec.SPAN_ID_KEY import static datadog.opentracing.propagation.B3HttpCodec.TRACE_ID_KEY import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX -class B3HttpExtractorTest extends Specification { +class B3HttpExtractorTest extends DDSpecification { HttpCodec.Extractor extractor = new B3HttpCodec.Extractor(["SOME_HEADER": "some-tag"]) diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/B3HttpInjectorTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/B3HttpInjectorTest.groovy index 0e0206ef91..1279d530e7 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/B3HttpInjectorTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/B3HttpInjectorTest.groovy @@ -5,15 +5,15 @@ import datadog.opentracing.DDTracer import datadog.opentracing.PendingTrace import datadog.trace.api.sampling.PrioritySampling import datadog.trace.common.writer.ListWriter +import datadog.trace.util.test.DDSpecification import io.opentracing.propagation.TextMapInjectAdapter -import spock.lang.Specification import static datadog.opentracing.propagation.B3HttpCodec.SAMPLING_PRIORITY_KEY import static datadog.opentracing.propagation.B3HttpCodec.SPAN_ID_KEY import static datadog.opentracing.propagation.B3HttpCodec.TRACE_ID_KEY import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX -class B3HttpInjectorTest extends Specification { +class B3HttpInjectorTest extends DDSpecification { HttpCodec.Injector injector = new B3HttpCodec.Injector() diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/DatadogHttpExtractorTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/DatadogHttpExtractorTest.groovy index aa3a73c9c0..8982691c0a 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/DatadogHttpExtractorTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/DatadogHttpExtractorTest.groovy @@ -1,9 +1,9 @@ package datadog.opentracing.propagation import datadog.trace.api.sampling.PrioritySampling +import datadog.trace.util.test.DDSpecification import io.opentracing.SpanContext import io.opentracing.propagation.TextMapExtractAdapter -import spock.lang.Specification import static datadog.opentracing.propagation.DatadogHttpCodec.ORIGIN_KEY import static datadog.opentracing.propagation.DatadogHttpCodec.OT_BAGGAGE_PREFIX @@ -12,7 +12,7 @@ import static datadog.opentracing.propagation.DatadogHttpCodec.SPAN_ID_KEY import static datadog.opentracing.propagation.DatadogHttpCodec.TRACE_ID_KEY import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX -class DatadogHttpExtractorTest extends Specification { +class DatadogHttpExtractorTest extends DDSpecification { HttpCodec.Extractor extractor = new DatadogHttpCodec.Extractor(["SOME_HEADER": "some-tag"]) diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/DatadogHttpInjectorTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/DatadogHttpInjectorTest.groovy index 8bf3e8983d..ea287b9091 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/DatadogHttpInjectorTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/DatadogHttpInjectorTest.groovy @@ -5,8 +5,8 @@ import datadog.opentracing.DDTracer import datadog.opentracing.PendingTrace import datadog.trace.api.sampling.PrioritySampling import datadog.trace.common.writer.ListWriter +import datadog.trace.util.test.DDSpecification import io.opentracing.propagation.TextMapInjectAdapter -import spock.lang.Specification import static datadog.opentracing.propagation.DatadogHttpCodec.ORIGIN_KEY import static datadog.opentracing.propagation.DatadogHttpCodec.OT_BAGGAGE_PREFIX @@ -15,7 +15,7 @@ import static datadog.opentracing.propagation.DatadogHttpCodec.SPAN_ID_KEY import static datadog.opentracing.propagation.DatadogHttpCodec.TRACE_ID_KEY import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX -class DatadogHttpInjectorTest extends Specification { +class DatadogHttpInjectorTest extends DDSpecification { HttpCodec.Injector injector = new DatadogHttpCodec.Injector() diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HaystackHttpExtractorTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HaystackHttpExtractorTest.groovy index 5278109504..d8aaeeb38e 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HaystackHttpExtractorTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HaystackHttpExtractorTest.groovy @@ -1,16 +1,16 @@ package datadog.opentracing.propagation import datadog.trace.api.sampling.PrioritySampling +import datadog.trace.util.test.DDSpecification import io.opentracing.SpanContext import io.opentracing.propagation.TextMapExtractAdapter -import spock.lang.Specification import static datadog.opentracing.propagation.HaystackHttpCodec.OT_BAGGAGE_PREFIX import static datadog.opentracing.propagation.HaystackHttpCodec.SPAN_ID_KEY import static datadog.opentracing.propagation.HaystackHttpCodec.TRACE_ID_KEY import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX -class HaystackHttpExtractorTest extends Specification { +class HaystackHttpExtractorTest extends DDSpecification { HttpCodec.Extractor extractor = new HaystackHttpCodec.Extractor(["SOME_HEADER": "some-tag"]) @@ -53,8 +53,8 @@ class HaystackHttpExtractorTest extends Specification { where: - headers | _ - [SOME_HEADER: "my-interesting-info"] | _ + headers | _ + [SOME_HEADER: "my-interesting-info"] | _ } def "extract empty headers returns null"() { diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HaystackHttpInjectorTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HaystackHttpInjectorTest.groovy index 2172d56f72..7e0885838d 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HaystackHttpInjectorTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HaystackHttpInjectorTest.groovy @@ -5,15 +5,15 @@ import datadog.opentracing.DDTracer import datadog.opentracing.PendingTrace import datadog.trace.api.sampling.PrioritySampling import datadog.trace.common.writer.ListWriter +import datadog.trace.util.test.DDSpecification import io.opentracing.propagation.TextMapInjectAdapter -import spock.lang.Specification import static datadog.opentracing.propagation.HaystackHttpCodec.OT_BAGGAGE_PREFIX import static datadog.opentracing.propagation.HaystackHttpCodec.SPAN_ID_KEY import static datadog.opentracing.propagation.HaystackHttpCodec.TRACE_ID_KEY import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX -class HaystackHttpInjectorTest extends Specification { +class HaystackHttpInjectorTest extends DDSpecification { HttpCodec.Injector injector = new HaystackHttpCodec.Injector() @@ -55,7 +55,6 @@ class HaystackHttpInjectorTest extends Specification { 1 * carrier.put(OT_BAGGAGE_PREFIX + "k2", "v2") - where: traceId | spanId | samplingPriority | origin "1" | "2" | PrioritySampling.SAMPLER_KEEP | null diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HttpExtractorTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HttpExtractorTest.groovy index 40e402253a..e148654d9d 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HttpExtractorTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HttpExtractorTest.groovy @@ -1,20 +1,17 @@ package datadog.opentracing.propagation -import datadog.trace.agent.test.utils.ConfigUtils + import datadog.trace.api.Config +import datadog.trace.util.test.DDSpecification import io.opentracing.SpanContext import io.opentracing.propagation.TextMapExtractAdapter import spock.lang.Shared -import spock.lang.Specification import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX import static datadog.trace.api.Config.PropagationStyle.B3 import static datadog.trace.api.Config.PropagationStyle.DATADOG -class HttpExtractorTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class HttpExtractorTest extends DDSpecification { @Shared String outOfRangeTraceId = UINT64_MAX.add(BigInteger.ONE) diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HttpInjectorTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HttpInjectorTest.groovy index 192315811c..6a38f52ccf 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HttpInjectorTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HttpInjectorTest.groovy @@ -3,20 +3,16 @@ package datadog.opentracing.propagation import datadog.opentracing.DDSpanContext import datadog.opentracing.DDTracer import datadog.opentracing.PendingTrace -import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.api.Config import datadog.trace.api.sampling.PrioritySampling import datadog.trace.common.writer.ListWriter +import datadog.trace.util.test.DDSpecification import io.opentracing.propagation.TextMapInjectAdapter -import spock.lang.Specification import static datadog.trace.api.Config.PropagationStyle.B3 import static datadog.trace.api.Config.PropagationStyle.DATADOG -class HttpInjectorTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class HttpInjectorTest extends DDSpecification { def "inject http headers"() { setup: diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/resolver/DDTracerResolverTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/resolver/DDTracerResolverTest.groovy index b2c1381566..683f0f71b4 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/resolver/DDTracerResolverTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/resolver/DDTracerResolverTest.groovy @@ -1,15 +1,11 @@ package datadog.opentracing.resolver import datadog.opentracing.DDTracer -import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.api.Config +import datadog.trace.util.test.DDSpecification import io.opentracing.contrib.tracerresolver.TracerResolver -import spock.lang.Specification -class DDTracerResolverTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class DDTracerResolverTest extends DDSpecification { def resolver = new DDTracerResolver() diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/scopemanager/ScopeManagerTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/scopemanager/ScopeManagerTest.groovy index 6e8128e33e..cf64b1b31d 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/scopemanager/ScopeManagerTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/scopemanager/ScopeManagerTest.groovy @@ -3,14 +3,13 @@ package datadog.opentracing.scopemanager import datadog.opentracing.DDSpan import datadog.opentracing.DDSpanContext import datadog.opentracing.DDTracer -import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.common.writer.ListWriter import datadog.trace.context.ScopeListener import datadog.trace.util.gc.GCUtils +import datadog.trace.util.test.DDSpecification import io.opentracing.Scope import io.opentracing.Span import io.opentracing.noop.NoopSpan -import spock.lang.Specification import spock.lang.Subject import spock.lang.Timeout @@ -22,10 +21,7 @@ import java.util.concurrent.atomic.AtomicReference import static java.util.concurrent.TimeUnit.SECONDS -class ScopeManagerTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class ScopeManagerTest extends DDSpecification { def latch def writer def tracer diff --git a/dd-trace-ot/src/test/groovy/datadog/trace/DDSpanContextTest.groovy b/dd-trace-ot/src/test/groovy/datadog/trace/DDSpanContextTest.groovy index 3d0c096b5d..ce2b423829 100644 --- a/dd-trace-ot/src/test/groovy/datadog/trace/DDSpanContextTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/trace/DDSpanContextTest.groovy @@ -2,9 +2,9 @@ package datadog.trace import datadog.opentracing.SpanFactory import datadog.trace.api.DDTags -import spock.lang.Specification +import datadog.trace.util.test.DDSpecification -class DDSpanContextTest extends Specification { +class DDSpanContextTest extends DDSpecification { def "null values for tags delete existing tags"() { setup: diff --git a/dd-trace-ot/src/test/groovy/datadog/trace/DDTracerTest.groovy b/dd-trace-ot/src/test/groovy/datadog/trace/DDTracerTest.groovy index 3ca70fe398..68ab6d42b1 100644 --- a/dd-trace-ot/src/test/groovy/datadog/trace/DDTracerTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/trace/DDTracerTest.groovy @@ -2,17 +2,16 @@ package datadog.trace import datadog.opentracing.DDTracer import datadog.opentracing.propagation.HttpCodec -import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.api.Config import datadog.trace.common.sampling.AllSampler import datadog.trace.common.sampling.RateByServiceSampler import datadog.trace.common.writer.DDAgentWriter import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.LoggingWriter +import datadog.trace.util.test.DDSpecification import org.junit.Rule import org.junit.contrib.java.lang.system.EnvironmentVariables import org.junit.contrib.java.lang.system.RestoreSystemProperties -import spock.lang.Specification import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME import static datadog.trace.api.Config.HEADER_TAGS @@ -22,10 +21,7 @@ import static datadog.trace.api.Config.SERVICE_MAPPING import static datadog.trace.api.Config.SPAN_TAGS import static datadog.trace.api.Config.WRITER_TYPE -class DDTracerTest extends Specification { - static { - ConfigUtils.makeConfigInstanceModifiable() - } +class DDTracerTest extends DDSpecification { @Rule public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties() diff --git a/dd-trace-ot/src/test/groovy/datadog/trace/api/sampling/AllSamplerTest.groovy b/dd-trace-ot/src/test/groovy/datadog/trace/api/sampling/AllSamplerTest.groovy new file mode 100644 index 0000000000..ff259ec4d9 --- /dev/null +++ b/dd-trace-ot/src/test/groovy/datadog/trace/api/sampling/AllSamplerTest.groovy @@ -0,0 +1,42 @@ +package datadog.trace.api.sampling + +import datadog.opentracing.DDSpan +import datadog.trace.common.sampling.AllSampler +import datadog.trace.util.test.DDSpecification +import spock.lang.Subject + +import java.util.regex.Pattern + +class AllSamplerTest extends DDSpecification { + + @Subject + DDSpan span = Mock() + + private final AllSampler sampler = new AllSampler() + + def "test AllSampler"() { + expect: + for (int i = 0; i < 500; i++) { + assert sampler.doSample(span) + } + } + + def "test skip tag sampler"() { + setup: + final Map tags = new HashMap<>() + 2 * span.getTags() >> tags + sampler.addSkipTagPattern("http.url", Pattern.compile(".*/hello")) + + when: + tags.put("http.url", "http://a/hello") + + then: + !sampler.sample(span) + + when: + tags.put("http.url", "http://a/hello2") + + then: + sampler.sample(span) + } +} diff --git a/dd-trace-ot/src/test/groovy/datadog/trace/api/sampling/RateByServiceSamplerTest.groovy b/dd-trace-ot/src/test/groovy/datadog/trace/api/sampling/RateByServiceSamplerTest.groovy index 0bf11278b6..a34b9b12b3 100644 --- a/dd-trace-ot/src/test/groovy/datadog/trace/api/sampling/RateByServiceSamplerTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/trace/api/sampling/RateByServiceSamplerTest.groovy @@ -4,11 +4,11 @@ import com.fasterxml.jackson.databind.ObjectMapper import datadog.opentracing.DDSpan import datadog.opentracing.SpanFactory import datadog.trace.common.sampling.RateByServiceSampler -import spock.lang.Specification +import datadog.trace.util.test.DDSpecification import static datadog.trace.common.sampling.RateByServiceSampler.DEFAULT_KEY -class RateByServiceSamplerTest extends Specification { +class RateByServiceSamplerTest extends DDSpecification { def "invalid rate -> 1"() { setup: diff --git a/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDAgentWriterTest.groovy b/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDAgentWriterTest.groovy index e64e3e2205..160e41ba99 100644 --- a/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDAgentWriterTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDAgentWriterTest.groovy @@ -7,7 +7,7 @@ import datadog.opentracing.PendingTrace import datadog.trace.api.sampling.PrioritySampling import datadog.trace.common.writer.DDAgentWriter import datadog.trace.common.writer.DDApi -import spock.lang.Specification +import datadog.trace.util.test.DDSpecification import spock.lang.Timeout import java.util.concurrent.TimeUnit @@ -16,7 +16,7 @@ import static datadog.opentracing.SpanFactory.newSpanOf import static datadog.trace.common.writer.DDAgentWriter.DISRUPTOR_BUFFER_SIZE @Timeout(20) -class DDAgentWriterTest extends Specification { +class DDAgentWriterTest extends DDSpecification { def api = Mock(DDApi) diff --git a/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDApiTest.groovy b/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDApiTest.groovy index f967b357cf..64523f6f60 100644 --- a/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDApiTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDApiTest.groovy @@ -5,14 +5,14 @@ import com.fasterxml.jackson.databind.JsonNode import datadog.opentracing.SpanFactory import datadog.trace.common.writer.DDApi import datadog.trace.common.writer.DDApi.ResponseListener -import spock.lang.Specification +import datadog.trace.util.test.DDSpecification import java.util.concurrent.atomic.AtomicLong import java.util.concurrent.atomic.AtomicReference import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer -class DDApiTest extends Specification { +class DDApiTest extends DDSpecification { static mapper = DDApi.OBJECT_MAPPER def "sending an empty list of traces returns no errors"() { diff --git a/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/SerializationTest.groovy b/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/SerializationTest.groovy index 1c8845f1d0..fde8855175 100644 --- a/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/SerializationTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/SerializationTest.groovy @@ -1,22 +1,21 @@ package datadog.trace.api.writer - import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.databind.ObjectMapper +import datadog.trace.util.test.DDSpecification import org.msgpack.core.MessagePack import org.msgpack.jackson.dataformat.MessagePackFactory import spock.lang.Shared -import spock.lang.Specification import static java.util.Collections.singletonMap -class SerializationTest extends Specification { +class SerializationTest extends DDSpecification { @Shared def jsonMapper = new ObjectMapper() @Shared def mpMapper = new ObjectMapper(new MessagePackFactory()) - + def "test json mapper serialization"() { setup: def map = ["key1": "val1"] diff --git a/dd-trace-ot/src/test/java/datadog/trace/api/sampling/AllSamplerTest.java b/dd-trace-ot/src/test/java/datadog/trace/api/sampling/AllSamplerTest.java deleted file mode 100644 index 618ae6701b..0000000000 --- a/dd-trace-ot/src/test/java/datadog/trace/api/sampling/AllSamplerTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package datadog.trace.api.sampling; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import datadog.opentracing.DDSpan; -import datadog.trace.common.sampling.AllSampler; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Pattern; -import org.junit.Test; -import org.mockito.Mock; - -public class AllSamplerTest { - - @Mock DDSpan mockSpan; - - private final AllSampler sampler = new AllSampler(); - - @Test - public void testAllSampler() { - - for (int i = 0; i < 500; i++) { - assertThat(sampler.doSample(mockSpan)).isTrue(); - } - } - - @Test - public void testSkipTagPatternSampler() { - - final Map tags = new HashMap<>(); - mockSpan = mock(DDSpan.class); - when(mockSpan.getTags()).thenReturn(tags).thenReturn(tags); - - sampler.addSkipTagPattern("http.url", Pattern.compile(".*/hello")); - - tags.put("http.url", "http://a/hello"); - assertThat(sampler.sample(mockSpan)).isFalse(); - - tags.put("http.url", "http://a/hello2"); - assertThat(sampler.sample(mockSpan)).isTrue(); - } -} diff --git a/dd-trace-ot/src/traceAgentTest/groovy/DDApiIntegrationTest.groovy b/dd-trace-ot/src/traceAgentTest/groovy/DDApiIntegrationTest.groovy index 3282384b9f..81cb6d4b72 100644 --- a/dd-trace-ot/src/traceAgentTest/groovy/DDApiIntegrationTest.groovy +++ b/dd-trace-ot/src/traceAgentTest/groovy/DDApiIntegrationTest.groovy @@ -6,11 +6,11 @@ import datadog.opentracing.PendingTrace import datadog.trace.api.sampling.PrioritySampling import datadog.trace.common.writer.DDApi import datadog.trace.common.writer.ListWriter +import datadog.trace.util.test.DDSpecification import org.testcontainers.containers.GenericContainer import org.testcontainers.containers.startupcheck.MinimumDurationRunningStartupCheckStrategy import spock.lang.Requires import spock.lang.Shared -import spock.lang.Specification import java.time.Duration import java.util.concurrent.TimeUnit @@ -20,7 +20,7 @@ class DDApiIntegrationTest { // Do not run tests locally on Java7 since testcontainers are not compatible with Java7 // It is fine to run on CI because CI provides rabbitmq externally, not through testcontainers @Requires({ "true" == System.getenv("CI") || jvm.java8Compatible }) - static class DDApiIntegrationV4Test extends Specification { + static class DDApiIntegrationV4Test extends DDSpecification { static final WRITER = new ListWriter() static final TRACER = new DDTracer(WRITER) static final CONTEXT = new DDSpanContext( diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index bb3ca933e5..219ffe7475 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -49,9 +49,14 @@ ext { ], // Testing - spock : dependencies.create("org.spockframework:spock-core:${versions.spock}", { - exclude group: 'org.codehaus.groovy', module: 'groovy-all' - }), + + spock : [ + dependencies.create("org.spockframework:spock-core:${versions.spock}", { + exclude group: 'org.codehaus.groovy', module: 'groovy-all' + }), + // Used by Spock for mocking: + dependencies.create(group: 'org.objenesis', name: 'objenesis', version: '2.6') // Last version to support Java7 + ], groovy : "org.codehaus.groovy:groovy-all:${versions.groovy}", junit : "junit:junit:${versions.junit}", testcontainers : "org.testcontainers:testcontainers:1.7.3", diff --git a/settings.gradle b/settings.gradle index 721a94a2e1..48d472a230 100644 --- a/settings.gradle +++ b/settings.gradle @@ -13,6 +13,7 @@ include ':dd-java-agent:agent-jmxfetch' // misc include ':dd-java-agent:testing' include ':utils:gc-utils' +include ':utils:test-utils' // smoke tests include ':dd-smoke-tests:cli' diff --git a/utils/test-utils/src/main/groovy/datadog/trace/util/test/DDSpecification.groovy b/utils/test-utils/src/main/groovy/datadog/trace/util/test/DDSpecification.groovy new file mode 100644 index 0000000000..0e94ad5074 --- /dev/null +++ b/utils/test-utils/src/main/groovy/datadog/trace/util/test/DDSpecification.groovy @@ -0,0 +1,78 @@ +package datadog.trace.util.test + +import net.bytebuddy.agent.ByteBuddyAgent +import net.bytebuddy.agent.builder.AgentBuilder +import net.bytebuddy.dynamic.ClassFileLocator +import net.bytebuddy.dynamic.Transformer +import spock.lang.Specification + +import java.lang.reflect.Modifier + +import static net.bytebuddy.description.modifier.FieldManifestation.VOLATILE +import static net.bytebuddy.description.modifier.Ownership.STATIC +import static net.bytebuddy.description.modifier.Visibility.PUBLIC +import static net.bytebuddy.matcher.ElementMatchers.named +import static net.bytebuddy.matcher.ElementMatchers.none + +abstract class DDSpecification extends Specification { + private static final String CONFIG = "datadog.trace.api.Config" + + static class ConfigInstance { + // Wrapped in a static class to lazy load. + static final CONFIG_INSTANCE_FIELD = Class.forName(CONFIG).getDeclaredField("INSTANCE") + static final RUNTIME_ID_FIELD = Class.forName(CONFIG).getDeclaredField("runtimeId") + } + + static { + makeConfigInstanceModifiable() + } + + // Keep track of config instance already made modifiable + private static isConfigInstanceModifiable = false + + static void makeConfigInstanceModifiable() { + if (isConfigInstanceModifiable) { + return + } + + def instrumentation = ByteBuddyAgent.install() + final transformer = + new AgentBuilder.Default() + .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) + .with(AgentBuilder.RedefinitionStrategy.Listener.ErrorEscalating.FAIL_FAST) + // Config is injected into the bootstrap, so we need to provide a locator. + .with( + new AgentBuilder.LocationStrategy.Simple( + ClassFileLocator.ForClassLoader.ofSystemLoader())) + .ignore(none()) // Allow transforming bootstrap classes + .type(named(CONFIG)) + .transform { builder, typeDescription, classLoader, module -> + builder + .field(named("INSTANCE")) + .transform(Transformer.ForField.withModifiers(PUBLIC, STATIC, VOLATILE)) + } + // Making runtimeId modifiable so that it can be preserved when resetting config in tests + .transform { builder, typeDescription, classLoader, module -> + builder + .field(named("runtimeId")) + .transform(Transformer.ForField.withModifiers(PUBLIC, VOLATILE)) + } + .installOn(instrumentation) + isConfigInstanceModifiable = true + + final field = ConfigInstance.CONFIG_INSTANCE_FIELD + assert Modifier.isPublic(field.getModifiers()) + assert Modifier.isStatic(field.getModifiers()) + assert Modifier.isVolatile(field.getModifiers()) + assert !Modifier.isFinal(field.getModifiers()) + + final runtimeIdField = ConfigInstance.RUNTIME_ID_FIELD + assert Modifier.isPublic(runtimeIdField.getModifiers()) + assert !Modifier.isStatic(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) + assert Modifier.isVolatile(runtimeIdField.getModifiers()) + assert !Modifier.isFinal(runtimeIdField.getModifiers()) + + // No longer needed (Unless class gets retransformed somehow). + instrumentation.removeTransformer(transformer) + } +} diff --git a/utils/test-utils/test-utils.gradle b/utils/test-utils/test-utils.gradle new file mode 100644 index 0000000000..68d1f4ebdc --- /dev/null +++ b/utils/test-utils/test-utils.gradle @@ -0,0 +1,9 @@ +apply from: "${rootDir}/gradle/java.gradle" + +dependencies { + compile deps.groovy + compile deps.spock + + compile deps.bytebuddy + compile deps.bytebuddyagent +}