diff --git a/dd-trace-core/src/main/java/datadog/trace/civisibility/writer/ddintake/CiTestCycleMapperV1.java b/dd-trace-core/src/main/java/datadog/trace/civisibility/writer/ddintake/CiTestCycleMapperV1.java index 534282701b7..7593ce9b9dd 100644 --- a/dd-trace-core/src/main/java/datadog/trace/civisibility/writer/ddintake/CiTestCycleMapperV1.java +++ b/dd-trace-core/src/main/java/datadog/trace/civisibility/writer/ddintake/CiTestCycleMapperV1.java @@ -9,6 +9,7 @@ import datadog.communication.serialization.msgpack.MsgPackWriter; import datadog.trace.api.DDTags; import datadog.trace.api.DDTraceId; +import datadog.trace.api.TagMap; import datadog.trace.api.civisibility.CiVisibilityWellKnownTags; import datadog.trace.api.civisibility.InstrumentationBridge; import datadog.trace.api.civisibility.telemetry.CiVisibilityDistributionMetric; @@ -84,16 +85,9 @@ public void map(List> trace, Writable writable) { for (final CoreSpan span : trace) { DDTraceId testSessionId = span.getTag(Tags.TEST_SESSION_ID); - span.removeTag(Tags.TEST_SESSION_ID); - Number testModuleId = span.getTag(Tags.TEST_MODULE_ID); - span.removeTag(Tags.TEST_MODULE_ID); - Number testSuiteId = span.getTag(Tags.TEST_SUITE_ID); - span.removeTag(Tags.TEST_SUITE_ID); - String itrCorrelationId = span.getTag(Tags.ITR_CORRELATION_ID); - span.removeTag(Tags.ITR_CORRELATION_ID); int topLevelTagsCount = 0; if (testSessionId != null) { @@ -323,12 +317,18 @@ MetaWriter withWritable(Writable writable) { @Override public void accept(Metadata metadata) { + TagMap tags = metadata.getTags().copy(); + + for (String ignoredTag : DEFAULT_TOP_LEVEL_TAGS) { + tags.remove(ignoredTag); + } + int metaSize = metadata.getBaggage().size() - + metadata.getTags().size() + + tags.size() + (null == metadata.getHttpStatusCode() ? 0 : 1); int metricsSize = 0; - for (Map.Entry tag : metadata.getTags().entrySet()) { + for (Map.Entry tag : tags.entrySet()) { if (tag.getValue() instanceof Number) { ++metricsSize; --metaSize; @@ -336,7 +336,7 @@ public void accept(Metadata metadata) { } writable.writeUTF8(METRICS); writable.startMap(metricsSize); - for (Map.Entry entry : metadata.getTags().entrySet()) { + for (Map.Entry entry : tags.entrySet()) { if (entry.getValue() instanceof Number) { writable.writeString(entry.getKey(), null); writable.writeObject(entry.getValue(), null); @@ -356,7 +356,7 @@ public void accept(Metadata metadata) { writable.writeUTF8(HTTP_STATUS); writable.writeUTF8(metadata.getHttpStatusCode()); } - for (Map.Entry entry : metadata.getTags().entrySet()) { + for (Map.Entry entry : tags.entrySet()) { Object value = entry.getValue(); if (!(value instanceof Number)) { writable.writeString(entry.getKey(), null); diff --git a/dd-trace-core/src/test/groovy/datadog/trace/civisibility/writer/ddintake/CiTestCycleMapperV1PayloadTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/civisibility/writer/ddintake/CiTestCycleMapperV1PayloadTest.groovy index 98b86f01b3f..8c9bf2768c6 100644 --- a/dd-trace-core/src/test/groovy/datadog/trace/civisibility/writer/ddintake/CiTestCycleMapperV1PayloadTest.groovy +++ b/dd-trace-core/src/test/groovy/datadog/trace/civisibility/writer/ddintake/CiTestCycleMapperV1PayloadTest.groovy @@ -149,6 +149,27 @@ class CiTestCycleMapperV1PayloadTest extends DDSpecification { assert !spanContent.containsKey("parent_id") } + def "verify result is not affected by successive mapping calls"(){ + setup: + def span = generateRandomSpan(InternalSpanTypes.TEST, [ + (Tags.TEST_SESSION_ID): DDTraceId.from(123), + (Tags.TEST_MODULE_ID) : 456, + (Tags.TEST_SUITE_ID) : 789, + ]) + + when: + whenASpanIsWritten(span) + Map deserializedSpan = whenASpanIsWritten(span) + + then: + verifyTopLevelTags(deserializedSpan, DDTraceId.from(123), 456, 789) + + def spanContent = (Map) deserializedSpan.get("content") + assert spanContent.containsKey("trace_id") + assert spanContent.containsKey("span_id") + assert spanContent.containsKey("parent_id") + } + private static void verifyTopLevelTags(Map deserializedSpan, DDTraceId testSessionId, Long testModuleId, Long testSuiteId) { Map deserializedSpanContent = (Map) deserializedSpan.get("content") Map deserializedMetrics = (Map) deserializedSpanContent.get("metrics")