diff --git a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentSpan.java b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentSpan.java index c1b38140d22..b218ef0478d 100644 --- a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentSpan.java +++ b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentSpan.java @@ -210,6 +210,7 @@ default boolean isValid() { AgentSpan setSamplingPriority(final int newPriority, int samplingMechanism); + @Nonnull TraceConfig traceConfig(); void addLink(AgentSpanLink link); diff --git a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/ExtractedSpan.java b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/ExtractedSpan.java index 80d2331ce43..d589141b8d2 100644 --- a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/ExtractedSpan.java +++ b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/ExtractedSpan.java @@ -140,7 +140,13 @@ public AgentSpanContext spanContext() { @Override public TraceConfig traceConfig() { - return null; + if (this.spanContext instanceof TagContext) { + TraceConfig traceConfig = ((TagContext) this.spanContext).getTraceConfig(); + if (traceConfig != null) { + return traceConfig; + } + } + return AgentTracer.traceConfig(); } @Override diff --git a/internal-api/src/test/groovy/datadog/trace/bootstrap/instrumentation/api/ExtractedSpanTest.groovy b/internal-api/src/test/groovy/datadog/trace/bootstrap/instrumentation/api/ExtractedSpanTest.groovy deleted file mode 100644 index 81bda406fbc..00000000000 --- a/internal-api/src/test/groovy/datadog/trace/bootstrap/instrumentation/api/ExtractedSpanTest.groovy +++ /dev/null @@ -1,53 +0,0 @@ -package datadog.trace.bootstrap.instrumentation.api - -import datadog.trace.api.DDTraceId -import datadog.trace.api.TagMap -import spock.lang.Specification - -class ExtractedSpanTest extends Specification { - def 'test extracted span from partial tracing context'() { - given: - def tags = TagMap.fromMap(['tag-1': 'value-1', 'tag-2': 'value-2']) - def baggage = ['baggage-1': 'value-1', 'baggage-2': 'value-2'] - def traceId = DDTraceId.from(12345) - def context = new TagContext('origin', tags, null, baggage, 0, null, null, traceId) - def extractedSpan = new ExtractedSpan(context) - - expect: - extractedSpan.getTraceId() == traceId - extractedSpan.getSpanId() == context.getSpanId() - extractedSpan.spanContext() == context - extractedSpan.getTags() == tags - extractedSpan.getTag('tag-1') == 'value-1' - extractedSpan.getBaggageItem('baggage-2') == 'value-2' - extractedSpan.isSameTrace(new ExtractedSpan(context)) - extractedSpan.toString() != null - - when: - extractedSpan.setTag('tag-1', 'updated') - extractedSpan.setBaggageItem('baggage-2', 'updated') - - then: - extractedSpan.getTag('tag-1') == 'value-1' - extractedSpan.getBaggageItem('baggage-2') == 'value-2' - } - - def 'test extracted span from custom span context'() { - given: - def context = Mock(AgentSpanContext) - context.getTraceId() >> DDTraceId.from(12345) - context.getSpanId() >> 67890 - context.baggageItems() >> Collections.emptyMap().entrySet() - def extractedSpan = new ExtractedSpan(context) - - expect: - extractedSpan.getTraceId() == context.getTraceId() - extractedSpan.getSpanId() == context.getSpanId() - extractedSpan.spanContext() == context - extractedSpan.getTags().isEmpty() - extractedSpan.getTag('tag-1') == null - extractedSpan.getBaggageItem('baggage-2') == null - extractedSpan.isSameTrace(new ExtractedSpan(context)) - extractedSpan.toString() != null - } -} diff --git a/internal-api/src/test/java/datadog/trace/bootstrap/instrumentation/api/ExtractedSpanTest.java b/internal-api/src/test/java/datadog/trace/bootstrap/instrumentation/api/ExtractedSpanTest.java new file mode 100644 index 00000000000..852e0142ba2 --- /dev/null +++ b/internal-api/src/test/java/datadog/trace/bootstrap/instrumentation/api/ExtractedSpanTest.java @@ -0,0 +1,91 @@ +package datadog.trace.bootstrap.instrumentation.api; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import datadog.trace.api.DDTraceId; +import datadog.trace.api.TagMap; +import datadog.trace.api.TraceConfig; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class ExtractedSpanTest { + + @Test + void extractedSpanFromPartialTracingContext() { + Map tagValues = new HashMap<>(); + tagValues.put("tag-1", "value-1"); + tagValues.put("tag-2", "value-2"); + TagMap tags = TagMap.fromMap(tagValues); + Map baggage = new HashMap<>(); + baggage.put("baggage-1", "value-1"); + baggage.put("baggage-2", "value-2"); + DDTraceId traceId = DDTraceId.from(12345); + TagContext context = new TagContext("origin", tags, null, baggage, 0, null, null, traceId); + ExtractedSpan extractedSpan = new ExtractedSpan(context); + + assertEquals(traceId, extractedSpan.getTraceId()); + assertEquals(context.getSpanId(), extractedSpan.getSpanId()); + assertEquals(context, extractedSpan.spanContext()); + assertEquals(tags, extractedSpan.getTags()); + assertEquals("value-1", extractedSpan.getTag("tag-1")); + assertEquals("value-2", extractedSpan.getBaggageItem("baggage-2")); + assertTrue(extractedSpan.isSameTrace(new ExtractedSpan(context))); + assertNotNull(extractedSpan.toString()); + + extractedSpan.setTag("tag-1", "updated"); + extractedSpan.setBaggageItem("baggage-2", "updated"); + + assertEquals("value-1", extractedSpan.getTag("tag-1")); + assertEquals("value-2", extractedSpan.getBaggageItem("baggage-2")); + } + + @Test + void extractedSpanFromCustomSpanContext() { + AgentSpanContext context = mock(AgentSpanContext.class); + when(context.getTraceId()).thenReturn(DDTraceId.from(12345)); + when(context.getSpanId()).thenReturn(67890L); + when(context.baggageItems()).thenReturn(Collections.emptyMap().entrySet()); + ExtractedSpan extractedSpan = new ExtractedSpan(context); + + assertEquals(context.getTraceId(), extractedSpan.getTraceId()); + assertEquals(context.getSpanId(), extractedSpan.getSpanId()); + assertEquals(context, extractedSpan.spanContext()); + assertTrue(extractedSpan.getTags().isEmpty()); + assertNull(extractedSpan.getTag("tag-1")); + assertNull(extractedSpan.getBaggageItem("baggage-2")); + assertTrue(extractedSpan.isSameTrace(new ExtractedSpan(context))); + assertNotNull(extractedSpan.toString()); + } + + @Test + void traceConfigReturnsExtractedSnapshotWhenPresent() { + TraceConfig snapshot = mock(TraceConfig.class); + TagContext context = new TagContext(null, null, null, null, 0, snapshot, null, DDTraceId.ZERO); + ExtractedSpan extractedSpan = new ExtractedSpan(context); + + assertEquals(snapshot, extractedSpan.traceConfig()); + } + + @Test + void traceConfigFallsBackToCurrentConfigWhenSnapshotAbsent() { + TagContext context = new TagContext(); + ExtractedSpan extractedSpan = new ExtractedSpan(context); + + assertNotNull(extractedSpan.traceConfig()); + } + + @Test + void traceConfigFallsBackToCurrentConfigForCustomSpanContext() { + AgentSpanContext context = mock(AgentSpanContext.class); + ExtractedSpan extractedSpan = new ExtractedSpan(context); + + assertNotNull(extractedSpan.traceConfig()); + } +}