Skip to content

Commit ab302c3

Browse files
Upload code coverage reports to Datadog (#9425)
1 parent 774fd16 commit ab302c3

File tree

67 files changed

+1006
-200
lines changed

Some content is hidden

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

67 files changed

+1006
-200
lines changed

communication/src/main/java/datadog/communication/BackendApiFactory.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ public enum Intake {
7777
"http-intake.logs",
7878
"v2",
7979
Config::isAgentlessLogSubmissionEnabled,
80-
Config::getAgentlessLogSubmissionUrl);
80+
Config::getAgentlessLogSubmissionUrl),
81+
CI_INTAKE(
82+
"ci-intake",
83+
"v2",
84+
Config::isCiVisibilityAgentlessEnabled,
85+
Config::getCiVisibilityIntakeAgentlessUrl);
8186

8287
public final String urlPrefix;
8388
public final String version;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ dependencies {
6464
testFixturesApi group: 'com.jayway.jsonpath', name: 'json-path', version: '2.8.0'
6565
testFixturesApi group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.16.0'
6666
testFixturesApi group: 'org.msgpack', name: 'jackson-dataformat-msgpack', version: '0.9.6'
67+
testFixturesApi group: 'org.xmlunit', name: 'xmlunit-core', version: '2.10.3'
6768

6869
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.9.2") // Required to update dependency lock files
6970
}

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

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,45 @@
66
import datadog.trace.api.civisibility.coverage.CoverageStore;
77
import datadog.trace.api.civisibility.coverage.NoOpCoverageStore;
88
import datadog.trace.civisibility.config.ExecutionSettings;
9+
import datadog.trace.civisibility.config.JvmInfo;
910
import datadog.trace.civisibility.coverage.SkippableAwareCoverageStoreFactory;
1011
import datadog.trace.civisibility.coverage.file.FileCoverageStore;
1112
import datadog.trace.civisibility.coverage.line.LineCoverageStore;
12-
import datadog.trace.civisibility.coverage.percentage.CoverageCalculator;
13-
import datadog.trace.civisibility.coverage.percentage.JacocoCoverageCalculator;
14-
import datadog.trace.civisibility.coverage.percentage.child.ChildProcessCoverageReporter;
15-
import datadog.trace.civisibility.coverage.percentage.child.JacocoChildProcessCoverageReporter;
13+
import datadog.trace.civisibility.coverage.report.CoverageProcessor;
14+
import datadog.trace.civisibility.coverage.report.CoverageReportUploader;
15+
import datadog.trace.civisibility.coverage.report.JacocoCoverageProcessor;
16+
import datadog.trace.civisibility.coverage.report.child.ChildProcessCoverageReporter;
17+
import datadog.trace.civisibility.coverage.report.child.JacocoChildProcessCoverageReporter;
1618
import datadog.trace.civisibility.domain.buildsystem.ModuleSignalRouter;
1719
import java.util.Map;
1820

