Skip to content

Commit cb8f3a1

Browse files
adds tag to specify if the user is setting DD_SERVICE
1 parent a41d151 commit cb8f3a1

File tree

10 files changed

+117
-46
lines changed

10 files changed

+117
-46
lines changed

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/AbstractTestModule.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static datadog.trace.api.civisibility.CIConstants.CI_VISIBILITY_INSTRUMENTATION_NAME;
44

55
import datadog.trace.api.Config;
6+
import datadog.trace.api.DDTags;
67
import datadog.trace.api.civisibility.telemetry.CiVisibilityCountMetric;
78
import datadog.trace.api.civisibility.telemetry.CiVisibilityMetricCollector;
89
import datadog.trace.api.civisibility.telemetry.tag.EventType;
@@ -72,6 +73,8 @@ public AbstractTestModule(
7273
span.setTag(Tags.TEST_MODULE_ID, span.getSpanId());
7374
span.setTag(Tags.TEST_SESSION_ID, span.getTraceId());
7475

76+
span.setTag(DDTags.TEST_IS_USER_PROVIDED_SERVICE, config.isServiceNameSetByUser());
77+
7578
// setting status to skip initially,
7679
// as we do not know in advance whether the module will have any children
7780
span.setTag(Tags.TEST_STATUS, TestStatus.skip);

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/AbstractTestSession.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static datadog.trace.api.civisibility.CIConstants.CI_VISIBILITY_INSTRUMENTATION_NAME;
55

66
import datadog.trace.api.Config;
7+
import datadog.trace.api.DDTags;
78
import datadog.trace.api.DDTraceId;
89
import datadog.trace.api.IdGenerationStrategy;
910
import datadog.trace.api.civisibility.CIConstants;
@@ -97,6 +98,8 @@ public AbstractTestSession(
9798
span.setTag(Tags.SPAN_KIND, Tags.SPAN_KIND_TEST_SESSION);
9899
span.setTag(Tags.TEST_SESSION_ID, span.getTraceId());
99100

101+
span.setTag(DDTags.TEST_IS_USER_PROVIDED_SERVICE, config.isServiceNameSetByUser());
102+
100103
// setting status to skip initially,
101104
// as we do not know in advance whether the session will have any children
102105
span.setTag(Tags.TEST_STATUS, TestStatus.skip);

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/TestImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan;
66

77
import datadog.trace.api.Config;
8+
import datadog.trace.api.DDTags;
89
import datadog.trace.api.DDTraceId;
910
import datadog.trace.api.civisibility.CIConstants;
1011
import datadog.trace.api.civisibility.DDTest;
@@ -124,6 +125,8 @@ public TestImpl(
124125
span.setTag(Tags.TEST_MODULE_ID, moduleSpanContext.getSpanId());
125126
span.setTag(Tags.TEST_SESSION_ID, moduleSpanContext.getTraceId());
126127

128+
span.setTag(DDTags.TEST_IS_USER_PROVIDED_SERVICE, config.isServiceNameSetByUser());
129+
127130
span.setTag(Tags.TEST_STATUS, TestStatus.pass);
128131

129132
if (testClass != null && !testClass.getName().equals(testSuiteName)) {

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/TestSuiteImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan;
66

77
import datadog.trace.api.Config;
8+
import datadog.trace.api.DDTags;
89
import datadog.trace.api.civisibility.DDTestSuite;
910
import datadog.trace.api.civisibility.coverage.CoverageStore;
1011
import datadog.trace.api.civisibility.telemetry.CiVisibilityCountMetric;
@@ -113,6 +114,8 @@ public TestSuiteImpl(
113114
span.setTag(Tags.TEST_MODULE_ID, moduleSpanContext.getSpanId());
114115
span.setTag(Tags.TEST_SESSION_ID, moduleSpanContext.getTraceId());
115116

117+
span.setTag(DDTags.TEST_IS_USER_PROVIDED_SERVICE, config.isServiceNameSetByUser());
118+
116119
// setting status to skip initially,
117120
// as we do not know in advance whether the suite will have any children
118121
span.setTag(Tags.TEST_STATUS, TestStatus.skip);

dd-java-agent/agent-ci-visibility/src/test/groovy/datadog/trace/civisibility/domain/TestImplTest.groovy

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package datadog.trace.civisibility.domain
33
import datadog.trace.agent.test.asserts.ListWriterAssert
44
import datadog.trace.api.Config
55
import datadog.trace.api.DDSpanTypes
6+
import datadog.trace.api.DDTags
67
import datadog.trace.api.DDTraceId
78
import datadog.trace.api.civisibility.config.TestIdentifier
89
import datadog.trace.api.civisibility.coverage.CoverageProbes
@@ -20,7 +21,7 @@ import datadog.trace.civisibility.test.ExecutionResults
2021
import datadog.trace.civisibility.utils.SpanUtils
2122

2223
class TestImplTest extends SpanWriterTest {
23-
def "test span is generated"() {
24+
def "test span is generated and tags populated"() {
2425
setup:
2526
def test = givenATest()
2627

@@ -33,6 +34,9 @@ class TestImplTest extends SpanWriterTest {
3334
span(0) {
3435
parent()
3536
spanType DDSpanTypes.TEST
37+
tags(false) {
38+
"$DDTags.TEST_IS_USER_PROVIDED_SERVICE" true
39+
}
3640
}
3741
}
3842
})
@@ -84,8 +88,7 @@ class TestImplTest extends SpanWriterTest {
8488
0 * coverageStore.report(_, _, _)
8589
}
8690

87-
private TestImpl givenATest(
88-
CoverageStore.Factory coverageStoreFactory = new NoOpCoverageStore.Factory()) {
91+
private TestImpl givenATest(CoverageStore.Factory coverageStoreFactory = new NoOpCoverageStore.Factory()) {
8992

9093
def traceId = Stub(DDTraceId)
9194
traceId.toLong() >> 123
@@ -95,8 +98,10 @@ class TestImplTest extends SpanWriterTest {
9598
moduleSpanContext.getTraceId() >> traceId
9699
def suiteId = 789
97100

101+
def config = Spy(Config.get())
102+
config.isServiceNameSetByUser() >> true
103+
98104
def testFramework = TestFrameworkInstrumentation.OTHER
99-
def config = Config.get()
100105
def metricCollector = Stub(CiVisibilityMetricCollectorImpl)
101106
def executionResults = Stub(ExecutionResults)
102107
def testDecorator = new TestDecoratorImpl("component", "session-name", "test-command", [:])

dd-java-agent/agent-ci-visibility/src/test/groovy/datadog/trace/civisibility/domain/TestSuiteImplTest.groovy

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package datadog.trace.civisibility.domain
33
import datadog.trace.agent.test.asserts.ListWriterAssert
44
import datadog.trace.api.Config
55
import datadog.trace.api.DDSpanTypes
6+
import datadog.trace.api.DDTags
67
import datadog.trace.api.DDTraceId
78
import datadog.trace.api.civisibility.coverage.CoverageStore
89
import datadog.trace.api.civisibility.coverage.NoOpCoverageStore
@@ -34,6 +35,7 @@ class TestSuiteImplTest extends SpanWriterTest {
3435
"$Tags.TEST_CODEOWNERS" "[\"@global-owner1\",\"@global-owner2\"]"
3536
"$Tags.TEST_SOURCE_START" 10
3637
"$Tags.TEST_SOURCE_END" 20
38+
"$DDTags.TEST_IS_USER_PROVIDED_SERVICE" true
3739
}
3840
}
3941
}
@@ -42,17 +44,18 @@ class TestSuiteImplTest extends SpanWriterTest {
4244

4345
private static final class MyClass {}
4446

45-
private TestSuiteImpl givenATestSuite(
46-
CoverageStore.Factory coverageStoreFactory = new NoOpCoverageStore.Factory()) {
47+
private TestSuiteImpl givenATestSuite(CoverageStore.Factory coverageStoreFactory = new NoOpCoverageStore.Factory()) {
4748
def traceId = Stub(DDTraceId)
4849
traceId.toLong() >> 123
4950

5051
def moduleSpanContext = Stub(AgentSpanContext)
5152
moduleSpanContext.getSpanId() >> 456
5253
moduleSpanContext.getTraceId() >> traceId
5354

55+
def config = Spy(Config.get())
56+
config.isServiceNameSetByUser() >> true
57+
5458
def testFramework = TestFrameworkInstrumentation.OTHER
55-
def config = Config.get()
5659
def metricCollector = Stub(CiVisibilityMetricCollectorImpl)
5760
def executionResults = Stub(ExecutionResults)
5861
def testDecorator = new TestDecoratorImpl("component", "session-name", "test-command", [:])
Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package datadog.trace.civisibility.domain.headless
22

3+
import datadog.trace.agent.test.asserts.ListWriterAssert
34
import datadog.trace.api.Config
5+
import datadog.trace.api.DDSpanTypes
6+
import datadog.trace.api.DDTags
47
import datadog.trace.api.civisibility.config.TestIdentifier
58
import datadog.trace.api.civisibility.config.TestSourceData
69
import datadog.trace.api.civisibility.coverage.CoverageStore
@@ -10,14 +13,58 @@ import datadog.trace.civisibility.codeowners.Codeowners
1013
import datadog.trace.civisibility.config.EarlyFlakeDetectionSettings
1114
import datadog.trace.civisibility.config.ExecutionSettings
1215
import datadog.trace.civisibility.decorator.TestDecorator
16+
import datadog.trace.civisibility.domain.SpanWriterTest
1317
import datadog.trace.civisibility.source.LinesResolver
1418
import datadog.trace.civisibility.source.SourcePathResolver
1519
import datadog.trace.civisibility.test.ExecutionStrategy
16-
import datadog.trace.test.util.DDSpecification
1720

18-
class HeadlessTestModuleTest extends DDSpecification {
21+
class HeadlessTestModuleTest extends SpanWriterTest {
22+
def "test module span is created and tags populated"() {
23+
setup:
24+
def headlessTestModule = givenAHeadlessTestModule()
25+
26+
when:
27+
headlessTestModule.end(null)
28+
29+
then:
30+
ListWriterAssert.assertTraces(TEST_WRITER, 1, false, {
31+
trace(1) {
32+
span(0) {
33+
spanType DDSpanTypes.TEST_MODULE_END
34+
tags(false) {
35+
"$DDTags.TEST_IS_USER_PROVIDED_SERVICE" true
36+
}
37+
}
38+
}
39+
})
40+
}
1941

2042
def "test total retries limit is applied across test cases"() {
43+
given:
44+
def headlessTestModule = givenAHeadlessTestModule()
45+
46+
when:
47+
def retryPolicy1 = headlessTestModule.retryPolicy(new TestIdentifier("suite", "test-1", null), TestSourceData.UNKNOWN)
48+
49+
then:
50+
retryPolicy1.retry(false, 1L) // 2nd test execution, 1st retry globally
51+
!retryPolicy1.retry(false, 1L) // asking for 3rd test execution - local limit reached
52+
53+
when:
54+
def retryPolicy2 = headlessTestModule.retryPolicy(new TestIdentifier("suite", "test-2", null), TestSourceData.UNKNOWN)
55+
56+
then:
57+
retryPolicy2.retry(false, 1L) // 2nd test execution, 2nd retry globally (since previous test was retried too)
58+
!retryPolicy2.retry(false, 1L) // asking for 3rd test execution - local limit reached
59+
60+
when:
61+
def retryPolicy3 = headlessTestModule.retryPolicy(new TestIdentifier("suite", "test-3", null), TestSourceData.UNKNOWN)
62+
63+
then:
64+
!retryPolicy3.retry(false, 1L) // asking for 3rd retry globally - global limit reached
65+
}
66+
67+
private HeadlessTestModule givenAHeadlessTestModule() {
2168
def executionSettings = Stub(ExecutionSettings)
2269
executionSettings.getEarlyFlakeDetectionSettings() >> EarlyFlakeDetectionSettings.DEFAULT
2370
executionSettings.isFlakyTestRetriesEnabled() >> true
@@ -28,11 +75,11 @@ class HeadlessTestModuleTest extends DDSpecification {
2875
// this counts all executions of a test case (first attempt is counted too)
2976
config.getCiVisibilityTotalFlakyRetryCount() >> 2
3077
// this counts retries across all tests (first attempt is not a retry, so it is not counted)
78+
config.isServiceNameSetByUser() >> true
3179

3280
def executionStrategy = new ExecutionStrategy(config, executionSettings, Stub(SourcePathResolver), Stub(LinesResolver))
3381

34-
given:
35-
def headlessTestModule = new HeadlessTestModule(
82+
new HeadlessTestModule(
3683
Stub(AgentSpanContext),
3784
"test-module",
3885
null,
@@ -46,27 +93,5 @@ class HeadlessTestModuleTest extends DDSpecification {
4693
executionStrategy,
4794
(span) -> { }
4895
)
49-
50-
when:
51-
def retryPolicy1 = headlessTestModule.retryPolicy(new TestIdentifier("suite", "test-1", null), TestSourceData.UNKNOWN)
52-
53-
then:
54-
retryPolicy1.retry(false, 1L) // 2nd test execution, 1st retry globally
55-
!retryPolicy1.retry(false, 1L) // asking for 3rd test execution - local limit reached
56-
57-
when:
58-
def retryPolicy2 = headlessTestModule.retryPolicy(new TestIdentifier("suite", "test-2", null), TestSourceData.UNKNOWN)
59-
60-
then:
61-
retryPolicy2.retry(false, 1L) // 2nd test execution, 2nd retry globally (since previous test was retried too)
62-
!retryPolicy2.retry(false, 1L) // asking for 3rd test execution - local limit reached
63-
64-
when:
65-
def retryPolicy3 = headlessTestModule.retryPolicy(new TestIdentifier("suite", "test-3", null), TestSourceData.UNKNOWN)
66-
67-
then:
68-
!retryPolicy3.retry(false, 1L) // asking for 3rd retry globally - global limit reached
6996
}
70-
71-
7297
}

dd-trace-api/src/main/java/datadog/trace/api/DDTags.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public class DDTags {
5858
public static final String LIBRARY_VERSION_TAG_KEY = "library_version";
5959
public static final String CI_ENV_VARS = "_dd.ci.env_vars";
6060
public static final String CI_ITR_TESTS_SKIPPED = "_dd.ci.itr.tests_skipped";
61+
public static final String TEST_IS_USER_PROVIDED_SERVICE = "_dd.test.is_user_provided_service";
6162
public static final String MEASURED = "_dd.measured";
6263
public static final String PID_TAG = "process_id";
6364
public static final String SCHEMA_VERSION_TAG_KEY = "_dd.trace_span_attribute_schema";

dd-trace-core/src/main/java/datadog/trace/civisibility/writer/ddintake/CiTestCycleMapperV1.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import datadog.communication.serialization.GrowableBuffer;
88
import datadog.communication.serialization.Writable;
99
import datadog.communication.serialization.msgpack.MsgPackWriter;
10+
import datadog.trace.api.DDTags;
1011
import datadog.trace.api.DDTraceId;
1112
import datadog.trace.api.civisibility.CiVisibilityWellKnownTags;
1213
import datadog.trace.api.civisibility.InstrumentationBridge;
@@ -41,6 +42,8 @@ public class CiTestCycleMapperV1 implements RemoteMapper {
4142
Tags.TEST_SESSION_ID.getBytes(StandardCharsets.UTF_8);
4243
private static final byte[] TEST_MODULE_ID = Tags.TEST_MODULE_ID.getBytes(StandardCharsets.UTF_8);
4344
private static final byte[] TEST_SUITE_ID = Tags.TEST_SUITE_ID.getBytes(StandardCharsets.UTF_8);
45+
private static final byte[] TEST_IS_USER_PROVIDED_SERVICE =
46+
DDTags.TEST_IS_USER_PROVIDED_SERVICE.getBytes(StandardCharsets.UTF_8);
4447
private static final byte[] ITR_CORRELATION_ID =
4548
Tags.ITR_CORRELATION_ID.getBytes(StandardCharsets.UTF_8);
4649

@@ -89,6 +92,9 @@ public void map(List<? extends CoreSpan<?>> trace, Writable writable) {
8992
Number testSuiteId = span.getTag(Tags.TEST_SUITE_ID);
9093
span.removeTag(Tags.TEST_SUITE_ID);
9194

95+
Boolean testIsUserProvidedService = span.getTag(DDTags.TEST_IS_USER_PROVIDED_SERVICE);
96+
span.removeTag(DDTags.TEST_IS_USER_PROVIDED_SERVICE);
97+
9298
String itrCorrelationId = span.getTag(Tags.ITR_CORRELATION_ID);
9399
span.removeTag(Tags.ITR_CORRELATION_ID);
94100

@@ -102,6 +108,9 @@ public void map(List<? extends CoreSpan<?>> trace, Writable writable) {
102108
if (testSuiteId != null) {
103109
topLevelTagsCount++;
104110
}
111+
if (testIsUserProvidedService != null) {
112+
topLevelTagsCount++;
113+
}
105114
if (itrCorrelationId != null) {
106115
topLevelTagsCount++;
107116
}
@@ -193,6 +202,10 @@ public void map(List<? extends CoreSpan<?>> trace, Writable writable) {
193202
writable.writeUTF8(TEST_SUITE_ID);
194203
writable.writeObject(testSuiteId, null);
195204
}
205+
if (testIsUserProvidedService != null) {
206+
writable.writeUTF8(TEST_IS_USER_PROVIDED_SERVICE);
207+
writable.writeObject(testIsUserProvidedService, null);
208+
}
196209
if (itrCorrelationId != null) {
197210
writable.writeUTF8(ITR_CORRELATION_ID);
198211
writable.writeObjectString(itrCorrelationId, null);

0 commit comments

Comments
 (0)