Extract base test class and move Config class changes there.

This commit is contained in:
Tyler Benson 2019-10-07 18:51:02 +02:00
parent 654e09ee7f
commit 9ef3332140
51 changed files with 261 additions and 301 deletions

View File

@ -1,21 +1,16 @@
package datadog.trace.agent.decorator package datadog.trace.agent.decorator
import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import datadog.trace.util.test.DDSpecification
import io.opentracing.Scope import io.opentracing.Scope
import io.opentracing.Span import io.opentracing.Span
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification
import static io.opentracing.log.Fields.ERROR_OBJECT import static io.opentracing.log.Fields.ERROR_OBJECT
class BaseDecoratorTest extends Specification { class BaseDecoratorTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
@Shared @Shared
def decorator = newDecorator() def decorator = newDecorator()

View File

@ -2,9 +2,9 @@ package datadog.trace.agent.test
import datadog.trace.agent.tooling.ClassLoaderMatcher import datadog.trace.agent.tooling.ClassLoaderMatcher
import datadog.trace.bootstrap.DatadogClassLoader 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"() { def "skip non-delegating classloader"() {
setup: setup:

View File

@ -2,18 +2,15 @@ package datadog.trace.agent.test
import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.agent.tooling.Instrumenter import datadog.trace.agent.tooling.Instrumenter
import datadog.trace.util.test.DDSpecification
import net.bytebuddy.agent.builder.AgentBuilder import net.bytebuddy.agent.builder.AgentBuilder
import net.bytebuddy.description.type.TypeDescription import net.bytebuddy.description.type.TypeDescription
import net.bytebuddy.matcher.ElementMatcher import net.bytebuddy.matcher.ElementMatcher
import org.junit.Rule import org.junit.Rule
import org.junit.contrib.java.lang.system.EnvironmentVariables import org.junit.contrib.java.lang.system.EnvironmentVariables
import org.junit.contrib.java.lang.system.RestoreSystemProperties import org.junit.contrib.java.lang.system.RestoreSystemProperties
import spock.lang.Specification
class DefaultInstrumenterTest extends Specification { class DefaultInstrumenterTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
@Rule @Rule
public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties() public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties()

View File

@ -5,18 +5,18 @@ import ch.qos.logback.classic.Logger
import ch.qos.logback.core.read.ListAppender import ch.qos.logback.core.read.ListAppender
import datadog.trace.agent.tooling.ExceptionHandlers import datadog.trace.agent.tooling.ExceptionHandlers
import datadog.trace.bootstrap.ExceptionLogger import datadog.trace.bootstrap.ExceptionLogger
import datadog.trace.util.test.DDSpecification
import net.bytebuddy.agent.ByteBuddyAgent import net.bytebuddy.agent.ByteBuddyAgent
import net.bytebuddy.agent.builder.AgentBuilder import net.bytebuddy.agent.builder.AgentBuilder
import net.bytebuddy.agent.builder.ResettableClassFileTransformer import net.bytebuddy.agent.builder.ResettableClassFileTransformer
import net.bytebuddy.dynamic.ClassFileLocator import net.bytebuddy.dynamic.ClassFileLocator
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification
import static net.bytebuddy.matcher.ElementMatchers.isMethod import static net.bytebuddy.matcher.ElementMatchers.isMethod
import static net.bytebuddy.matcher.ElementMatchers.named import static net.bytebuddy.matcher.ElementMatchers.named
class ExceptionHandlerTest extends Specification { class ExceptionHandlerTest extends DDSpecification {
@Shared @Shared
ListAppender testAppender = new ListAppender() ListAppender testAppender = new ListAppender()
@Shared @Shared

View File

@ -1,14 +1,14 @@
package datadog.trace.agent.test package datadog.trace.agent.test
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.agent.tooling.AgentInstaller import datadog.trace.agent.tooling.AgentInstaller
import datadog.trace.agent.tooling.HelperInjector import datadog.trace.agent.tooling.HelperInjector
import datadog.trace.agent.tooling.Utils import datadog.trace.agent.tooling.Utils
import datadog.trace.util.test.DDSpecification
import net.bytebuddy.agent.ByteBuddyAgent import net.bytebuddy.agent.ByteBuddyAgent
import net.bytebuddy.description.type.TypeDescription import net.bytebuddy.description.type.TypeDescription
import net.bytebuddy.dynamic.ClassFileLocator import net.bytebuddy.dynamic.ClassFileLocator
import net.bytebuddy.dynamic.loading.ClassInjector import net.bytebuddy.dynamic.loading.ClassInjector
import spock.lang.Specification
import spock.lang.Timeout import spock.lang.Timeout
import java.lang.ref.WeakReference 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.agent.tooling.ClassLoaderMatcher.BOOTSTRAP_CLASSLOADER
import static datadog.trace.util.gc.GCUtils.awaitGC import static datadog.trace.util.gc.GCUtils.awaitGC
class HelperInjectionTest extends Specification { class HelperInjectionTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
@Timeout(10) @Timeout(10)
def "helpers injected to non-delegating classloader"() { def "helpers injected to non-delegating classloader"() {

View File

@ -1,12 +1,13 @@
package datadog.trace.agent.test package datadog.trace.agent.test
import datadog.trace.agent.tooling.DDLocationStrategy 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 net.bytebuddy.agent.builder.AgentBuilder
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification
class ResourceLocatingTest extends Specification { import java.util.concurrent.atomic.AtomicReference
class ResourceLocatingTest extends DDSpecification {
@Shared @Shared
def lastLookup = new AtomicReference<String>() def lastLookup = new AtomicReference<String>()
@Shared @Shared

View File

@ -1,7 +1,7 @@
package datadog.trace.agent.tooling package datadog.trace.agent.tooling
import datadog.trace.util.gc.GCUtils import datadog.trace.util.gc.GCUtils
import spock.lang.Specification import datadog.trace.util.test.DDSpecification
import spock.lang.Subject import spock.lang.Subject
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@ -10,7 +10,7 @@ import java.util.concurrent.atomic.AtomicInteger
import static java.util.concurrent.TimeUnit.MILLISECONDS import static java.util.concurrent.TimeUnit.MILLISECONDS
class CleanerTest extends Specification { class CleanerTest extends DDSpecification {
@Subject @Subject
def cleaner = new Cleaner() def cleaner = new Cleaner()

View File

@ -1,9 +1,9 @@
package datadog.trace.agent.tooling package datadog.trace.agent.tooling
import datadog.trace.util.gc.GCUtils import datadog.trace.util.gc.GCUtils
import datadog.trace.util.test.DDSpecification
import net.bytebuddy.description.type.TypeDescription import net.bytebuddy.description.type.TypeDescription
import net.bytebuddy.pool.TypePool import net.bytebuddy.pool.TypePool
import spock.lang.Specification
import spock.lang.Timeout import spock.lang.Timeout
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@ -13,7 +13,7 @@ import java.util.concurrent.atomic.AtomicReference
import static datadog.trace.agent.tooling.AgentTooling.CLEANER import static datadog.trace.agent.tooling.AgentTooling.CLEANER
@Timeout(5) @Timeout(5)
class EvictingCacheProviderTest extends Specification { class EvictingCacheProviderTest extends DDSpecification {
def "test provider"() { def "test provider"() {
setup: setup:

View File

@ -1,9 +1,8 @@
package datadog.trace.agent.tooling package datadog.trace.agent.tooling
import spock.lang.Specification import datadog.trace.util.test.DDSpecification
class UtilsTest extends DDSpecification {
class UtilsTest extends Specification {
def "getStackTraceAsString() returns the stack trace as a single new line separated string"() { def "getStackTraceAsString() returns the stack trace as a single new line separated string"() {
setup: setup:

View File

@ -2,9 +2,9 @@ package datadog.trace.agent.tooling
import datadog.trace.bootstrap.WeakMap import datadog.trace.bootstrap.WeakMap
import datadog.trace.util.gc.GCUtils import datadog.trace.util.gc.GCUtils
import datadog.trace.util.test.DDSpecification
import spock.lang.Retry import spock.lang.Retry
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -13,7 +13,7 @@ import static datadog.trace.agent.tooling.AgentTooling.CLEANER
@Retry @Retry
// These tests fail sometimes in CI. // These tests fail sometimes in CI.
class WeakConcurrentSupplierTest extends Specification { class WeakConcurrentSupplierTest extends DDSpecification {
@Shared @Shared
def weakConcurrentSupplier = new WeakMapSuppliers.WeakConcurrent(CLEANER) def weakConcurrentSupplier = new WeakMapSuppliers.WeakConcurrent(CLEANER)
@Shared @Shared

View File

@ -1,10 +1,10 @@
import datadog.trace.instrumentation.jdbc.DBInfo import datadog.trace.instrumentation.jdbc.DBInfo
import datadog.trace.util.test.DDSpecification
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification
import static datadog.trace.instrumentation.jdbc.JDBCConnectionUrlParser.parse import static datadog.trace.instrumentation.jdbc.JDBCConnectionUrlParser.parse
class JDBCConnectionUrlParserTest extends Specification { class JDBCConnectionUrlParserTest extends DDSpecification {
@Shared @Shared
def stdProps = { def stdProps = {

View File

@ -20,7 +20,6 @@ dependencies {
testCompile group: 'com.twilio.sdk', name: 'twilio', version: '0.0.1' 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:apache-httpclient-4')
testCompile project(':dd-java-agent:instrumentation:java-concurrent') 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 testCompile group: 'nl.jqno.equalsverifier', name: 'equalsverifier', version: '2.5.2' // Last version to support Java7
latestDepTestCompile group: 'com.twilio.sdk', name: 'twilio', version: '+' latestDepTestCompile group: 'com.twilio.sdk', name: 'twilio', version: '+'

View File

@ -7,13 +7,13 @@ import datadog.opentracing.DDSpan;
import datadog.opentracing.DDTracer; import datadog.opentracing.DDTracer;
import datadog.opentracing.PendingTrace; import datadog.opentracing.PendingTrace;
import datadog.trace.agent.test.asserts.ListWriterAssert; 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.test.utils.GlobalTracerUtils;
import datadog.trace.agent.tooling.AgentInstaller; import datadog.trace.agent.tooling.AgentInstaller;
import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.Instrumenter;
import datadog.trace.api.GlobalTracer; import datadog.trace.api.GlobalTracer;
import datadog.trace.common.writer.ListWriter; import datadog.trace.common.writer.ListWriter;
import datadog.trace.common.writer.Writer; import datadog.trace.common.writer.Writer;
import datadog.trace.util.test.DDSpecification;
import groovy.lang.Closure; import groovy.lang.Closure;
import groovy.lang.DelegatesTo; import groovy.lang.DelegatesTo;
import groovy.transform.stc.ClosureParams; import groovy.transform.stc.ClosureParams;
@ -41,7 +41,6 @@ import org.junit.BeforeClass;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.spockframework.runtime.model.SpecMetadata; import org.spockframework.runtime.model.SpecMetadata;
import spock.lang.Specification;
/** /**
* A spock test runner which automatically applies instrumentation and exposes a global trace * A spock test runner which automatically applies instrumentation and exposes a global trace
@ -61,7 +60,7 @@ import spock.lang.Specification;
@RunWith(SpockRunner.class) @RunWith(SpockRunner.class)
@SpecMetadata(filename = "AgentTestRunner.java", line = 0) @SpecMetadata(filename = "AgentTestRunner.java", line = 0)
@Slf4j @Slf4j
public abstract class AgentTestRunner extends Specification { public abstract class AgentTestRunner extends DDSpecification {
private static final long TIMEOUT_MILLIS = 10 * 1000; private static final long TIMEOUT_MILLIS = 10 * 1000;
/** /**
* For test runs, agent's global tracer will report to this list writer. * 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(Logger.ROOT_LOGGER_NAME)).setLevel(Level.WARN);
((Logger) LoggerFactory.getLogger("datadog")).setLevel(Level.DEBUG); ((Logger) LoggerFactory.getLogger("datadog")).setLevel(Level.DEBUG);
ConfigUtils.makeConfigInstanceModifiable();
TEST_WRITER = TEST_WRITER =
new ListWriter() { new ListWriter() {
@Override @Override

View File

@ -2,44 +2,32 @@ package datadog.trace.agent.test.utils
import datadog.trace.api.Config import datadog.trace.api.Config
import lombok.SneakyThrows 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.lang.reflect.Modifier
import java.util.concurrent.Callable 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 { class ConfigUtils {
private static class ConfigInstance {
// Wrapped in a static class to lazy load. static final CONFIG_INSTANCE_FIELD = Config.getDeclaredField("INSTANCE")
static final FIELD = Config.getDeclaredField("INSTANCE")
static final RUNTIME_ID_FIELD = Config.getDeclaredField("runtimeId") static final RUNTIME_ID_FIELD = Config.getDeclaredField("runtimeId")
}
@SneakyThrows @SneakyThrows
synchronized static <T extends Object> Object withConfigOverride(final String name, final String value, final Callable<T> r) { 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() // Ensure the class was retransformed properly in DDSpecification.makeConfigInstanceModifiable()
assert Modifier.isPublic(ConfigInstance.FIELD.getModifiers()) assert Modifier.isPublic(CONFIG_INSTANCE_FIELD.getModifiers())
assert Modifier.isStatic(ConfigInstance.FIELD.getModifiers()) assert Modifier.isStatic(CONFIG_INSTANCE_FIELD.getModifiers())
assert Modifier.isVolatile(ConfigInstance.FIELD.getModifiers()) assert Modifier.isVolatile(CONFIG_INSTANCE_FIELD.getModifiers())
assert !Modifier.isFinal(ConfigInstance.FIELD.getModifiers()) assert !Modifier.isFinal(CONFIG_INSTANCE_FIELD.getModifiers())
def existingConfig = Config.get() def existingConfig = Config.get()
Properties properties = new Properties() Properties properties = new Properties()
properties.put(name, value) 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 assert Config.get() != existingConfig
try { try {
return r.call() return r.call()
} finally { } finally {
ConfigInstance.FIELD.set(null, existingConfig) CONFIG_INSTANCE_FIELD.set(null, existingConfig)
} }
} }
@ -50,7 +38,6 @@ class ConfigUtils {
* @return * @return
*/ */
static updateConfig(final Callable r) { static updateConfig(final Callable r) {
makeConfigInstanceModifiable()
r.call() r.call()
resetConfig() resetConfig()
} }
@ -59,71 +46,22 @@ class ConfigUtils {
* Reset the global configuration. Please note that Runtime ID is preserved to the pre-existing value. * Reset the global configuration. Please note that Runtime ID is preserved to the pre-existing value.
*/ */
static void resetConfig() { static void resetConfig() {
// Ensure the class was re-transformed properly in AgentTestRunner.makeConfigInstanceModifiable() // Ensure the class was re-transformed properly in DDSpecification.makeConfigInstanceModifiable()
assert Modifier.isPublic(ConfigInstance.FIELD.getModifiers()) assert Modifier.isPublic(CONFIG_INSTANCE_FIELD.getModifiers())
assert Modifier.isStatic(ConfigInstance.FIELD.getModifiers()) assert Modifier.isStatic(CONFIG_INSTANCE_FIELD.getModifiers())
assert Modifier.isVolatile(ConfigInstance.FIELD.getModifiers()) assert Modifier.isVolatile(CONFIG_INSTANCE_FIELD.getModifiers())
assert !Modifier.isFinal(ConfigInstance.FIELD.getModifiers()) assert !Modifier.isFinal(CONFIG_INSTANCE_FIELD.getModifiers())
assert Modifier.isPublic(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) assert Modifier.isPublic(RUNTIME_ID_FIELD.getModifiers())
assert !Modifier.isStatic(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) assert !Modifier.isStatic(RUNTIME_ID_FIELD.getModifiers())
assert Modifier.isVolatile(ConfigInstance.RUNTIME_ID_FIELD.getModifiers()) assert Modifier.isVolatile(RUNTIME_ID_FIELD.getModifiers())
assert !Modifier.isFinal(ConfigInstance.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() def newConfig = new Config()
ConfigInstance.FIELD.set(null, newConfig) CONFIG_INSTANCE_FIELD.set(null, newConfig)
if (previousConfig != null) { 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)
}
} }

View File

@ -24,6 +24,7 @@ dependencies {
compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.0.0.v20110901' compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.0.0.v20110901'
compile project(':dd-java-agent:agent-tooling') compile project(':dd-java-agent:agent-tooling')
compile project(':utils:test-utils')
annotationProcessor deps.autoservice annotationProcessor deps.autoservice
implementation deps.autoservice implementation deps.autoservice
@ -31,6 +32,7 @@ dependencies {
compile deps.groovy compile deps.groovy
testCompile project(':utils:gc-utils') testCompile project(':utils:gc-utils')
testCompile project(':utils:test-utils')
testCompile project(':dd-java-agent:instrumentation:trace-annotation') testCompile project(':dd-java-agent:instrumentation:trace-annotation')
testCompile group: 'cglib', name: 'cglib', version: '3.2.5' testCompile group: 'cglib', name: 'cglib', version: '3.2.5'

View File

@ -15,5 +15,5 @@ excludedClassesCoverage += [
description = 'dd-trace-api' description = 'dd-trace-api'
dependencies { dependencies {
compile deps.slf4j compile deps.slf4j
testCompile deps.junit testCompile project(':utils:test-utils')
} }

View File

@ -1,9 +1,9 @@
package datadog.trace.api package datadog.trace.api
import datadog.trace.util.test.DDSpecification
import org.junit.Rule import org.junit.Rule
import org.junit.contrib.java.lang.system.EnvironmentVariables import org.junit.contrib.java.lang.system.EnvironmentVariables
import org.junit.contrib.java.lang.system.RestoreSystemProperties 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_HOST
import static datadog.trace.api.Config.AGENT_PORT_LEGACY 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.TRACE_RESOLVER_ENABLED
import static datadog.trace.api.Config.WRITER_TYPE import static datadog.trace.api.Config.WRITER_TYPE
class ConfigTest extends Specification { class ConfigTest extends DDSpecification {
@Rule @Rule
public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties() public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties()
@Rule @Rule

View File

@ -44,10 +44,7 @@ dependencies {
testCompile project(":dd-java-agent:testing") testCompile project(":dd-java-agent:testing")
testCompile project(':utils:gc-utils') testCompile project(':utils:gc-utils')
testCompile group: 'org.assertj', name: 'assertj-core', version: '2.9.+' // testCompile group: 'cglib', name: 'cglib-nodep', version: '3.2.5'
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: 'com.github.stefanbirkner', name: 'system-rules', version: '1.17.1' testCompile group: 'com.github.stefanbirkner', name: 'system-rules', version: '1.17.1'
traceAgentTestCompile deps.testcontainers traceAgentTestCompile deps.testcontainers

View File

@ -1,10 +1,9 @@
package datadog.opentracing package datadog.opentracing
import spock.lang.Specification import datadog.trace.util.test.DDSpecification
import spock.lang.Unroll import spock.lang.Unroll
class ContainerInfoTest extends DDSpecification {
class ContainerInfoTest extends Specification {
@Unroll @Unroll
def "CGroupInfo is parsed from individual lines"() { def "CGroupInfo is parsed from individual lines"() {

View File

@ -2,24 +2,18 @@ package datadog.opentracing
import datadog.opentracing.propagation.ExtractedContext import datadog.opentracing.propagation.ExtractedContext
import datadog.opentracing.propagation.TagContext import datadog.opentracing.propagation.TagContext
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.Config import datadog.trace.api.Config
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.util.test.DDSpecification
import io.opentracing.Scope import io.opentracing.Scope
import io.opentracing.noop.NoopSpan import io.opentracing.noop.NoopSpan
import spock.lang.Specification
import static datadog.opentracing.DDSpanContext.ORIGIN_KEY import static datadog.opentracing.DDSpanContext.ORIGIN_KEY
import static java.util.concurrent.TimeUnit.MILLISECONDS import static java.util.concurrent.TimeUnit.MILLISECONDS
import static org.mockito.Mockito.mock
import static org.mockito.Mockito.when
class DDSpanBuilderTest extends Specification { class DDSpanBuilderTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def writer = new ListWriter() def writer = new ListWriter()
def config = Config.get() def config = Config.get()
@ -158,11 +152,12 @@ class DDSpanBuilderTest extends Specification {
final String spanId = "1" final String spanId = "1"
final long expectedParentId = spanId final long expectedParentId = spanId
final DDSpanContext mockedContext = mock(DDSpanContext) final DDSpanContext mockedContext = Mock()
when(mockedContext.getTraceId()).thenReturn(spanId) 1 * mockedContext.getTraceId() >> spanId
when(mockedContext.getSpanId()).thenReturn(spanId) 1 * mockedContext.getSpanId() >> spanId
when(mockedContext.getServiceName()).thenReturn("foo") _ * mockedContext.getServiceName() >> "foo"
when(mockedContext.getTrace()).thenReturn(new PendingTrace(tracer, "1", [:])) 1 * mockedContext.getBaggageItems() >> [:]
1 * mockedContext.getTrace() >> new PendingTrace(tracer, "1", [:])
final String expectedName = "fakeName" final String expectedName = "fakeName"

View File

@ -2,20 +2,16 @@ package datadog.opentracing
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import com.google.common.collect.Maps import com.google.common.collect.Maps
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.util.test.DDSpecification
import org.msgpack.core.MessagePack import org.msgpack.core.MessagePack
import org.msgpack.core.buffer.ArrayBufferInput import org.msgpack.core.buffer.ArrayBufferInput
import org.msgpack.jackson.dataformat.MessagePackFactory import org.msgpack.jackson.dataformat.MessagePackFactory
import org.msgpack.value.ValueType import org.msgpack.value.ValueType
import spock.lang.Specification
class DDSpanSerializationTest extends Specification { class DDSpanSerializationTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def "serialize spans with sampling #samplingPriority"() throws Exception { def "serialize spans with sampling #samplingPriority"() throws Exception {
setup: setup:

View File

@ -1,26 +1,21 @@
package datadog.opentracing package datadog.opentracing
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import datadog.opentracing.propagation.ExtractedContext import datadog.opentracing.propagation.ExtractedContext
import datadog.opentracing.propagation.TagContext import datadog.opentracing.propagation.TagContext
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.sampling.RateByServiceSampler import datadog.trace.common.sampling.RateByServiceSampler
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.util.test.DDSpecification
import io.opentracing.SpanContext import io.opentracing.SpanContext
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME
class DDSpanTest extends Specification { class DDSpanTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def writer = new ListWriter() def writer = new ListWriter()
def sampler = new RateByServiceSampler() def sampler = new RateByServiceSampler()

View File

@ -1,10 +1,10 @@
package datadog.opentracing package datadog.opentracing
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.Config import datadog.trace.api.Config
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.util.gc.GCUtils import datadog.trace.util.gc.GCUtils
import spock.lang.Specification import datadog.trace.util.test.DDSpecification
import spock.lang.Subject import spock.lang.Subject
import spock.lang.Timeout import spock.lang.Timeout
@ -14,10 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger
import static datadog.trace.api.Config.PARTIAL_FLUSH_MIN_SPANS import static datadog.trace.api.Config.PARTIAL_FLUSH_MIN_SPANS
class PendingTraceTest extends Specification { class PendingTraceTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def traceCount = new AtomicInteger() def traceCount = new AtomicInteger()
def writer = new ListWriter() { def writer = new ListWriter() {

View File

@ -1,13 +1,10 @@
package datadog.opentracing package datadog.opentracing
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
class SpanFactory { class SpanFactory {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
static DDSpan newSpanOf(long timestampMicro, String threadName = Thread.currentThread().name) { static DDSpan newSpanOf(long timestampMicro, String threadName = Thread.currentThread().name) {
def writer = new ListWriter() def writer = new ListWriter()

View File

@ -1,14 +1,11 @@
package datadog.opentracing 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 { import datadog.trace.common.writer.ListWriter
static { import datadog.trace.util.test.DDSpecification
ConfigUtils.makeConfigInstanceModifiable() import spock.lang.Shared
}
class TraceCorrelationTest extends DDSpecification {
static final WRITER = new ListWriter() static final WRITER = new ListWriter()

View File

@ -1,18 +1,15 @@
package datadog.opentracing package datadog.opentracing
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.GlobalTracer import datadog.trace.api.GlobalTracer
import datadog.trace.api.interceptor.MutableSpan import datadog.trace.api.interceptor.MutableSpan
import datadog.trace.api.interceptor.TraceInterceptor import datadog.trace.api.interceptor.TraceInterceptor
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import spock.lang.Specification import datadog.trace.util.test.DDSpecification
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
class TraceInterceptorTest extends Specification { class TraceInterceptorTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def writer = new ListWriter() def writer = new ListWriter()
def tracer = new DDTracer(writer) def tracer = new DDTracer(writer)

View File

@ -9,17 +9,16 @@ import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import datadog.trace.common.sampling.AllSampler import datadog.trace.common.sampling.AllSampler
import datadog.trace.common.writer.LoggingWriter import datadog.trace.common.writer.LoggingWriter
import datadog.trace.util.test.DDSpecification
import io.opentracing.tag.StringTag import io.opentracing.tag.StringTag
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import spock.lang.Specification
import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME
import static datadog.trace.api.DDTags.EVENT_SAMPLE_RATE import static datadog.trace.api.DDTags.EVENT_SAMPLE_RATE
import static java.util.Collections.emptyMap import static java.util.Collections.emptyMap
class SpanDecoratorTest extends Specification { class SpanDecoratorTest extends DDSpecification {
static { static {
ConfigUtils.makeConfigInstanceModifiable()
ConfigUtils.updateConfig { ConfigUtils.updateConfig {
System.setProperty("dd.$Config.SPLIT_BY_TAGS", "sn.tag1,sn.tag2") System.setProperty("dd.$Config.SPLIT_BY_TAGS", "sn.tag1,sn.tag2")
} }

View File

@ -3,17 +3,13 @@ package datadog.opentracing.decorators
import datadog.opentracing.DDSpanContext import datadog.opentracing.DDSpanContext
import datadog.opentracing.DDTracer import datadog.opentracing.DDTracer
import datadog.opentracing.PendingTrace import datadog.opentracing.PendingTrace
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.util.test.DDSpecification
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import spock.lang.Specification
import spock.lang.Subject import spock.lang.Subject
class URLAsResourceNameTest extends Specification { class URLAsResourceNameTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def writer = new ListWriter() def writer = new ListWriter()
def tracer = new DDTracer(writer) def tracer = new DDTracer(writer)

View File

@ -1,16 +1,16 @@
package datadog.opentracing.propagation package datadog.opentracing.propagation
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.util.test.DDSpecification
import io.opentracing.SpanContext import io.opentracing.SpanContext
import io.opentracing.propagation.TextMapExtractAdapter import io.opentracing.propagation.TextMapExtractAdapter
import spock.lang.Specification
import static datadog.opentracing.propagation.B3HttpCodec.SAMPLING_PRIORITY_KEY import static datadog.opentracing.propagation.B3HttpCodec.SAMPLING_PRIORITY_KEY
import static datadog.opentracing.propagation.B3HttpCodec.SPAN_ID_KEY import static datadog.opentracing.propagation.B3HttpCodec.SPAN_ID_KEY
import static datadog.opentracing.propagation.B3HttpCodec.TRACE_ID_KEY import static datadog.opentracing.propagation.B3HttpCodec.TRACE_ID_KEY
import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX 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"]) HttpCodec.Extractor extractor = new B3HttpCodec.Extractor(["SOME_HEADER": "some-tag"])

View File

@ -5,15 +5,15 @@ import datadog.opentracing.DDTracer
import datadog.opentracing.PendingTrace import datadog.opentracing.PendingTrace
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.util.test.DDSpecification
import io.opentracing.propagation.TextMapInjectAdapter import io.opentracing.propagation.TextMapInjectAdapter
import spock.lang.Specification
import static datadog.opentracing.propagation.B3HttpCodec.SAMPLING_PRIORITY_KEY import static datadog.opentracing.propagation.B3HttpCodec.SAMPLING_PRIORITY_KEY
import static datadog.opentracing.propagation.B3HttpCodec.SPAN_ID_KEY import static datadog.opentracing.propagation.B3HttpCodec.SPAN_ID_KEY
import static datadog.opentracing.propagation.B3HttpCodec.TRACE_ID_KEY import static datadog.opentracing.propagation.B3HttpCodec.TRACE_ID_KEY
import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX
class B3HttpInjectorTest extends Specification { class B3HttpInjectorTest extends DDSpecification {
HttpCodec.Injector injector = new B3HttpCodec.Injector() HttpCodec.Injector injector = new B3HttpCodec.Injector()

View File

@ -1,9 +1,9 @@
package datadog.opentracing.propagation package datadog.opentracing.propagation
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.util.test.DDSpecification
import io.opentracing.SpanContext import io.opentracing.SpanContext
import io.opentracing.propagation.TextMapExtractAdapter import io.opentracing.propagation.TextMapExtractAdapter
import spock.lang.Specification
import static datadog.opentracing.propagation.DatadogHttpCodec.ORIGIN_KEY import static datadog.opentracing.propagation.DatadogHttpCodec.ORIGIN_KEY
import static datadog.opentracing.propagation.DatadogHttpCodec.OT_BAGGAGE_PREFIX 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.DatadogHttpCodec.TRACE_ID_KEY
import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX 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"]) HttpCodec.Extractor extractor = new DatadogHttpCodec.Extractor(["SOME_HEADER": "some-tag"])

View File

@ -5,8 +5,8 @@ import datadog.opentracing.DDTracer
import datadog.opentracing.PendingTrace import datadog.opentracing.PendingTrace
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.util.test.DDSpecification
import io.opentracing.propagation.TextMapInjectAdapter import io.opentracing.propagation.TextMapInjectAdapter
import spock.lang.Specification
import static datadog.opentracing.propagation.DatadogHttpCodec.ORIGIN_KEY import static datadog.opentracing.propagation.DatadogHttpCodec.ORIGIN_KEY
import static datadog.opentracing.propagation.DatadogHttpCodec.OT_BAGGAGE_PREFIX 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.DatadogHttpCodec.TRACE_ID_KEY
import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX
class DatadogHttpInjectorTest extends Specification { class DatadogHttpInjectorTest extends DDSpecification {
HttpCodec.Injector injector = new DatadogHttpCodec.Injector() HttpCodec.Injector injector = new DatadogHttpCodec.Injector()

View File

@ -1,16 +1,16 @@
package datadog.opentracing.propagation package datadog.opentracing.propagation
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.util.test.DDSpecification
import io.opentracing.SpanContext import io.opentracing.SpanContext
import io.opentracing.propagation.TextMapExtractAdapter import io.opentracing.propagation.TextMapExtractAdapter
import spock.lang.Specification
import static datadog.opentracing.propagation.HaystackHttpCodec.OT_BAGGAGE_PREFIX import static datadog.opentracing.propagation.HaystackHttpCodec.OT_BAGGAGE_PREFIX
import static datadog.opentracing.propagation.HaystackHttpCodec.SPAN_ID_KEY import static datadog.opentracing.propagation.HaystackHttpCodec.SPAN_ID_KEY
import static datadog.opentracing.propagation.HaystackHttpCodec.TRACE_ID_KEY import static datadog.opentracing.propagation.HaystackHttpCodec.TRACE_ID_KEY
import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX 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"]) HttpCodec.Extractor extractor = new HaystackHttpCodec.Extractor(["SOME_HEADER": "some-tag"])

View File

@ -5,15 +5,15 @@ import datadog.opentracing.DDTracer
import datadog.opentracing.PendingTrace import datadog.opentracing.PendingTrace
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.util.test.DDSpecification
import io.opentracing.propagation.TextMapInjectAdapter import io.opentracing.propagation.TextMapInjectAdapter
import spock.lang.Specification
import static datadog.opentracing.propagation.HaystackHttpCodec.OT_BAGGAGE_PREFIX import static datadog.opentracing.propagation.HaystackHttpCodec.OT_BAGGAGE_PREFIX
import static datadog.opentracing.propagation.HaystackHttpCodec.SPAN_ID_KEY import static datadog.opentracing.propagation.HaystackHttpCodec.SPAN_ID_KEY
import static datadog.opentracing.propagation.HaystackHttpCodec.TRACE_ID_KEY import static datadog.opentracing.propagation.HaystackHttpCodec.TRACE_ID_KEY
import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX
class HaystackHttpInjectorTest extends Specification { class HaystackHttpInjectorTest extends DDSpecification {
HttpCodec.Injector injector = new HaystackHttpCodec.Injector() HttpCodec.Injector injector = new HaystackHttpCodec.Injector()
@ -55,7 +55,6 @@ class HaystackHttpInjectorTest extends Specification {
1 * carrier.put(OT_BAGGAGE_PREFIX + "k2", "v2") 1 * carrier.put(OT_BAGGAGE_PREFIX + "k2", "v2")
where: where:
traceId | spanId | samplingPriority | origin traceId | spanId | samplingPriority | origin
"1" | "2" | PrioritySampling.SAMPLER_KEEP | null "1" | "2" | PrioritySampling.SAMPLER_KEEP | null

View File

@ -1,20 +1,17 @@
package datadog.opentracing.propagation package datadog.opentracing.propagation
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.Config import datadog.trace.api.Config
import datadog.trace.util.test.DDSpecification
import io.opentracing.SpanContext import io.opentracing.SpanContext
import io.opentracing.propagation.TextMapExtractAdapter import io.opentracing.propagation.TextMapExtractAdapter
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification
import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX import static datadog.opentracing.propagation.HttpCodec.UINT64_MAX
import static datadog.trace.api.Config.PropagationStyle.B3 import static datadog.trace.api.Config.PropagationStyle.B3
import static datadog.trace.api.Config.PropagationStyle.DATADOG import static datadog.trace.api.Config.PropagationStyle.DATADOG
class HttpExtractorTest extends Specification { class HttpExtractorTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
@Shared @Shared
String outOfRangeTraceId = UINT64_MAX.add(BigInteger.ONE) String outOfRangeTraceId = UINT64_MAX.add(BigInteger.ONE)

View File

@ -3,20 +3,16 @@ package datadog.opentracing.propagation
import datadog.opentracing.DDSpanContext import datadog.opentracing.DDSpanContext
import datadog.opentracing.DDTracer import datadog.opentracing.DDTracer
import datadog.opentracing.PendingTrace import datadog.opentracing.PendingTrace
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.Config import datadog.trace.api.Config
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.util.test.DDSpecification
import io.opentracing.propagation.TextMapInjectAdapter import io.opentracing.propagation.TextMapInjectAdapter
import spock.lang.Specification
import static datadog.trace.api.Config.PropagationStyle.B3 import static datadog.trace.api.Config.PropagationStyle.B3
import static datadog.trace.api.Config.PropagationStyle.DATADOG import static datadog.trace.api.Config.PropagationStyle.DATADOG
class HttpInjectorTest extends Specification { class HttpInjectorTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def "inject http headers"() { def "inject http headers"() {
setup: setup:

View File

@ -1,15 +1,11 @@
package datadog.opentracing.resolver package datadog.opentracing.resolver
import datadog.opentracing.DDTracer import datadog.opentracing.DDTracer
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.Config import datadog.trace.api.Config
import datadog.trace.util.test.DDSpecification
import io.opentracing.contrib.tracerresolver.TracerResolver import io.opentracing.contrib.tracerresolver.TracerResolver
import spock.lang.Specification
class DDTracerResolverTest extends Specification { class DDTracerResolverTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def resolver = new DDTracerResolver() def resolver = new DDTracerResolver()

View File

@ -3,14 +3,13 @@ package datadog.opentracing.scopemanager
import datadog.opentracing.DDSpan import datadog.opentracing.DDSpan
import datadog.opentracing.DDSpanContext import datadog.opentracing.DDSpanContext
import datadog.opentracing.DDTracer import datadog.opentracing.DDTracer
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.context.ScopeListener import datadog.trace.context.ScopeListener
import datadog.trace.util.gc.GCUtils import datadog.trace.util.gc.GCUtils
import datadog.trace.util.test.DDSpecification
import io.opentracing.Scope import io.opentracing.Scope
import io.opentracing.Span import io.opentracing.Span
import io.opentracing.noop.NoopSpan import io.opentracing.noop.NoopSpan
import spock.lang.Specification
import spock.lang.Subject import spock.lang.Subject
import spock.lang.Timeout import spock.lang.Timeout
@ -22,10 +21,7 @@ import java.util.concurrent.atomic.AtomicReference
import static java.util.concurrent.TimeUnit.SECONDS import static java.util.concurrent.TimeUnit.SECONDS
class ScopeManagerTest extends Specification { class ScopeManagerTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
def latch def latch
def writer def writer
def tracer def tracer

View File

@ -2,9 +2,9 @@ package datadog.trace
import datadog.opentracing.SpanFactory import datadog.opentracing.SpanFactory
import datadog.trace.api.DDTags 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"() { def "null values for tags delete existing tags"() {
setup: setup:

View File

@ -2,17 +2,16 @@ package datadog.trace
import datadog.opentracing.DDTracer import datadog.opentracing.DDTracer
import datadog.opentracing.propagation.HttpCodec import datadog.opentracing.propagation.HttpCodec
import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.Config import datadog.trace.api.Config
import datadog.trace.common.sampling.AllSampler import datadog.trace.common.sampling.AllSampler
import datadog.trace.common.sampling.RateByServiceSampler import datadog.trace.common.sampling.RateByServiceSampler
import datadog.trace.common.writer.DDAgentWriter import datadog.trace.common.writer.DDAgentWriter
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.common.writer.LoggingWriter import datadog.trace.common.writer.LoggingWriter
import datadog.trace.util.test.DDSpecification
import org.junit.Rule import org.junit.Rule
import org.junit.contrib.java.lang.system.EnvironmentVariables import org.junit.contrib.java.lang.system.EnvironmentVariables
import org.junit.contrib.java.lang.system.RestoreSystemProperties 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.DEFAULT_SERVICE_NAME
import static datadog.trace.api.Config.HEADER_TAGS 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.SPAN_TAGS
import static datadog.trace.api.Config.WRITER_TYPE import static datadog.trace.api.Config.WRITER_TYPE
class DDTracerTest extends Specification { class DDTracerTest extends DDSpecification {
static {
ConfigUtils.makeConfigInstanceModifiable()
}
@Rule @Rule
public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties() public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties()

View File

@ -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<String, Object> 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)
}
}

View File

@ -4,11 +4,11 @@ import com.fasterxml.jackson.databind.ObjectMapper
import datadog.opentracing.DDSpan import datadog.opentracing.DDSpan
import datadog.opentracing.SpanFactory import datadog.opentracing.SpanFactory
import datadog.trace.common.sampling.RateByServiceSampler 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 import static datadog.trace.common.sampling.RateByServiceSampler.DEFAULT_KEY
class RateByServiceSamplerTest extends Specification { class RateByServiceSamplerTest extends DDSpecification {
def "invalid rate -> 1"() { def "invalid rate -> 1"() {
setup: setup:

View File

@ -7,7 +7,7 @@ import datadog.opentracing.PendingTrace
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.DDAgentWriter import datadog.trace.common.writer.DDAgentWriter
import datadog.trace.common.writer.DDApi import datadog.trace.common.writer.DDApi
import spock.lang.Specification import datadog.trace.util.test.DDSpecification
import spock.lang.Timeout import spock.lang.Timeout
import java.util.concurrent.TimeUnit 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 import static datadog.trace.common.writer.DDAgentWriter.DISRUPTOR_BUFFER_SIZE
@Timeout(20) @Timeout(20)
class DDAgentWriterTest extends Specification { class DDAgentWriterTest extends DDSpecification {
def api = Mock(DDApi) def api = Mock(DDApi)

View File

@ -5,14 +5,14 @@ import com.fasterxml.jackson.databind.JsonNode
import datadog.opentracing.SpanFactory import datadog.opentracing.SpanFactory
import datadog.trace.common.writer.DDApi import datadog.trace.common.writer.DDApi
import datadog.trace.common.writer.DDApi.ResponseListener 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.AtomicLong
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
class DDApiTest extends Specification { class DDApiTest extends DDSpecification {
static mapper = DDApi.OBJECT_MAPPER static mapper = DDApi.OBJECT_MAPPER
def "sending an empty list of traces returns no errors"() { def "sending an empty list of traces returns no errors"() {

View File

@ -1,16 +1,15 @@
package datadog.trace.api.writer package datadog.trace.api.writer
import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import datadog.trace.util.test.DDSpecification
import org.msgpack.core.MessagePack import org.msgpack.core.MessagePack
import org.msgpack.jackson.dataformat.MessagePackFactory import org.msgpack.jackson.dataformat.MessagePackFactory
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification
import static java.util.Collections.singletonMap import static java.util.Collections.singletonMap
class SerializationTest extends Specification { class SerializationTest extends DDSpecification {
@Shared @Shared
def jsonMapper = new ObjectMapper() def jsonMapper = new ObjectMapper()
@Shared @Shared

View File

@ -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<String, Object> 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();
}
}

View File

@ -6,11 +6,11 @@ import datadog.opentracing.PendingTrace
import datadog.trace.api.sampling.PrioritySampling import datadog.trace.api.sampling.PrioritySampling
import datadog.trace.common.writer.DDApi import datadog.trace.common.writer.DDApi
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
import datadog.trace.util.test.DDSpecification
import org.testcontainers.containers.GenericContainer import org.testcontainers.containers.GenericContainer
import org.testcontainers.containers.startupcheck.MinimumDurationRunningStartupCheckStrategy import org.testcontainers.containers.startupcheck.MinimumDurationRunningStartupCheckStrategy
import spock.lang.Requires import spock.lang.Requires
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification
import java.time.Duration import java.time.Duration
import java.util.concurrent.TimeUnit 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 // 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 // It is fine to run on CI because CI provides rabbitmq externally, not through testcontainers
@Requires({ "true" == System.getenv("CI") || jvm.java8Compatible }) @Requires({ "true" == System.getenv("CI") || jvm.java8Compatible })
static class DDApiIntegrationV4Test extends Specification { static class DDApiIntegrationV4Test extends DDSpecification {
static final WRITER = new ListWriter() static final WRITER = new ListWriter()
static final TRACER = new DDTracer(WRITER) static final TRACER = new DDTracer(WRITER)
static final CONTEXT = new DDSpanContext( static final CONTEXT = new DDSpanContext(

View File

@ -49,9 +49,14 @@ ext {
], ],
// Testing // Testing
spock : dependencies.create("org.spockframework:spock-core:${versions.spock}", {
spock : [
dependencies.create("org.spockframework:spock-core:${versions.spock}", {
exclude group: 'org.codehaus.groovy', module: 'groovy-all' 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}", groovy : "org.codehaus.groovy:groovy-all:${versions.groovy}",
junit : "junit:junit:${versions.junit}", junit : "junit:junit:${versions.junit}",
testcontainers : "org.testcontainers:testcontainers:1.7.3", testcontainers : "org.testcontainers:testcontainers:1.7.3",

View File

@ -13,6 +13,7 @@ include ':dd-java-agent:agent-jmxfetch'
// misc // misc
include ':dd-java-agent:testing' include ':dd-java-agent:testing'
include ':utils:gc-utils' include ':utils:gc-utils'
include ':utils:test-utils'
// smoke tests // smoke tests
include ':dd-smoke-tests:cli' include ':dd-smoke-tests:cli'

View File

@ -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)
}
}

View File

@ -0,0 +1,9 @@
apply from: "${rootDir}/gradle/java.gradle"
dependencies {
compile deps.groovy
compile deps.spock
compile deps.bytebuddy
compile deps.bytebuddyagent
}