1921
/**
20-
* Services that are related to coverage calculation (both per-test coverage and total coverage
21-
* percentage). The scope is session/module.
22+
* Services that are related to per-test code coverage and coverage report uploads. The scope is
23+
* session/module.
2224
*/
2325
public class CiVisibilityCoverageServices {
2426

2527
/** Services used in the parent process (build system). */
2628
static class Parent {
2729
final ModuleSignalRouter moduleSignalRouter;
28-
final CoverageCalculator.Factory<?> coverageCalculatorFactory;
30+
final CoverageProcessor.Factory<?> coverageProcessorFactory;
2931

3032
Parent(CiVisibilityServices services, CiVisibilityRepoServices repoServices) {
3133
moduleSignalRouter = new ModuleSignalRouter();
32-
coverageCalculatorFactory =
33-
new JacocoCoverageCalculator.Factory(
34+
35+
ExecutionSettings executionSettings =
36+
repoServices.executionSettingsFactory.create(JvmInfo.CURRENT_JVM, null);
37+
CoverageReportUploader coverageReportUploader =
38+
executionSettings.isCodeCoverageReportUploadEnabled()
39+
? new CoverageReportUploader(
40+
services.ciIntake, repoServices.ciTags, services.metricCollector)
41+
: null;
42+
43+
coverageProcessorFactory =
44+
new JacocoCoverageProcessor.Factory(
3445
services.config,
3546
repoServices.repoIndexProvider,
47+
coverageReportUploader,
3648
repoServices.repoRoot,
3749
moduleSignalRouter);
3850
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public class CiVisibilityServices {
6666
final Config config;
6767
final CiVisibilityMetricCollector metricCollector;
6868
final BackendApi backendApi;
69+
final BackendApi ciIntake;
6970
final JvmInfoFactory jvmInfoFactory;
7071
final CiEnvironment environment;
7172
final CIProviderInfoFactory ciProviderInfoFactory;
@@ -85,6 +86,8 @@ public class CiVisibilityServices {
8586
this.metricCollector = metricCollector;
8687
this.backendApi =
8788
new BackendApiFactory(config, sco).createBackendApi(BackendApiFactory.Intake.API);
89+
this.ciIntake =
90+
new BackendApiFactory(config, sco).createBackendApi(BackendApiFactory.Intake.CI_INTAKE);
8891
this.jvmInfoFactory = new CachingJvmInfoFactory(config, new JvmInfoFactoryImpl());
8992
this.gitClientFactory = buildGitClientFactory(config, metricCollector);
9093

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import java.lang.instrument.Instrumentation;
4242
import java.nio.file.Path;
4343
import java.nio.file.Paths;
44+
import java.util.ArrayList;
4445
import java.util.Collection;
4546
import java.util.concurrent.CopyOnWriteArrayList;
4647
import java.util.function.Predicate;
@@ -241,7 +242,7 @@ private static BuildSystemSession.Factory buildSystemSessionFactory(
241242
repoServices.executionSettingsFactory,
242243
signalServer,
243244
repoServices.repoIndexProvider,
244-
coverageServices.coverageCalculatorFactory);
245+
coverageServices.coverageProcessorFactory);
245246
};
246247
}
247248

@@ -266,6 +267,11 @@ private static TestFrameworkSession.Factory childTestFrameworkSessionFactory(
266267
repoServices.sourcePathResolver,
267268
services.linesResolver);
268269

270+
// only add report upload capability for children sessions,
271+
// because report upload is only supported when the build system is instrumented
272+
capabilities = new ArrayList<>(capabilities);
273+
capabilities.add(LibraryCapability.COV_REPORT_UPLOAD);
274+
269275
return new ProxyTestSession(
270276
services.processHierarchy.parentProcessModuleContext,
271277
services.config,

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class CiVisibilitySettings {
1717
false,
1818
false,
1919
false,
20+
false,
2021
EarlyFlakeDetectionSettings.DEFAULT,
2122
TestManagementSettings.DEFAULT,
2223
null);
@@ -28,6 +29,7 @@ public class CiVisibilitySettings {
2829
private final boolean flakyTestRetriesEnabled;
2930
private final boolean impactedTestsDetectionEnabled;
3031
private final boolean knownTestsEnabled;
32+
private final boolean coverageReportUploadEnabled;
3133
private final EarlyFlakeDetectionSettings earlyFlakeDetectionSettings;
3234
private final TestManagementSettings testManagementSettings;
3335
@Nullable private final String defaultBranch;
@@ -40,6 +42,7 @@ public class CiVisibilitySettings {
4042
boolean flakyTestRetriesEnabled,
4143
boolean impactedTestsDetectionEnabled,
4244
boolean knownTestsEnabled,
45+
boolean coverageReportUploadEnabled,
4346
EarlyFlakeDetectionSettings earlyFlakeDetectionSettings,
4447
TestManagementSettings testManagementSettings,
4548
@Nullable String defaultBranch) {
@@ -50,6 +53,7 @@ public class CiVisibilitySettings {
5053
this.flakyTestRetriesEnabled = flakyTestRetriesEnabled;
5154
this.impactedTestsDetectionEnabled = impactedTestsDetectionEnabled;
5255
this.knownTestsEnabled = knownTestsEnabled;
56+
this.coverageReportUploadEnabled = coverageReportUploadEnabled;
5357
this.earlyFlakeDetectionSettings = earlyFlakeDetectionSettings;
5458
this.testManagementSettings = testManagementSettings;
5559
this.defaultBranch = defaultBranch;
@@ -83,6 +87,10 @@ public boolean isKnownTestsEnabled() {
8387
return knownTestsEnabled;
8488
}
8589

90+
public boolean isCoverageReportUploadEnabled() {
91+
return coverageReportUploadEnabled;
92+
}
93+
8694
public EarlyFlakeDetectionSettings getEarlyFlakeDetectionSettings() {
8795
return earlyFlakeDetectionSettings;
8896
}
@@ -112,6 +120,7 @@ public boolean equals(Object o) {
112120
&& flakyTestRetriesEnabled == that.flakyTestRetriesEnabled
113121
&& impactedTestsDetectionEnabled == that.impactedTestsDetectionEnabled
114122
&& knownTestsEnabled == that.knownTestsEnabled
123+
&& coverageReportUploadEnabled == that.coverageReportUploadEnabled
115124
&& Objects.equals(earlyFlakeDetectionSettings, that.earlyFlakeDetectionSettings)
116125
&& Objects.equals(testManagementSettings, that.testManagementSettings)
117126
&& Objects.equals(defaultBranch, that.defaultBranch);
@@ -127,6 +136,7 @@ public int hashCode() {
127136
flakyTestRetriesEnabled,
128137
impactedTestsDetectionEnabled,
129138
knownTestsEnabled,
139+
coverageReportUploadEnabled,
130140
earlyFlakeDetectionSettings,
131141
testManagementSettings,
132142
defaultBranch);
@@ -154,6 +164,7 @@ public CiVisibilitySettings fromJson(Map<String, Object> json) {
154164
getBoolean(json, "flaky_test_retries_enabled", false),
155165
getBoolean(json, "impacted_tests_enabled", false),
156166
getBoolean(json, "known_tests_enabled", false),
167+
getBoolean(json, "coverage_report_upload_enabled", false),
157168
EarlyFlakeDetectionSettings.JsonAdapter.INSTANCE.fromJson(
158169
(Map<String, Object>) json.get("early_flake_detection")),
159170
TestManagementSettings.JsonAdapter.INSTANCE.fromJson(

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public class ExecutionSettings {
2626
false,
2727
false,
2828
false,
29+
false,
2930
EarlyFlakeDetectionSettings.DEFAULT,
3031
TestManagementSettings.DEFAULT,
3132
null,
@@ -43,6 +44,7 @@ public class ExecutionSettings {
4344
private final boolean testSkippingEnabled;
4445
private final boolean flakyTestRetriesEnabled;
4546
private final boolean impactedTestsDetectionEnabled;
47+
private final boolean codeCoverageReportUploadEnabled;
4648
@Nonnull private final EarlyFlakeDetectionSettings earlyFlakeDetectionSettings;
4749
@Nonnull private final TestManagementSettings testManagementSettings;
4850
@Nullable private final String itrCorrelationId;
@@ -58,6 +60,7 @@ public ExecutionSettings(
5860
boolean testSkippingEnabled,
5961
boolean flakyTestRetriesEnabled,
6062
boolean impactedTestsDetectionEnabled,
63+
boolean codeCoverageReportUploadEnabled,
6164
@Nonnull EarlyFlakeDetectionSettings earlyFlakeDetectionSettings,
6265
@Nonnull TestManagementSettings testManagementSettings,
6366
@Nullable String itrCorrelationId,
@@ -74,6 +77,7 @@ public ExecutionSettings(
7477
this.testSkippingEnabled = testSkippingEnabled;
7578
this.flakyTestRetriesEnabled = flakyTestRetriesEnabled;
7679
this.impactedTestsDetectionEnabled = impactedTestsDetectionEnabled;
80+
this.codeCoverageReportUploadEnabled = codeCoverageReportUploadEnabled;
7781
this.earlyFlakeDetectionSettings = earlyFlakeDetectionSettings;
7882
this.testManagementSettings = testManagementSettings;
7983
this.itrCorrelationId = itrCorrelationId;
@@ -110,6 +114,7 @@ private ExecutionSettings(
110114
boolean testSkippingEnabled,
111115
boolean flakyTestRetriesEnabled,
112116
boolean impactedTestsDetectionEnabled,
117+
boolean codeCoverageReportUploadEnabled,
113118
@Nonnull EarlyFlakeDetectionSettings earlyFlakeDetectionSettings,
114119
@Nonnull TestManagementSettings testManagementSettings,
115120
@Nullable String itrCorrelationId,
@@ -123,6 +128,7 @@ private ExecutionSettings(
123128
this.testSkippingEnabled = testSkippingEnabled;
124129
this.flakyTestRetriesEnabled = flakyTestRetriesEnabled;
125130
this.impactedTestsDetectionEnabled = impactedTestsDetectionEnabled;
131+
this.codeCoverageReportUploadEnabled = codeCoverageReportUploadEnabled;
126132
this.earlyFlakeDetectionSettings = earlyFlakeDetectionSettings;
127133
this.testManagementSettings = testManagementSettings;
128134
this.itrCorrelationId = itrCorrelationId;
@@ -157,6 +163,10 @@ public boolean isImpactedTestsDetectionEnabled() {
157163
return impactedTestsDetectionEnabled;
158164
}
159165

166+
public boolean isCodeCoverageReportUploadEnabled() {
167+
return codeCoverageReportUploadEnabled;
168+
}
169+
160170
@Nonnull
161171
public EarlyFlakeDetectionSettings getEarlyFlakeDetectionSettings() {
162172
return earlyFlakeDetectionSettings;
@@ -243,6 +253,7 @@ public boolean equals(Object o) {
243253
&& testSkippingEnabled == that.testSkippingEnabled
244254
&& flakyTestRetriesEnabled == that.flakyTestRetriesEnabled
245255
&& impactedTestsDetectionEnabled == that.impactedTestsDetectionEnabled
256+
&& codeCoverageReportUploadEnabled == that.codeCoverageReportUploadEnabled
246257
&& Objects.equals(earlyFlakeDetectionSettings, that.earlyFlakeDetectionSettings)
247258
&& Objects.equals(testManagementSettings, that.testManagementSettings)
248259
&& Objects.equals(itrCorrelationId, that.itrCorrelationId)
@@ -261,6 +272,7 @@ public int hashCode() {
261272
testSkippingEnabled,
262273
flakyTestRetriesEnabled,
263274
impactedTestsDetectionEnabled,
275+
codeCoverageReportUploadEnabled,
264276
earlyFlakeDetectionSettings,
265277
testManagementSettings,
266278
itrCorrelationId,
@@ -278,6 +290,7 @@ public static class Serializer {
278290
private static final int TEST_SKIPPING_ENABLED_FLAG = 4;
279291
private static final int FLAKY_TEST_RETRIES_ENABLED_FLAG = 8;
280292
private static final int IMPACTED_TESTS_DETECTION_ENABLED_FLAG = 16;
293+
private static final int CODE_COVERAGE_REPORT_UPLOAD_ENABLED_FLAG = 32;
281294

282295
public static ByteBuffer serialize(ExecutionSettings settings) {
283296
datadog.trace.civisibility.ipc.serialization.Serializer s =
@@ -291,6 +304,9 @@ public static ByteBuffer serialize(ExecutionSettings settings) {
291304
| (settings.flakyTestRetriesEnabled ? FLAKY_TEST_RETRIES_ENABLED_FLAG : 0)
292305
| (settings.impactedTestsDetectionEnabled
293306
? IMPACTED_TESTS_DETECTION_ENABLED_FLAG
307+
: 0)
308+
| (settings.codeCoverageReportUploadEnabled
309+
? CODE_COVERAGE_REPORT_UPLOAD_ENABLED_FLAG
294310
: 0));
295311
s.write(flags);
296312

@@ -330,6 +346,8 @@ public static ExecutionSettings deserialize(ByteBuffer buffer) {
330346
boolean testSkippingEnabled = (flags & TEST_SKIPPING_ENABLED_FLAG) != 0;
331347
boolean flakyTestRetriesEnabled = (flags & FLAKY_TEST_RETRIES_ENABLED_FLAG) != 0;
332348
boolean impactedTestsDetectionEnabled = (flags & IMPACTED_TESTS_DETECTION_ENABLED_FLAG) != 0;
349+
boolean codeCoverageReportUploadEnabled =
350+
(flags & CODE_COVERAGE_REPORT_UPLOAD_ENABLED_FLAG) != 0;
333351

334352
EarlyFlakeDetectionSettings earlyFlakeDetectionSettings =
335353
EarlyFlakeDetectionSettings.Serializer.deserialize(buffer);
@@ -372,6 +390,7 @@ public static ExecutionSettings deserialize(ByteBuffer buffer) {
372390
testSkippingEnabled,
373391
flakyTestRetriesEnabled,
374392
impactedTestsDetectionEnabled,
393+
codeCoverageReportUploadEnabled,
375394
earlyFlakeDetectionSettings,
376395
testManagementSettings,
377396
itrCorrelationId,

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ private Map<String, ExecutionSettings> doCreate(
177177
settings,
178178
CiVisibilitySettings::isKnownTestsEnabled,
179179
Config::isCiVisibilityKnownTestsRequestEnabled);
180+
boolean codeCoverageReportUpload =
181+
isFeatureEnabled(
182+
settings,
183+
CiVisibilitySettings::isCoverageReportUploadEnabled,
184+
Config::isCiVisibilityCodeCoverageReportUploadEnabled);
180185

181186
TestManagementSettings testManagementSettings = getTestManagementSettings(settings);
182187

@@ -189,7 +194,8 @@ private Map<String, ExecutionSettings> doCreate(
189194
+ "Impacted tests detection - {},\n"
190195
+ "Known tests marking - {},\n"
191196
+ "Auto test retries - {},\n"
192-
+ "Test Management - {}",
197+
+ "Test Management - {},\n"
198+
+ "Code coverage report upload - {}",
193199
repositoryRoot,
194200
tracerEnvironment.getConfigurations().getRuntimeName(),
195201
tracerEnvironment.getConfigurations().getRuntimeVersion(),
@@ -201,7 +207,8 @@ private Map<String, ExecutionSettings> doCreate(
201207
impactedTestsEnabled,
202208
knownTestsRequest,
203209
flakyTestRetriesEnabled,
204-
testManagementSettings.isEnabled());
210+
testManagementSettings.isEnabled(),
211+
codeCoverageReportUpload);
205212

206213
Future<SkippableTests> skippableTestsFuture =
207214
executor.submit(() -> getSkippableTests(tracerEnvironment, itrEnabled));
@@ -253,6 +260,7 @@ private Map<String, ExecutionSettings> doCreate(
253260
testSkippingEnabled,
254261
flakyTestRetriesEnabled,
255262
impactedTestsEnabled,
263+
codeCoverageReportUpload,
256264
earlyFlakeDetectionEnabled
257265
? settings.getEarlyFlakeDetectionSettings()
258266
: EarlyFlakeDetectionSettings.DEFAULT,

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/coverage/percentage/NoOpCoverageCalculator.java

Lines changed: 0 additions & 34 deletions
This file was deleted.
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
package datadog.trace.civisibility.coverage.percentage;
1+
package datadog.trace.civisibility.coverage.report;
22

33
import datadog.trace.api.civisibility.domain.BuildModuleLayout;
44
import datadog.trace.civisibility.config.ExecutionSettings;
55
import javax.annotation.Nullable;
66

7-
/** Calculates percentage of executable lines that are covered with tests. */
8-
public interface CoverageCalculator {
7+
/** Processes coverage reports. */
8+
public interface CoverageProcessor {
9+
/** Processes previously collected coverage data and returns the percentage of lines covered. */
910
@Nullable
10-
Long calculateCoveragePercentage();
11+
Long processCoverageData();
1112

12-
interface Factory<T extends CoverageCalculator> {
13+
interface Factory<T extends CoverageProcessor> {
1314
T sessionCoverage(long sessionId);
1415

1516
T moduleCoverage(

0 commit comments

Comments
 (0)