Skip to content

Commit 1efc71f

Browse files
Always request known tests from the backend (#8268)
1 parent 4025000 commit 1efc71f

File tree

123 files changed

+1104
-631
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+1104
-631
lines changed

dd-java-agent/agent-ci-visibility/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ dependencies {
4343
testFixturesApi project(':utils:test-utils')
4444

4545
testFixturesApi group: 'org.skyscreamer', name: 'jsonassert', version: '1.5.1'
46-
testFixturesApi group: 'org.freemarker', name: 'freemarker', version: '2.3.30'
46+
testFixturesApi group: 'org.freemarker', name: 'freemarker', version: '2.3.31'
4747
testFixturesApi group: 'com.jayway.jsonpath', name: 'json-path', version: '2.8.0'
4848
testFixturesApi group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.16.0'
4949
testFixturesApi group: 'org.msgpack', name: 'jackson-dataformat-msgpack', version: '0.9.6'

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/config/CiVisibilitySettings.java

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,39 @@
33
import com.squareup.moshi.FromJson;
44
import java.nio.file.Path;
55
import java.util.Map;
6+
import java.util.Objects;
67

78
public class CiVisibilitySettings {
89

910
public static final CiVisibilitySettings DEFAULT =
1011
new CiVisibilitySettings(
11-
false, false, false, false, false, false, EarlyFlakeDetectionSettings.DEFAULT);
12+
false, false, false, false, false, false, false, EarlyFlakeDetectionSettings.DEFAULT);
1213

1314
private final boolean itrEnabled;
1415
private final boolean codeCoverage;
1516
private final boolean testsSkipping;
1617
private final boolean requireGit;
1718
private final boolean flakyTestRetriesEnabled;
1819
private final boolean impactedTestsDetectionEnabled;
20+
private final boolean knownTestsEnabled;
1921
private final EarlyFlakeDetectionSettings earlyFlakeDetectionSettings;
2022

21-
private CiVisibilitySettings(
23+
CiVisibilitySettings(
2224
boolean itrEnabled,
2325
boolean codeCoverage,
2426
boolean testsSkipping,
2527
boolean requireGit,
2628
boolean flakyTestRetriesEnabled,
2729
boolean impactedTestsDetectionEnabled,
30+
boolean knownTestsEnabled,
2831
EarlyFlakeDetectionSettings earlyFlakeDetectionSettings) {
2932
this.itrEnabled = itrEnabled;
3033
this.codeCoverage = codeCoverage;
3134
this.testsSkipping = testsSkipping;
3235
this.requireGit = requireGit;
3336
this.flakyTestRetriesEnabled = flakyTestRetriesEnabled;
3437
this.impactedTestsDetectionEnabled = impactedTestsDetectionEnabled;
38+
this.knownTestsEnabled = knownTestsEnabled;
3539
this.earlyFlakeDetectionSettings = earlyFlakeDetectionSettings;
3640
}
3741

@@ -59,10 +63,46 @@ public boolean isImpactedTestsDetectionEnabled() {
5963
return impactedTestsDetectionEnabled;
6064
}
6165

66+
public boolean isKnownTestsEnabled() {
67+
return knownTestsEnabled;
68+
}
69+
6270
public EarlyFlakeDetectionSettings getEarlyFlakeDetectionSettings() {
6371
return earlyFlakeDetectionSettings;
6472
}
6573

74+
@Override
75+
public boolean equals(Object o) {
76+
if (this == o) {
77+
return true;
78+
}
79+
if (o == null || getClass() != o.getClass()) {
80+
return false;
81+
}
82+
CiVisibilitySettings that = (CiVisibilitySettings) o;
83+
return itrEnabled == that.itrEnabled
84+
&& codeCoverage == that.codeCoverage
85+
&& testsSkipping == that.testsSkipping
86+
&& requireGit == that.requireGit
87+
&& flakyTestRetriesEnabled == that.flakyTestRetriesEnabled
88+
&& impactedTestsDetectionEnabled == that.impactedTestsDetectionEnabled
89+
&& knownTestsEnabled == that.knownTestsEnabled
90+
&& Objects.equals(earlyFlakeDetectionSettings, that.earlyFlakeDetectionSettings);
91+
}
92+
93+
@Override
94+
public int hashCode() {
95+
return Objects.hash(
96+
itrEnabled,
97+
codeCoverage,
98+
testsSkipping,
99+
requireGit,
100+
flakyTestRetriesEnabled,
101+
impactedTestsDetectionEnabled,
102+
knownTestsEnabled,
103+
earlyFlakeDetectionSettings);
104+
}
105+
66106
public interface Factory {
67107
CiVisibilitySettings create(Path path);
68108
}
@@ -84,6 +124,7 @@ public CiVisibilitySettings fromJson(Map<String, Object> json) {
84124
getBoolean(json, "require_git", false),
85125
getBoolean(json, "flaky_test_retries_enabled", false),
86126
getBoolean(json, "impacted_tests_enabled", false),
127+
getBoolean(json, "known_tests_enabled", false),
87128
EarlyFlakeDetectionSettingsJsonAdapter.INSTANCE.fromJson(
88129
(Map<String, Object>) json.get("early_flake_detection")));
89130
}

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/config/ConfigurationApi.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.util.Collection;
66
import java.util.Collections;
77
import java.util.Map;
8+
import javax.annotation.Nullable;
89

910
public interface ConfigurationApi {
1011

@@ -45,6 +46,7 @@ public ChangedFiles getChangedFiles(TracerEnvironment tracerEnvironment) {
4546
Map<String, Collection<TestIdentifier>> getFlakyTestsByModule(TracerEnvironment tracerEnvironment)
4647
throws IOException;
4748

49+
@Nullable
4850
Map<String, Collection<TestIdentifier>> getKnownTestsByModule(TracerEnvironment tracerEnvironment)
4951
throws IOException;
5052

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/config/ConfigurationApiImpl.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
import datadog.trace.api.civisibility.telemetry.tag.CoverageEnabled;
1717
import datadog.trace.api.civisibility.telemetry.tag.EarlyFlakeDetectionEnabled;
1818
import datadog.trace.api.civisibility.telemetry.tag.FlakyTestRetriesEnabled;
19+
import datadog.trace.api.civisibility.telemetry.tag.ImpactedTestsDetectionEnabled;
1920
import datadog.trace.api.civisibility.telemetry.tag.ItrEnabled;
2021
import datadog.trace.api.civisibility.telemetry.tag.ItrSkipEnabled;
22+
import datadog.trace.api.civisibility.telemetry.tag.KnownTestsEnabled;
2123
import datadog.trace.api.civisibility.telemetry.tag.RequireGit;
2224
import datadog.trace.civisibility.communication.TelemetryListener;
2325
import java.io.File;
@@ -141,6 +143,8 @@ public CiVisibilitySettings getSettings(TracerEnvironment tracerEnvironment) thr
141143
? EarlyFlakeDetectionEnabled.TRUE
142144
: null,
143145
settings.isFlakyTestRetriesEnabled() ? FlakyTestRetriesEnabled.TRUE : null,
146+
settings.isKnownTestsEnabled() ? KnownTestsEnabled.TRUE : null,
147+
settings.isImpactedTestsDetectionEnabled() ? ImpactedTestsDetectionEnabled.TRUE : null,
144148
settings.isGitUploadRequired() ? RequireGit.TRUE : null);
145149

146150
return settings;
@@ -238,15 +242,16 @@ public Map<String, Collection<TestIdentifier>> getFlakyTestsByModule(
238242
return testIdentifiers;
239243
}
240244

245+
@Nullable
241246
@Override
242247
public Map<String, Collection<TestIdentifier>> getKnownTestsByModule(
243248
TracerEnvironment tracerEnvironment) throws IOException {
244249
OkHttpUtils.CustomListener telemetryListener =
245250
new TelemetryListener.Builder(metricCollector)
246-
.requestCount(CiVisibilityCountMetric.EFD_REQUEST)
247-
.requestErrors(CiVisibilityCountMetric.EFD_REQUEST_ERRORS)
248-
.requestDuration(CiVisibilityDistributionMetric.EFD_REQUEST_MS)
249-
.responseBytes(CiVisibilityDistributionMetric.EFD_RESPONSE_BYTES)
251+
.requestCount(CiVisibilityCountMetric.KNOWN_TESTS_REQUEST)
252+
.requestErrors(CiVisibilityCountMetric.KNOWN_TESTS_REQUEST_ERRORS)
253+
.requestDuration(CiVisibilityDistributionMetric.KNOWN_TESTS_REQUEST_MS)
254+
.responseBytes(CiVisibilityDistributionMetric.KNOWN_TESTS_RESPONSE_BYTES)
250255
.build();
251256

252257
String uuid = uuidGenerator.get();
@@ -288,8 +293,15 @@ private Map<String, Collection<TestIdentifier>> parseTestIdentifiers(KnownTestsD
288293
}
289294

290295
LOGGER.debug("Received {} known tests in total", knownTestsCount);
291-
metricCollector.add(CiVisibilityDistributionMetric.EFD_RESPONSE_TESTS, knownTestsCount);
292-
return testIdentifiers;
296+
metricCollector.add(CiVisibilityDistributionMetric.KNOWN_TESTS_RESPONSE_TESTS, knownTestsCount);
297+
return knownTestsCount > 0
298+
? testIdentifiers
299+
// returning null if there are no known tests:
300+
// this will disable the features that are reliant on known tests
301+
// and is done on purpose:
302+
// if no tests are known, this is likely the first execution for this repository,
303+
// and we want to fill the backend with the initial set of tests
304+
: null;
293305
}
294306

295307
@Override

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/config/EarlyFlakeDetectionSettings.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ public ExecutionsByDuration(long durationMillis, int executions) {
7171
this.executions = executions;
7272
}
7373

74+
public long getDurationMillis() {
75+
return durationMillis;
76+
}
77+
78+
public int getExecutions() {
79+
return executions;
80+
}
81+
7482
@Override
7583
public boolean equals(Object o) {
7684
if (this == o) {

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/config/ExecutionSettingsFactoryImpl.java

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Map;
2525
import java.util.Set;
2626
import java.util.concurrent.TimeUnit;
27+
import java.util.function.Function;
2728
import javax.annotation.Nonnull;
2829
import javax.annotation.Nullable;
2930
import org.slf4j.Logger;
@@ -113,14 +114,41 @@ private TracerEnvironment buildTracerEnvironment(
113114
}
114115

115116
private @Nonnull Map<String, ExecutionSettings> create(TracerEnvironment tracerEnvironment) {
116-
CiVisibilitySettings ciVisibilitySettings = getCiVisibilitySettings(tracerEnvironment);
117-
118-
boolean itrEnabled = isItrEnabled(ciVisibilitySettings);
119-
boolean codeCoverageEnabled = isCodeCoverageEnabled(ciVisibilitySettings);
120-
boolean testSkippingEnabled = isTestSkippingEnabled(ciVisibilitySettings);
121-
boolean flakyTestRetriesEnabled = isFlakyTestRetriesEnabled(ciVisibilitySettings);
122-
boolean impactedTestsDetectionEnabled = isImpactedTestsDetectionEnabled(ciVisibilitySettings);
123-
boolean earlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled(ciVisibilitySettings);
117+
CiVisibilitySettings settings = getCiVisibilitySettings(tracerEnvironment);
118+
119+
boolean itrEnabled =
120+
isFeatureEnabled(
121+
settings, CiVisibilitySettings::isItrEnabled, Config::isCiVisibilityItrEnabled);
122+
boolean codeCoverageEnabled =
123+
isFeatureEnabled(
124+
settings,
125+
CiVisibilitySettings::isCodeCoverageEnabled,
126+
Config::isCiVisibilityCodeCoverageEnabled);
127+
boolean testSkippingEnabled =
128+
isFeatureEnabled(
129+
settings,
130+
CiVisibilitySettings::isTestsSkippingEnabled,
131+
Config::isCiVisibilityTestSkippingEnabled);
132+
boolean flakyTestRetriesEnabled =
133+
isFeatureEnabled(
134+
settings,
135+
CiVisibilitySettings::isFlakyTestRetriesEnabled,
136+
Config::isCiVisibilityFlakyRetryEnabled);
137+
boolean impactedTestsDetectionEnabled =
138+
isFeatureEnabled(
139+
settings,
140+
CiVisibilitySettings::isImpactedTestsDetectionEnabled,
141+
Config::isCiVisibilityImpactedTestsDetectionEnabled);
142+
boolean earlyFlakeDetectionEnabled =
143+
isFeatureEnabled(
144+
settings,
145+
s -> s.getEarlyFlakeDetectionSettings().isEnabled(),
146+
Config::isCiVisibilityEarlyFlakeDetectionEnabled);
147+
boolean knownTestsRequest =
148+
isFeatureEnabled(
149+
settings,
150+
CiVisibilitySettings::isKnownTestsEnabled,
151+
Config::isCiVisibilityKnownTestsRequestEnabled);
124152

125153
LOGGER.info(
126154
"CI Visibility settings ({}, {}/{}/{}):\n"
@@ -129,6 +157,7 @@ private TracerEnvironment buildTracerEnvironment(
129157
+ "Tests skipping - {},\n"
130158
+ "Early flakiness detection - {},\n"
131159
+ "Impacted tests detection - {},\n"
160+
+ "Known tests marking - {},\n"
132161
+ "Auto test retries - {}",
133162
repositoryRoot,
134163
tracerEnvironment.getConfigurations().getRuntimeName(),
@@ -139,6 +168,7 @@ private TracerEnvironment buildTracerEnvironment(
139168
testSkippingEnabled,
140169
earlyFlakeDetectionEnabled,
141170
impactedTestsDetectionEnabled,
171+
knownTestsRequest,
142172
flakyTestRetriesEnabled);
143173

144174
String itrCorrelationId = null;
@@ -163,11 +193,7 @@ private TracerEnvironment buildTracerEnvironment(
163193
: null;
164194

165195
Map<String, Collection<TestIdentifier>> knownTestsByModule =
166-
earlyFlakeDetectionEnabled
167-
|| CIConstants.FAIL_FAST_TEST_ORDER.equalsIgnoreCase(
168-
config.getCiVisibilityTestOrder())
169-
? getKnownTestsByModule(tracerEnvironment)
170-
: null;
196+
knownTestsRequest ? getKnownTestsByModule(tracerEnvironment) : null;
171197

172198
Set<String> moduleNames = new HashSet<>(Collections.singleton(DEFAULT_SETTINGS));
173199
moduleNames.addAll(skippableTestIdentifiers.keySet());
@@ -191,7 +217,7 @@ private TracerEnvironment buildTracerEnvironment(
191217
flakyTestRetriesEnabled,
192218
impactedTestsDetectionEnabled,
193219
earlyFlakeDetectionEnabled
194-
? ciVisibilitySettings.getEarlyFlakeDetectionSettings()
220+
? settings.getEarlyFlakeDetectionSettings()
195221
: EarlyFlakeDetectionSettings.DEFAULT,
196222
itrCorrelationId,
197223
skippableTestIdentifiers.getOrDefault(moduleName, Collections.emptyMap()),
@@ -225,33 +251,11 @@ private CiVisibilitySettings getCiVisibilitySettings(TracerEnvironment tracerEnv
225251
}
226252
}
227253

228-
private boolean isItrEnabled(CiVisibilitySettings ciVisibilitySettings) {
229-
return ciVisibilitySettings.isItrEnabled() && config.isCiVisibilityItrEnabled();
230-
}
231-
232-
private boolean isTestSkippingEnabled(CiVisibilitySettings ciVisibilitySettings) {
233-
return ciVisibilitySettings.isTestsSkippingEnabled()
234-
&& config.isCiVisibilityTestSkippingEnabled();
235-
}
236-
237-
private boolean isCodeCoverageEnabled(CiVisibilitySettings ciVisibilitySettings) {
238-
return ciVisibilitySettings.isCodeCoverageEnabled()
239-
&& config.isCiVisibilityCodeCoverageEnabled();
240-
}
241-
242-
private boolean isFlakyTestRetriesEnabled(CiVisibilitySettings ciVisibilitySettings) {
243-
return ciVisibilitySettings.isFlakyTestRetriesEnabled()
244-
&& config.isCiVisibilityFlakyRetryEnabled();
245-
}
246-
247-
private boolean isImpactedTestsDetectionEnabled(CiVisibilitySettings ciVisibilitySettings) {
248-
return ciVisibilitySettings.isImpactedTestsDetectionEnabled()
249-
&& config.isCiVisibilityImpactedTestsDetectionEnabled();
250-
}
251-
252-
private boolean isEarlyFlakeDetectionEnabled(CiVisibilitySettings ciVisibilitySettings) {
253-
return ciVisibilitySettings.getEarlyFlakeDetectionSettings().isEnabled()
254-
&& config.isCiVisibilityEarlyFlakeDetectionEnabled();
254+
private boolean isFeatureEnabled(
255+
CiVisibilitySettings ciVisibilitySettings,
256+
Function<CiVisibilitySettings, Boolean> remoteSetting,
257+
Function<Config, Boolean> killSwitch) {
258+
return remoteSetting.apply(ciVisibilitySettings) && killSwitch.apply(config);
255259
}
256260

257261
@Nullable

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/config/TracerEnvironment.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,26 @@ public String getSha() {
4040
return sha;
4141
}
4242

43+
public String getService() {
44+
return service;
45+
}
46+
47+
public String getEnv() {
48+
return env;
49+
}
50+
51+
public String getRepositoryUrl() {
52+
return repositoryUrl;
53+
}
54+
55+
public String getBranch() {
56+
return branch;
57+
}
58+
59+
public String getTestLevel() {
60+
return testLevel;
61+
}
62+
4363
public Configurations getConfigurations() {
4464
return configurations;
4565
}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import datadog.trace.api.civisibility.telemetry.tag.IsNew;
2323
import datadog.trace.api.civisibility.telemetry.tag.IsRetry;
2424
import datadog.trace.api.civisibility.telemetry.tag.IsRum;
25+
import datadog.trace.api.civisibility.telemetry.tag.RetryReason;
2526
import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation;
2627
import datadog.trace.api.gateway.RequestContextSlot;
2728
import datadog.trace.bootstrap.instrumentation.api.AgentScope;
@@ -265,12 +266,25 @@ public void end(@Nullable Long endTime) {
265266
span.getTag(Tags.TEST_IS_NEW) != null ? IsNew.TRUE : null,
266267
span.getTag(Tags.TEST_IS_MODIFIED) != null ? IsModified.TRUE : null,
267268
span.getTag(Tags.TEST_IS_RETRY) != null ? IsRetry.TRUE : null,
269+
getRetryReason(),
268270
span.getTag(Tags.TEST_IS_RUM_ACTIVE) != null ? IsRum.TRUE : null,
269271
CIConstants.SELENIUM_BROWSER_DRIVER.equals(span.getTag(Tags.TEST_BROWSER_DRIVER))
270272
? BrowserDriver.SELENIUM
271273
: null);
272274
}
273275

276+
private RetryReason getRetryReason() {
277+
String retryReason = (String) span.getTag(Tags.TEST_RETRY_REASON);
278+
if (retryReason != null) {
279+
try {
280+
return RetryReason.valueOf(retryReason.toUpperCase());
281+
} catch (IllegalArgumentException e) {
282+
log.debug("Non-standard retry-reason: {}", retryReason);
283+
}
284+
}
285+
return null;
286+
}
287+
274288
/**
275289
* Tests often perform operations that involve APM instrumentations: sending an HTTP request,
276290
* executing a database query, etc. APM instrumentations create spans that correspond to those

0 commit comments

Comments
 (0)