Fix tests, increase code coverage, codenarc
MODIFY
dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy
dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy
@@ -13,6 +13,9 @@ import static datadog.trace.api.Config.DB_CLIENT_HOST_SPLIT_BY_INSTANCE
import static datadog.trace.api.Config.DEFAULT_JMX_FETCH_STATSD_PORT
import static datadog.trace.api.Config.GLOBAL_TAGS
import static datadog.trace.api.Config.HEADER_TAGS
+import static datadog.trace.api.Config.HEALTH_METRICS_ENABLED
+import static datadog.trace.api.Config.HEALTH_METRICS_STATSD_HOST
+import static datadog.trace.api.Config.HEALTH_METRICS_STATSD_PORT
import static datadog.trace.api.Config.HTTP_CLIENT_ERROR_STATUSES
import static datadog.trace.api.Config.HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN
import static datadog.trace.api.Config.HTTP_SERVER_ERROR_STATUSES
@@ -39,10 +42,11 @@ import static datadog.trace.api.Config.TRACE_AGENT_PORT
import static datadog.trace.api.Config.TRACE_ENABLED
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_SAMPLING_DEFAULT_RATE
+import static datadog.trace.api.Config.TRACE_SAMPLING_OPERATION_RULES
+import static datadog.trace.api.Config.TRACE_SAMPLING_RATE_LIMIT
+import static datadog.trace.api.Config.TRACE_SAMPLING_SERVICE_RULES
import static datadog.trace.api.Config.WRITER_TYPE
-import static datadog.trace.api.Config.HEALTH_METRICS_ENABLED
-import static datadog.trace.api.Config.HEALTH_METRICS_STATSD_HOST
-import static datadog.trace.api.Config.HEALTH_METRICS_STATSD_PORT
class ConfigTest extends DDSpecification {
@Rule
@@ -145,6 +149,10 @@ class ConfigTest extends DDSpecification {
prop.setProperty(HEALTH_METRICS_ENABLED, "true")
prop.setProperty(HEALTH_METRICS_STATSD_HOST, "metrics statsd host")
prop.setProperty(HEALTH_METRICS_STATSD_PORT, "654")
+ prop.setProperty(TRACE_SAMPLING_SERVICE_RULES, "a:1")
+ prop.setProperty(TRACE_SAMPLING_OPERATION_RULES, "b:1")
+ prop.setProperty(TRACE_SAMPLING_DEFAULT_RATE, ".5")
+ prop.setProperty(TRACE_SAMPLING_RATE_LIMIT, "200")
when:
Config config = Config.get(prop)
@@ -181,6 +189,10 @@ class ConfigTest extends DDSpecification {
config.healthMetricsEnabled == true
config.healthMetricsStatsdHost == "metrics statsd host"
config.healthMetricsStatsdPort == 654
+ config.traceSamplingServiceRules == [a: "1"]
+ config.traceSamplingOperationRules == [b: "1"]
+ config.traceSamplingDefaultRate == 0.5
+ config.traceSamplingRateLimit == 200
}
def "specify overrides via system properties"() {
@@ -218,6 +230,10 @@ class ConfigTest extends DDSpecification {
System.setProperty(PREFIX + HEALTH_METRICS_ENABLED, "true")
System.setProperty(PREFIX + HEALTH_METRICS_STATSD_HOST, "metrics statsd host")
System.setProperty(PREFIX + HEALTH_METRICS_STATSD_PORT, "654")
+ System.setProperty(PREFIX + TRACE_SAMPLING_SERVICE_RULES, "a:1")
+ System.setProperty(PREFIX + TRACE_SAMPLING_OPERATION_RULES, "b:1")
+ System.setProperty(PREFIX + TRACE_SAMPLING_DEFAULT_RATE, ".5")
+ System.setProperty(PREFIX + TRACE_SAMPLING_RATE_LIMIT, "200")
when:
Config config = new Config()
@@ -254,6 +270,10 @@ class ConfigTest extends DDSpecification {
config.healthMetricsEnabled == true
config.healthMetricsStatsdHost == "metrics statsd host"
config.healthMetricsStatsdPort == 654
+ config.traceSamplingServiceRules == [a: "1"]
+ config.traceSamplingOperationRules == [b: "1"]
+ config.traceSamplingDefaultRate == 0.5
+ config.traceSamplingRateLimit == 200
}
def "specify overrides via env vars"() {
@@ -610,6 +630,35 @@ class ConfigTest extends DDSpecification {
defaultValue = 10.0
}
+ def "test getDoubleSettingFromEnvironment(#name)"() {
+ setup:
+ environmentVariables.set("DD_ENV_ZERO_TEST", "0.0")
+ environmentVariables.set("DD_ENV_FLOAT_TEST", "1.0")
+ environmentVariables.set("DD_FLOAT_TEST", "0.2")
+
+ System.setProperty("dd.prop.zero.test", "0")
+ System.setProperty("dd.prop.float.test", "0.3")
+ System.setProperty("dd.float.test", "0.4")
+ System.setProperty("dd.garbage.test", "garbage")
+ System.setProperty("dd.negative.test", "-1")
+
+ expect:
+ Config.getDoubleSettingFromEnvironment(name, defaultValue) == (double) expected
+
+ where:
+ name | expected
+ "env.zero.test" | 0.0
+ "prop.zero.test" | 0
+ "env.float.test" | 1.0
+ "prop.float.test" | 0.3
+ "float.test" | 0.4
+ "negative.test" | -1.0
+ "garbage.test" | 10.0
+ "default.test" | 10.0
+
+ defaultValue = 10.0
+ }
+
def "verify mapping configs on tracer"() {
setup:
System.setProperty(PREFIX + SERVICE_MAPPING, mapString)

MODIFY
dd-trace-ot/src/main/java/datadog/trace/common/sampling/RuleBasedSampler.java
dd-trace-ot/src/main/java/datadog/trace/common/sampling/RuleBasedSampler.java
@@ -67,7 +67,8 @@ public class RuleBasedSampler implements Sampler, PrioritySampler {
}
if (defaultRate != null) {
- final SamplingRule samplingRule = new AlwaysMatchesSamplingRule(new KnuthSampler(defaultRate));
+ final SamplingRule samplingRule =
+ new AlwaysMatchesSamplingRule(new KnuthSampler(defaultRate));
samplingRules.add(samplingRule);
}

MODIFY
dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy
dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy
@@ -29,9 +29,9 @@ class DDSpanSerializationTest extends DDSpecification {
expected.put("duration", 33000)
expected.put("resource", "operation")
final Map<String, Number> metrics = new HashMap<>()
- if (samplingPriority != PrioritySampling.UNSET) {
- metrics.put("_sampling_priority_v1", Integer.valueOf(samplingPriority))
- metrics.put("_sample_rate", Double.valueOf(1.0))
+ metrics.put("_sampling_priority_v1", 1)
+ if (samplingPriority == PrioritySampling.UNSET) { // RateByServiceSampler sets priority
+ metrics.put("_dd.agent_psr", 1.0d)
}
expected.put("metrics", metrics)
expected.put("start", 100000)
@@ -62,9 +62,7 @@ class DDSpanSerializationTest extends DDSpecification {
baggage.put(DDTags.THREAD_ID, String.valueOf(Thread.currentThread().getId()))
DDSpan span = new DDSpan(100L, context)
- if (samplingPriority != PrioritySampling.UNSET) {
- span.context().setMetric("_sample_rate", Double.valueOf(1.0))
- }
+
span.finish(133L)
ObjectMapper serializer = new ObjectMapper()

MODIFY
dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy
dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy
package datadog.opentracing
-import com.fasterxml.jackson.databind.ObjectMapper
+
import datadog.opentracing.propagation.ExtractedContext
import datadog.opentracing.propagation.TagContext
-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 java.util.concurrent.TimeUnit
@@ -21,14 +19,6 @@ class DDSpanTest extends DDSpecification {
def sampler = new RateByServiceSampler()
def tracer = new DDTracer(DEFAULT_SERVICE_NAME, writer, sampler, [:])
- @Shared
- def defaultSamplingPriority = PrioritySampling.SAMPLER_KEEP
-
- def setup() {
- sampler.onResponse("test", new ObjectMapper()
- .readTree('{"rate_by_service":{"service:,env:":1.0,"service:spock,env:":0.0}}'))
- }
-
def "getters and setters"() {
setup:
final DDSpanContext context =
@@ -257,70 +247,4 @@ class DDSpanTest extends DDSpecification {
null | true
new ExtractedContext(123G, 456G, 1, "789", [:], [:]) | false
}
-
- def "sampling priority set on init"() {
- setup:
- def span = tracer.buildSpan("test").start()
-
- expect:
- span.getSamplingPriority() == PrioritySampling.SAMPLER_KEEP
-
- when:
- span.setTag(DDTags.SERVICE_NAME, "spock")
-
- then:
- // FIXME: priority currently only applies if service name set before span started.
- span.getSamplingPriority() == PrioritySampling.SAMPLER_KEEP
-// span.getSamplingPriority() == PrioritySampling.SAMPLER_DROP
-
- when:
- span = tracer.buildSpan("test").withTag(DDTags.SERVICE_NAME, "spock").start()
-
- then:
- span.getSamplingPriority() == PrioritySampling.SAMPLER_DROP
- }
-
- def "setting forced tracing via tag"() {
- setup:
- def span = tracer.buildSpan("root").start()
- if (tagName) {
- span.setTag(tagName, tagValue)
- }
-
- expect:
- span.getSamplingPriority() == expectedPriority
-
- cleanup:
- span.finish()
-
- where:
- tagName | tagValue | expectedPriority
- 'manual.drop' | true | PrioritySampling.USER_DROP
- 'manual.keep' | true | PrioritySampling.USER_KEEP
- }
-
- def "not setting forced tracing via tag or setting it wrong value not causing exception"() {
-
- setup:
- def span = tracer.buildSpan("root").start()
- if (tagName) {
- span.setTag(tagName, tagValue)
- }
-
- expect:
- span.getSamplingPriority() == defaultSamplingPriority
-
- cleanup:
- span.finish()
-
- where:
- tagName | tagValue
- // When no tag is set default to
- null | null
- // Setting to not known value
- 'manual.drop' | false
- 'manual.keep' | false
- 'manual.drop' | 1
- 'manual.keep' | 1
- }
}

MODIFY
dd-trace-ot/src/test/groovy/datadog/trace/DDTracerTest.groovy
dd-trace-ot/src/test/groovy/datadog/trace/DDTracerTest.groovy
package datadog.trace
+
import datadog.opentracing.DDSpan
import datadog.opentracing.DDTracer
import datadog.opentracing.propagation.DatadogHttpCodec
@@ -220,7 +221,7 @@ class DDTracerTest extends DDSpecification {
when:
def root = tracer.buildSpan("operation").start()
- def child = tracer.buildSpan('my_child').asChildOf(root).start();
+ def child = tracer.buildSpan('my_child').asChildOf(root).start()
root.finish()
then:
@@ -243,7 +244,7 @@ class DDTracerTest extends DDSpecification {
when:
def root = tracer.buildSpan("operation").start()
- def child = tracer.buildSpan('my_child').asChildOf(root).start();
+ def child = tracer.buildSpan('my_child').asChildOf(root).start()
tracer.inject(child.context(), TEXT_MAP_INJECT, injector)
then:
@@ -264,7 +265,7 @@ class DDTracerTest extends DDSpecification {
when:
def root = tracer.buildSpan("operation").start()
- def child = tracer.buildSpan('my_child').asChildOf(root).start();
+ def child = tracer.buildSpan('my_child').asChildOf(root).start()
tracer.inject(child.context(), TEXT_MAP_INJECT, injector)
then:
@@ -274,7 +275,7 @@ class DDTracerTest extends DDSpecification {
when:
sampler.nextSamplingPriority = PrioritySampling.SAMPLER_DROP
- def child2 = tracer.buildSpan('my_child2').asChildOf(root).start();
+ def child2 = tracer.buildSpan('my_child2').asChildOf(root).start()
tracer.inject(child2.context(), TEXT_MAP_INJECT, injector)
then:
@@ -297,7 +298,7 @@ class DDTracerTest extends DDSpecification {
when:
def root = tracer.buildSpan("operation").start()
- def child = tracer.buildSpan('my_child').asChildOf(root).start();
+ def child = tracer.buildSpan('my_child').asChildOf(root).start()
child.setSamplingPriority(PrioritySampling.USER_DROP)
tracer.inject(child.context(), TEXT_MAP_INJECT, injector)

MODIFY
dd-trace-ot/src/test/groovy/datadog/trace/api/sampling/RateByServiceSamplerTest.groovy
dd-trace-ot/src/test/groovy/datadog/trace/api/sampling/RateByServiceSamplerTest.groovy
@@ -2,8 +2,11 @@ package datadog.trace.api.sampling
import com.fasterxml.jackson.databind.ObjectMapper
import datadog.opentracing.DDSpan
+import datadog.opentracing.DDTracer
import datadog.opentracing.SpanFactory
+import datadog.trace.api.DDTags
import datadog.trace.common.sampling.RateByServiceSampler
+import datadog.trace.common.writer.LoggingWriter
import datadog.trace.util.test.DDSpecification
import static datadog.trace.common.sampling.RateByServiceSampler.DEFAULT_KEY
@@ -68,4 +71,77 @@ class RateByServiceSamplerTest extends DDSpecification {
// RateByServiceSamler must not set the sample rate
span.getMetrics().get("_sample_rate") == null
}
+
+ def "sampling priority set when service later"() {
+ def sampler = new RateByServiceSampler()
+ def tracer = new DDTracer("serviceName", new LoggingWriter(), sampler)
+
+ sampler.onResponse("test", new ObjectMapper()
+ .readTree('{"rate_by_service":{"service:,env:":1.0,"service:spock,env:":0.0}}'))
+
+ when:
+ def span = tracer.buildSpan("test").start()
+
+ then:
+ span.getSamplingPriority() == null
+
+ when:
+ span.setTag(DDTags.SERVICE_NAME, "spock")
+
+ then:
+ span.finish()
+ span.getSamplingPriority() == PrioritySampling.SAMPLER_DROP
+
+ when:
+ span = tracer.buildSpan("test").withTag(DDTags.SERVICE_NAME, "spock").start()
+ span.finish()
+
+ then:
+ span.getSamplingPriority() == PrioritySampling.SAMPLER_DROP
+ }
+
+ def "setting forced tracing via tag"() {
+ when:
+ def sampler = new RateByServiceSampler()
+ def tracer = new DDTracer("serviceName", new LoggingWriter(), sampler)
+ def span = tracer.buildSpan("root").start()
+ if (tagName) {
+ span.setTag(tagName, tagValue)
+ }
+ span.finish()
+
+ then:
+ span.getSamplingPriority() == expectedPriority
+
+ where:
+ tagName | tagValue | expectedPriority
+ 'manual.drop' | true | PrioritySampling.USER_DROP
+ 'manual.keep' | true | PrioritySampling.USER_KEEP
+ }
+
+ def "not setting forced tracing via tag or setting it wrong value not causing exception"() {
+ setup:
+ def sampler = new RateByServiceSampler()
+ def tracer = new DDTracer("serviceName", new LoggingWriter(), sampler)
+ def span = tracer.buildSpan("root").start()
+ if (tagName) {
+ span.setTag(tagName, tagValue)
+ }
+
+ expect:
+ span.getSamplingPriority() == null
+
+ cleanup:
+ span.finish()
+
+ where:
+ tagName | tagValue
+ // When no tag is set default to
+ null | null
+ // Setting to not known value
+ 'manual.drop' | false
+ 'manual.keep' | false
+ 'manual.drop' | 1
+ 'manual.keep' | 1
+ }
}

Fix tests, increase code coverage, codenarc