Skip to content

Commit ad44687

Browse files
Implement impacted tests detection (#8188)
1 parent 6d86370 commit ad44687

File tree

152 files changed

+4647
-1030
lines changed

Some content is hidden

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

152 files changed

+4647
-1030
lines changed

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

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import datadog.trace.civisibility.ci.CIInfo;
99
import datadog.trace.civisibility.ci.CIProviderInfo;
1010
import datadog.trace.civisibility.ci.CITagsProvider;
11+
import datadog.trace.civisibility.ci.PullRequestInfo;
1112
import datadog.trace.civisibility.codeowners.Codeowners;
1213
import datadog.trace.civisibility.codeowners.CodeownersProvider;
1314
import datadog.trace.civisibility.codeowners.NoCodeowners;
@@ -22,6 +23,7 @@
2223
import datadog.trace.civisibility.git.tree.GitDataApi;
2324
import datadog.trace.civisibility.git.tree.GitDataUploader;
2425
import datadog.trace.civisibility.git.tree.GitDataUploaderImpl;
26+
import datadog.trace.civisibility.git.tree.GitRepoUnshallow;
2527
import datadog.trace.civisibility.ipc.ExecutionSettingsRequest;
2628
import datadog.trace.civisibility.ipc.ExecutionSettingsResponse;
2729
import datadog.trace.civisibility.ipc.SignalClient;
@@ -31,6 +33,8 @@
3133
import datadog.trace.civisibility.source.SourcePathResolver;
3234
import datadog.trace.civisibility.source.index.RepoIndexProvider;
3335
import datadog.trace.civisibility.source.index.RepoIndexSourcePathResolver;
36+
import datadog.trace.util.Strings;
37+
import java.io.File;
3438
import java.nio.file.Path;
3539
import java.nio.file.Paths;
3640
import java.util.Map;
@@ -59,16 +63,26 @@ public class CiVisibilityRepoServices {
5963
ciProvider = ciProviderInfo.getProvider();
6064

6165
CIInfo ciInfo = ciProviderInfo.buildCIInfo();
62-
repoRoot = ciInfo.getNormalizedCiWorkspace();
63-
moduleName = getModuleName(services.config, path, ciInfo);
64-
ciTags = new CITagsProvider().getCiTags(ciInfo);
66+
PullRequestInfo pullRequestInfo = ciProviderInfo.buildPullRequestInfo();
67+
68+
if (pullRequestInfo.isNotEmpty()) {
69+
LOGGER.info("PR detected: {}", pullRequestInfo);
70+
}
71+
72+
repoRoot = appendSlashIfNeeded(getRepoRoot(ciInfo, services.gitClientFactory));
73+
moduleName = getModuleName(services.config, repoRoot, path);
74+
ciTags = new CITagsProvider().getCiTags(ciInfo, pullRequestInfo);
75+
76+
GitClient gitClient = services.gitClientFactory.create(repoRoot);
77+
GitRepoUnshallow gitRepoUnshallow = new GitRepoUnshallow(services.config, gitClient);
6578

6679
gitDataUploader =
6780
buildGitDataUploader(
6881
services.config,
6982
services.metricCollector,
7083
services.gitInfoProvider,
71-
services.gitClientFactory,
84+
gitClient,
85+
gitRepoUnshallow,
7286
services.backendApi,
7387
repoRoot);
7488
repoIndexProvider = services.repoIndexProviderFactory.create(repoRoot);
@@ -84,18 +98,49 @@ public class CiVisibilityRepoServices {
8498
services.config,
8599
services.metricCollector,
86100
services.backendApi,
101+
gitClient,
102+
gitRepoUnshallow,
87103
gitDataUploader,
104+
pullRequestInfo,
88105
repoRoot);
89106
}
90107
}
91108

