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..d65295563f5 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 @@ -58,9 +58,14 @@ public class CiTestCycleMapperV1 implements RemoteMapper { private static final UTF8BytesString SPAN_TYPE = UTF8BytesString.create("span"); - private static final Collection DEFAULT_TOP_LEVEL_TAGS = - Arrays.asList( - Tags.TEST_SESSION_ID, Tags.TEST_MODULE_ID, Tags.TEST_SUITE_ID, Tags.ITR_CORRELATION_ID); + private static final Set DEFAULT_TOP_LEVEL_TAGS = + Collections.unmodifiableSet( + new HashSet<>( + Arrays.asList( + Tags.TEST_SESSION_ID, + Tags.TEST_MODULE_ID, + Tags.TEST_SUITE_ID, + Tags.ITR_CORRELATION_ID))); private final CiVisibilityWellKnownTags wellKnownTags; private final int size; @@ -84,16 +89,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,23 +321,29 @@ MetaWriter withWritable(Writable writable) { @Override public void accept(Metadata metadata) { - int metaSize = - metadata.getBaggage().size() - + metadata.getTags().size() - + (null == metadata.getHttpStatusCode() ? 0 : 1); + int metaSize = metadata.getBaggage().size() + (null == metadata.getHttpStatusCode() ? 0 : 1); int metricsSize = 0; for (Map.Entry tag : metadata.getTags().entrySet()) { + if (DEFAULT_TOP_LEVEL_TAGS.contains(tag.getKey())) { + continue; + } if (tag.getValue() instanceof Number) { ++metricsSize; - --metaSize; + } else { + ++metaSize; } } writable.writeUTF8(METRICS); writable.startMap(metricsSize); for (Map.Entry entry : metadata.getTags().entrySet()) { - if (entry.getValue() instanceof Number) { - writable.writeString(entry.getKey(), null); - writable.writeObject(entry.getValue(), null); + String key = entry.getKey(); + if (DEFAULT_TOP_LEVEL_TAGS.contains(key)) { + continue; + } + Object value = entry.getValue(); + if (value instanceof Number) { + writable.writeString(key, null); + writable.writeObject(value, null); } } @@ -357,9 +361,13 @@ public void accept(Metadata metadata) { writable.writeUTF8(metadata.getHttpStatusCode()); } for (Map.Entry entry : metadata.getTags().entrySet()) { + String key = entry.getKey(); + if (DEFAULT_TOP_LEVEL_TAGS.contains(key)) { + continue; + } Object value = entry.getValue(); if (!(value instanceof Number)) { - writable.writeString(entry.getKey(), null); + writable.writeString(key, null); if (!(value instanceof Iterable)) { writable.writeObjectString(value, null); } else { 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")