From e79d6f6c2301991626413bc4e7703a3e79526f55 Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Mon, 29 Jun 2026 10:46:46 -0400 Subject: [PATCH 1/3] =?UTF-8?q?Exclude=20CoreSpan=20from=20coverage=20?= =?UTF-8?q?=E2=80=94=20all=20default=20methods=20are=20overridden=20by=20D?= =?UTF-8?q?DSpan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The four defaults (getServiceNameSource, isKind, unsafeGetTag x2) are unreachable in practice; DDSpan overrides each with a different implementation. Co-Authored-By: Claude Sonnet 4.6 --- dd-trace-core/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dd-trace-core/build.gradle b/dd-trace-core/build.gradle index ee8ef78ee16..35e01b1d546 100644 --- a/dd-trace-core/build.gradle +++ b/dd-trace-core/build.gradle @@ -36,7 +36,8 @@ excludedClassesCoverage += [ 'datadog.trace.core.DDSpan.1', 'datadog.trace.core.tagprocessor.QueryObfuscator.1', 'datadog.trace.common.writer.TraceProcessingWorker.NonDaemonTraceSerializingHandler', - // Interface with an empty defender method + // Interfaces with default methods that are overridden by all concrete implementations + 'datadog.trace.core.CoreSpan', 'datadog.trace.core.propagation.HttpCodec.Extractor', 'datadog.trace.llmobs.writer.ddintake.LLMObsSpanMapper', 'datadog.trace.llmobs.writer.ddintake.LLMObsSpanMapper.PayloadV1', From d1117c7b82cb1b435361bac5576e416b349be727 Mon Sep 17 00:00:00 2001 From: Douglas Q Hawkins Date: Mon, 29 Jun 2026 10:51:56 -0400 Subject: [PATCH 2/3] Remove default methods from CoreSpan; implement them in test doubles The four defaults (getServiceNameSource, isKind, unsafeGetTag x2) were unreachable in practice because DDSpan overrides each one. Making them abstract forces test implementations to be explicit, and coverage is satisfied by the concrete implementations rather than unreachable defaults. Co-Authored-By: Claude Sonnet 4.6 --- dd-trace-core/build.gradle | 3 +-- .../java/datadog/trace/core/CoreSpan.java | 18 ++++----------- .../trace/common/metrics/SimpleSpan.groovy | 10 ++++++++ .../trace/common/writer/TraceGenerator.java | 23 +++++++++++++++++++ 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/dd-trace-core/build.gradle b/dd-trace-core/build.gradle index 35e01b1d546..ee8ef78ee16 100644 --- a/dd-trace-core/build.gradle +++ b/dd-trace-core/build.gradle @@ -36,8 +36,7 @@ excludedClassesCoverage += [ 'datadog.trace.core.DDSpan.1', 'datadog.trace.core.tagprocessor.QueryObfuscator.1', 'datadog.trace.common.writer.TraceProcessingWorker.NonDaemonTraceSerializingHandler', - // Interfaces with default methods that are overridden by all concrete implementations - 'datadog.trace.core.CoreSpan', + // Interface with an empty defender method 'datadog.trace.core.propagation.HttpCodec.Extractor', 'datadog.trace.llmobs.writer.ddintake.LLMObsSpanMapper', 'datadog.trace.llmobs.writer.ddintake.LLMObsSpanMapper.PayloadV1', diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreSpan.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreSpan.java index a6ced35967c..4d0d8c87f99 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreSpan.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreSpan.java @@ -1,7 +1,6 @@ package datadog.trace.core; import datadog.trace.api.DDTraceId; -import datadog.trace.bootstrap.instrumentation.api.Tags; import java.util.Map; public interface CoreSpan> { @@ -10,9 +9,7 @@ public interface CoreSpan> { String getServiceName(); - default CharSequence getServiceNameSource() { - return null; - } + CharSequence getServiceNameSource(); CharSequence getOperationName(); @@ -62,13 +59,9 @@ default CharSequence getServiceNameSource() { U getTag(CharSequence name); - default U unsafeGetTag(CharSequence name, U defaultValue) { - return getTag(name, defaultValue); - } + U unsafeGetTag(CharSequence name, U defaultValue); - default U unsafeGetTag(CharSequence name) { - return getTag(name); - } + U unsafeGetTag(CharSequence name); boolean hasSamplingPriority(); @@ -81,10 +74,7 @@ default U unsafeGetTag(CharSequence name) { boolean isForceKeep(); - default boolean isKind(SpanKindFilter filter) { - Object kind = unsafeGetTag(Tags.SPAN_KIND); - return filter.matches(kind == null ? null : kind.toString()); - } + boolean isKind(SpanKindFilter filter); CharSequence getType(); diff --git a/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SimpleSpan.groovy b/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SimpleSpan.groovy index 2fd8554d499..f23045856ef 100644 --- a/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SimpleSpan.groovy +++ b/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SimpleSpan.groovy @@ -199,6 +199,16 @@ class SimpleSpan implements CoreSpan { return getTag(name, null) } + @Override + U unsafeGetTag(CharSequence name, U defaultValue) { + return getTag(name, defaultValue) + } + + @Override + U unsafeGetTag(CharSequence name) { + return getTag(name) + } + @Override boolean hasSamplingPriority() { return false diff --git a/dd-trace-core/src/test/java/datadog/trace/common/writer/TraceGenerator.java b/dd-trace-core/src/test/java/datadog/trace/common/writer/TraceGenerator.java index 618b2ef77ae..00610ddbb61 100644 --- a/dd-trace-core/src/test/java/datadog/trace/common/writer/TraceGenerator.java +++ b/dd-trace-core/src/test/java/datadog/trace/common/writer/TraceGenerator.java @@ -11,10 +11,12 @@ import datadog.trace.api.TagMap; import datadog.trace.api.sampling.PrioritySampling; import datadog.trace.bootstrap.instrumentation.api.AgentSpanLink; +import datadog.trace.bootstrap.instrumentation.api.Tags; import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString; import datadog.trace.core.CoreSpan; import datadog.trace.core.Metadata; import datadog.trace.core.MetadataConsumer; +import datadog.trace.core.SpanKindFilter; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; @@ -502,5 +504,26 @@ public PojoSpan setMetaStruct(String field, Object value) { public int getLongRunningVersion() { return 0; } + + @Override + public CharSequence getServiceNameSource() { + return null; + } + + @Override + public boolean isKind(SpanKindFilter filter) { + Object kind = unsafeGetTag(Tags.SPAN_KIND); + return filter.matches(kind == null ? null : kind.toString()); + } + + @Override + public U unsafeGetTag(CharSequence name, U defaultValue) { + return getTag(name, defaultValue); + } + + @Override + public U unsafeGetTag(CharSequence name) { + return getTag(name); + } } } From 132b9196eec05d2757d56e8828a0e31fa134f746 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Tue, 30 Jun 2026 12:13:31 +0200 Subject: [PATCH 3/3] fix: implement CoreSpan methods in traceAgentTest --- .../groovy/TraceGenerator.groovy | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/dd-trace-core/src/traceAgentTest/groovy/TraceGenerator.groovy b/dd-trace-core/src/traceAgentTest/groovy/TraceGenerator.groovy index e668d0112a6..8477ad00df3 100644 --- a/dd-trace-core/src/traceAgentTest/groovy/TraceGenerator.groovy +++ b/dd-trace-core/src/traceAgentTest/groovy/TraceGenerator.groovy @@ -1,6 +1,7 @@ import static datadog.trace.api.ProcessTags.tagsForSerialization import static datadog.trace.api.TagMap.fromMap import static datadog.trace.api.sampling.PrioritySampling.UNSET +import static datadog.trace.bootstrap.instrumentation.api.Tags.SPAN_KIND import static java.lang.Thread.currentThread import static java.util.Collections.emptyList @@ -13,6 +14,7 @@ import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString import datadog.trace.core.CoreSpan import datadog.trace.core.Metadata import datadog.trace.core.MetadataConsumer +import datadog.trace.core.SpanKindFilter import java.util.concurrent.ThreadLocalRandom import java.util.concurrent.TimeUnit @@ -173,6 +175,11 @@ class TraceGenerator { return serviceName } + @Override + CharSequence getServiceNameSource() { + return null + } + @Override CharSequence getOperationName() { return operationName @@ -298,6 +305,12 @@ class TraceGenerator { return false } + @Override + boolean isKind(SpanKindFilter filter) { + Object kind = unsafeGetTag(SPAN_KIND) + return filter.matches(kind == null ? null : kind.toString()) + } + Map getBaggage() { return metadata.getBaggage() } @@ -394,6 +407,16 @@ class TraceGenerator { return value as U } + @Override + U unsafeGetTag(CharSequence name, U defaultValue) { + return getTag(name, defaultValue) + } + + @Override + U unsafeGetTag(CharSequence name) { + return getTag(name) + } + @Override boolean hasSamplingPriority() { return false