92-
static String getModuleName(Config config, Path path, CIInfo ciInfo) {
109+
private static String getRepoRoot(CIInfo ciInfo, GitClient.Factory gitClientFactory) {
110+
String ciWorkspace = ciInfo.getNormalizedCiWorkspace();
111+
if (Strings.isNotBlank(ciWorkspace)) {
112+
return ciWorkspace;
113+
114+
} else {
115+
try {
116+
return gitClientFactory.create(".").getRepoRoot();
117+
118+
} catch (InterruptedException e) {
119+
Thread.currentThread().interrupt();
120+
LOGGER.error("Interrupted while getting repo root", e);
121+
return null;
122+
123+
} catch (Exception e) {
124+
LOGGER.error("Error while getting repo root", e);
125+
return null;
126+
}
127+
}
128+
}
129+
130+
private static String appendSlashIfNeeded(String repoRoot) {
131+
if (repoRoot != null && !repoRoot.endsWith(File.separator)) {
132+
return repoRoot + File.separator;
133+
} else {
134+
return repoRoot;
135+
}
136+
}
137+
138+
static String getModuleName(Config config, String repoRoot, Path path) {
93139
// if parent process is instrumented, it will provide build system's module name
94140
String parentModuleName = config.getCiVisibilityModuleName();
95141
if (parentModuleName != null) {
96142
return parentModuleName;
97143
}
98-
String repoRoot = ciInfo.getNormalizedCiWorkspace();
99144
if (repoRoot != null && path.startsWith(repoRoot)) {
100145
String relativePath = Paths.get(repoRoot).relativize(path).toString();
101146
if (!relativePath.isEmpty()) {
@@ -126,7 +171,10 @@ private static ExecutionSettingsFactory buildExecutionSettingsFactory(
126171
Config config,
127172
CiVisibilityMetricCollector metricCollector,
128173
BackendApi backendApi,
174+
GitClient gitClient,
175+
GitRepoUnshallow gitRepoUnshallow,
129176
GitDataUploader gitDataUploader,
177+
PullRequestInfo pullRequestInfo,
130178
String repoRoot) {
131179
ConfigurationApi configurationApi;
132180
if (backendApi == null) {
@@ -138,7 +186,14 @@ private static ExecutionSettingsFactory buildExecutionSettingsFactory(
138186
}
139187

140188
ExecutionSettingsFactoryImpl factory =
141-
new ExecutionSettingsFactoryImpl(config, configurationApi, gitDataUploader, repoRoot);
189+
new ExecutionSettingsFactoryImpl(
190+
config,
191+
configurationApi,
192+
gitClient,
193+
gitRepoUnshallow,
194+
gitDataUploader,
195+
pullRequestInfo,
196+
repoRoot);
142197
if (processHierarchy.isHeadless()) {
143198
return factory;
144199
} else {
@@ -150,7 +205,8 @@ private static GitDataUploader buildGitDataUploader(
150205
Config config,
151206
CiVisibilityMetricCollector metricCollector,
152207
GitInfoProvider gitInfoProvider,
153-
GitClient.Factory gitClientFactory,
208+
GitClient gitClient,
209+
GitRepoUnshallow gitRepoUnshallow,
154210
BackendApi backendApi,
155211
String repoRoot) {
156212
if (!config.isCiVisibilityGitUploadEnabled()) {
@@ -171,9 +227,15 @@ private static GitDataUploader buildGitDataUploader(
171227

172228
String remoteName = config.getCiVisibilityGitRemoteName();
173229
GitDataApi gitDataApi = new GitDataApi(backendApi, metricCollector);
174-
GitClient gitClient = gitClientFactory.create(repoRoot);
175230
return new GitDataUploaderImpl(
176-
config, metricCollector, gitDataApi, gitClient, gitInfoProvider, repoRoot, remoteName);
231+
config,
232+
metricCollector,
233+
gitDataApi,
234+
gitClient,
235+
gitRepoUnshallow,
236+
gitInfoProvider,
237+
repoRoot,
238+
remoteName);
177239
}
178240

179241
private static SourcePathResolver buildSourcePathResolver(

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

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
import datadog.communication.ddagent.SharedCommunicationObjects;
99
import datadog.communication.http.HttpRetryPolicy;
1010
import datadog.communication.http.OkHttpUtils;
11+
import datadog.communication.util.IOUtils;
1112
import datadog.trace.api.Config;
13+
import datadog.trace.api.civisibility.telemetry.CiVisibilityCountMetric;
1214
import datadog.trace.api.civisibility.telemetry.CiVisibilityMetricCollector;
15+
import datadog.trace.api.civisibility.telemetry.tag.Command;
1316
import datadog.trace.api.git.GitInfoProvider;
1417
import datadog.trace.civisibility.ci.CIProviderInfoFactory;
1518
import datadog.trace.civisibility.ci.env.CiEnvironment;
@@ -22,24 +25,28 @@
2225
import datadog.trace.civisibility.git.CIProviderGitInfoBuilder;
2326
import datadog.trace.civisibility.git.GitClientGitInfoBuilder;
2427
import datadog.trace.civisibility.git.tree.GitClient;
28+
import datadog.trace.civisibility.git.tree.NoOpGitClient;
29+
import datadog.trace.civisibility.git.tree.ShellGitClient;
2530
import datadog.trace.civisibility.ipc.SignalClient;
2631
import datadog.trace.civisibility.source.BestEffortLinesResolver;
2732
import datadog.trace.civisibility.source.ByteCodeLinesResolver;
2833
import datadog.trace.civisibility.source.CompilerAidedLinesResolver;
2934
import datadog.trace.civisibility.source.LinesResolver;
3035
import datadog.trace.civisibility.source.index.*;
36+
import datadog.trace.civisibility.utils.ShellCommandExecutor;
37+
import java.io.File;
3138
import java.lang.reflect.Type;
3239
import java.net.InetSocketAddress;
3340
import java.nio.file.FileSystem;
3441
import java.nio.file.FileSystems;
3542
import java.nio.file.Path;
3643
import java.util.Collections;
3744
import java.util.Map;
45+
import javax.annotation.Nonnull;
3846
import javax.annotation.Nullable;
3947
import okhttp3.HttpUrl;
4048
import okhttp3.OkHttpClient;
4149
import okhttp3.Request;
42-
import org.jetbrains.annotations.NotNull;
4350
import org.slf4j.Logger;
4451
import org.slf4j.LoggerFactory;
4552

@@ -78,7 +85,7 @@ public class CiVisibilityServices {
7885
this.backendApi =
7986
new BackendApiFactory(config, sco).createBackendApi(BackendApiFactory.Intake.API);
8087
this.jvmInfoFactory = new CachingJvmInfoFactory(config, new JvmInfoFactoryImpl());
81-
this.gitClientFactory = new GitClient.Factory(config, metricCollector);
88+
this.gitClientFactory = buildGitClientFactory(config, metricCollector);
8289

8390
CiEnvironment environment = buildCiEnvironment(config, sco);
8491
this.ciProviderInfoFactory = new CIProviderInfoFactory(config, environment);
@@ -111,7 +118,30 @@ public class CiVisibilityServices {
111118
}
112119
}
113120

114-
@NotNull
121+
private static GitClient.Factory buildGitClientFactory(
122+
Config config, CiVisibilityMetricCollector metricCollector) {
123+
if (!config.isCiVisibilityGitClientEnabled()) {
124+
return r -> NoOpGitClient.INSTANCE;
125+
}
126+
try {
127+
ShellCommandExecutor shellCommandExecutor =
128+
new ShellCommandExecutor(new File("."), config.getCiVisibilityGitCommandTimeoutMillis());
129+
String gitVersion = shellCommandExecutor.executeCommand(IOUtils::readFully, "git", "version");
130+
logger.debug("Detected git executable version {}", gitVersion);
131+
return new ShellGitClient.Factory(config, metricCollector);
132+
133+
} catch (Exception e) {
134+
metricCollector.add(
135+
CiVisibilityCountMetric.GIT_COMMAND_ERRORS,
136+
1,
137+
Command.OTHER,
138+
ShellCommandExecutor.getExitCode(e));
139+
logger.info("No git executable detected, some features will not be available");
140+
return r -> NoOpGitClient.INSTANCE;
141+
}
142+
}
143+
144+
@Nonnull
115145
private static CiEnvironment buildCiEnvironment(Config config, SharedCommunicationObjects sco) {
116146
String remoteEnvVarsProviderUrl = config.getCiVisibilityRemoteEnvVarsProviderUrl();
117147
if (remoteEnvVarsProviderUrl != null) {

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,11 @@ private static TestFrameworkSession.Factory childTestFrameworkSessionFactory(
238238
new TestDecoratorImpl(component, sessionName, testCommand, repoServices.ciTags);
239239

240240
ExecutionStrategy executionStrategy =
241-
new ExecutionStrategy(services.config, executionSettings);
241+
new ExecutionStrategy(
242+
services.config,
243+
executionSettings,
244+
repoServices.sourcePathResolver,
245+
services.linesResolver);
242246

243247
return new ProxyTestSession(
244248
services.processHierarchy.parentProcessModuleContext,
@@ -268,7 +272,11 @@ private static TestFrameworkSession.Factory headlessTestFrameworkEssionFactory(
268272
new TestDecoratorImpl(component, sessionName, projectName, repoServices.ciTags);
269273

270274
ExecutionStrategy executionStrategy =
271-
new ExecutionStrategy(services.config, executionSettings);
275+
new ExecutionStrategy(
276+
services.config,
277+
executionSettings,
278+
repoServices.sourcePathResolver,
279+
services.linesResolver);
272280
return new HeadlessTestSession(
273281
projectName,
274282
startTime,

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import datadog.trace.api.git.GitInfo;
1010
import datadog.trace.api.git.PersonInfo;
1111
import datadog.trace.civisibility.ci.env.CiEnvironment;
12+
import javax.annotation.Nonnull;
1213

1314
class AppVeyorInfo implements CIProviderInfo {
1415

@@ -79,6 +80,12 @@ public CIInfo buildCIInfo() {
7980
.build();
8081
}
8182

83+
@Nonnull
84+
@Override
85+
public PullRequestInfo buildPullRequestInfo() {
86+
return PullRequestInfo.EMPTY;
87+
}
88+
8289
private String buildGitBranch(final String repoProvider) {
8390
if ("github".equals(repoProvider)) {
8491
String branch = environment.get(APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH);

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import datadog.trace.api.civisibility.telemetry.tag.Provider;
44
import datadog.trace.api.git.GitInfo;
55
import datadog.trace.civisibility.ci.env.CiEnvironment;
6+
import javax.annotation.Nonnull;
67

78
class AwsCodePipelineInfo implements CIProviderInfo {
89

@@ -35,6 +36,12 @@ public CIInfo buildCIInfo() {
3536
.build();
3637
}
3738

39+
@Nonnull
40+
@Override
41+
public PullRequestInfo buildPullRequestInfo() {
42+
return PullRequestInfo.EMPTY;
43+
}
44+
3845
@Override
3946
public Provider getProvider() {
4047
return Provider.AWS;

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import datadog.trace.api.git.GitInfo;
1212
import datadog.trace.api.git.PersonInfo;
1313
import datadog.trace.civisibility.ci.env.CiEnvironment;
14+
import javax.annotation.Nonnull;
1415

1516
class AzurePipelinesInfo implements CIProviderInfo {
1617

@@ -81,6 +82,12 @@ public CIInfo buildCIInfo() {
8182
.build();
8283
}
8384

85+
@Nonnull
86+
@Override
87+
public PullRequestInfo buildPullRequestInfo() {
88+
return PullRequestInfo.EMPTY;
89+
}
90+
8491
private String buildGitBranch() {
8592
String gitBranchOrTag = getGitBranchOrTag();
8693
if (!isTagReference(gitBranchOrTag)) {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import datadog.trace.api.git.GitInfo;
1111
import datadog.trace.civisibility.ci.env.CiEnvironment;
1212
import datadog.trace.util.Strings;
13+
import javax.annotation.Nonnull;
1314

1415
class BitBucketInfo implements CIProviderInfo {
1516

@@ -70,6 +71,12 @@ public CIInfo buildCIInfo() {
7071
.build();
7172
}
7273

74+
@Nonnull
75+
@Override
76+
public PullRequestInfo buildPullRequestInfo() {
77+
return PullRequestInfo.EMPTY;
78+
}
79+
7380
private String buildPipelineUrl(final String repo, final String number) {
7481
return String.format(
7582
"https://bitbucket.org/%s/addon/pipelines/home#!/results/%s", repo, number);

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import datadog.trace.api.git.GitInfo;
1111
import datadog.trace.api.git.PersonInfo;
1212
import datadog.trace.civisibility.ci.env.CiEnvironment;
13+
import javax.annotation.Nonnull;
1314

1415
class BitriseInfo implements CIProviderInfo {
1516

@@ -66,6 +67,12 @@ public CIInfo buildCIInfo() {
6667
.build();
6768
}
6869

70+
@Nonnull
71+
@Override
72+
public PullRequestInfo buildPullRequestInfo() {
73+
return PullRequestInfo.EMPTY;
74+
}
75+
6976
private String buildGitCommit() {
7077
final String fromCommit = environment.get(BITRISE_GIT_PR_COMMIT);
7178
if (fromCommit != null && !fromCommit.isEmpty()) {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import datadog.trace.api.git.GitInfo;
1010
import datadog.trace.api.git.PersonInfo;
1111
import datadog.trace.civisibility.ci.env.CiEnvironment;
12+
import javax.annotation.Nonnull;
1213

1314
class BuddyInfo implements CIProviderInfo {
1415

@@ -58,6 +59,12 @@ public CIInfo buildCIInfo() {
5859
.build();
5960
}
6061

62+
@Nonnull
63+
@Override
64+
public PullRequestInfo buildPullRequestInfo() {
65+
return PullRequestInfo.EMPTY;
66+
}
67+
6168
private String getPipelineId(String pipelineNumber) {
6269
String pipelineId = environment.get(BUDDY_PIPELINE_ID);
6370
if (pipelineId == null) {

0 commit comments

Comments
 (0)