diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/git/CILocalGitInfoBuilder.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/git/CILocalGitInfoBuilder.java index aadaf9968f7..8c2a73ff31d 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/git/CILocalGitInfoBuilder.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/git/CILocalGitInfoBuilder.java @@ -1,5 +1,7 @@ package datadog.trace.civisibility.git; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderDiscrepant; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderExpected; import datadog.trace.api.git.GitInfo; import datadog.trace.api.git.GitInfoBuilder; import datadog.trace.civisibility.git.tree.GitClient; @@ -54,4 +56,14 @@ private Path getGitPath(String repositoryPath) { public int order() { return 2; } + + @Override + public GitProviderExpected providerAsExpected() { + return GitProviderExpected.LOCAL_GIT; + } + + @Override + public GitProviderDiscrepant providerAsDiscrepant() { + return GitProviderDiscrepant.LOCAL_GIT; + } } diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/git/CIProviderGitInfoBuilder.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/git/CIProviderGitInfoBuilder.java index b4a6d6f0d30..cf4d60ce8cf 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/git/CIProviderGitInfoBuilder.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/git/CIProviderGitInfoBuilder.java @@ -1,6 +1,8 @@ package datadog.trace.civisibility.git; import datadog.trace.api.Config; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderDiscrepant; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderExpected; import datadog.trace.api.git.GitInfo; import datadog.trace.api.git.GitInfoBuilder; import datadog.trace.civisibility.ci.CIProviderInfo; @@ -32,4 +34,14 @@ public GitInfo build(@Nullable String repositoryPath) { public int order() { return 1; } + + @Override + public GitProviderExpected providerAsExpected() { + return GitProviderExpected.CI_PROVIDER; + } + + @Override + public GitProviderDiscrepant providerAsDiscrepant() { + return GitProviderDiscrepant.CI_PROVIDER; + } } diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/git/GitClientGitInfoBuilder.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/git/GitClientGitInfoBuilder.java index 6c22c91ff56..7553cf40318 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/git/GitClientGitInfoBuilder.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/git/GitClientGitInfoBuilder.java @@ -1,6 +1,8 @@ package datadog.trace.civisibility.git; import datadog.trace.api.Config; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderDiscrepant; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderExpected; import datadog.trace.api.git.CommitInfo; import datadog.trace.api.git.GitInfo; import datadog.trace.api.git.GitInfoBuilder; @@ -64,4 +66,14 @@ public GitInfo build(@Nullable String repositoryPath) { public int order() { return 3; } + + @Override + public GitProviderExpected providerAsExpected() { + return GitProviderExpected.GIT_CLIENT; + } + + @Override + public GitProviderDiscrepant providerAsDiscrepant() { + return GitProviderDiscrepant.GIT_CLIENT; + } } diff --git a/internal-api/build.gradle b/internal-api/build.gradle index dd5ee2ce0cc..d137456f9fe 100644 --- a/internal-api/build.gradle +++ b/internal-api/build.gradle @@ -139,6 +139,7 @@ excludedClassesCoverage += [ // POJO "datadog.trace.api.git.GitInfo", "datadog.trace.api.git.GitInfoProvider", + "datadog.trace.api.git.GitInfoProvider.ShaDiscrepancy", // POJO "datadog.trace.api.git.PersonInfo", // POJO diff --git a/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/CiVisibilityCountMetric.java b/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/CiVisibilityCountMetric.java index 9bf734eeab6..2d8de535abe 100644 --- a/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/CiVisibilityCountMetric.java +++ b/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/CiVisibilityCountMetric.java @@ -14,6 +14,10 @@ import datadog.trace.api.civisibility.telemetry.tag.ExitCode; import datadog.trace.api.civisibility.telemetry.tag.FailFastTestOrderEnabled; import datadog.trace.api.civisibility.telemetry.tag.FlakyTestRetriesEnabled; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderDiscrepant; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderExpected; +import datadog.trace.api.civisibility.telemetry.tag.GitShaDiscrepancyType; +import datadog.trace.api.civisibility.telemetry.tag.GitShaMatch; import datadog.trace.api.civisibility.telemetry.tag.HasCodeowner; import datadog.trace.api.civisibility.telemetry.tag.HasFailedAllRetries; import datadog.trace.api.civisibility.telemetry.tag.ImpactedTestsDetectionEnabled; @@ -101,6 +105,14 @@ public enum CiVisibilityCountMetric { GIT_COMMAND("git.command", Command.class), /** The number of git commands that errored */ GIT_COMMAND_ERRORS("git.command_errors", Command.class, ExitCode.class), + /** Number of commit sha comparisons and if they matched when building git info for a repo */ + GIT_COMMIT_SHA_MATCH("git.commit_sha_match", GitShaMatch.class), + /** Number of sha mismatches when building git info for a repo */ + GIT_COMMIT_SHA_DISCREPANCY( + "git.commit_sha_discrepancy", + GitProviderExpected.class, + GitProviderDiscrepant.class, + GitShaDiscrepancyType.class), /** The number of requests sent to the search commit endpoint */ GIT_REQUESTS_SEARCH_COMMITS("git_requests.search_commits", RequestCompressed.class), /** The number of search commit requests sent to the endpoint that errored */ diff --git a/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/tag/GitProviderDiscrepant.java b/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/tag/GitProviderDiscrepant.java new file mode 100644 index 00000000000..e356805a255 --- /dev/null +++ b/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/tag/GitProviderDiscrepant.java @@ -0,0 +1,16 @@ +package datadog.trace.api.civisibility.telemetry.tag; + +import datadog.trace.api.civisibility.telemetry.TagValue; + +public enum GitProviderDiscrepant implements TagValue { + USER_SUPPLIED, + CI_PROVIDER, + LOCAL_GIT, + GIT_CLIENT, + EMBEDDED; + + @Override + public String asString() { + return "discrepant_provider:" + name().toLowerCase(); + } +} diff --git a/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/tag/GitProviderExpected.java b/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/tag/GitProviderExpected.java new file mode 100644 index 00000000000..cf2c6e5b9f3 --- /dev/null +++ b/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/tag/GitProviderExpected.java @@ -0,0 +1,16 @@ +package datadog.trace.api.civisibility.telemetry.tag; + +import datadog.trace.api.civisibility.telemetry.TagValue; + +public enum GitProviderExpected implements TagValue { + USER_SUPPLIED, + CI_PROVIDER, + LOCAL_GIT, + GIT_CLIENT, + EMBEDDED; + + @Override + public String asString() { + return "expected_provider:" + name().toLowerCase(); + } +} diff --git a/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/tag/GitShaDiscrepancyType.java b/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/tag/GitShaDiscrepancyType.java new file mode 100644 index 00000000000..2be69a41e08 --- /dev/null +++ b/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/tag/GitShaDiscrepancyType.java @@ -0,0 +1,13 @@ +package datadog.trace.api.civisibility.telemetry.tag; + +import datadog.trace.api.civisibility.telemetry.TagValue; + +public enum GitShaDiscrepancyType implements TagValue { + REPOSITORY_DISCREPANCY, + COMMIT_DISCREPANCY; + + @Override + public String asString() { + return "type:" + name().toLowerCase(); + } +} diff --git a/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/tag/GitShaMatch.java b/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/tag/GitShaMatch.java new file mode 100644 index 00000000000..f5ea9b9a7f8 --- /dev/null +++ b/internal-api/src/main/java/datadog/trace/api/civisibility/telemetry/tag/GitShaMatch.java @@ -0,0 +1,13 @@ +package datadog.trace.api.civisibility.telemetry.tag; + +import datadog.trace.api.civisibility.telemetry.TagValue; + +public enum GitShaMatch implements TagValue { + TRUE, + FALSE; + + @Override + public String asString() { + return "matched:" + name().toLowerCase(); + } +} diff --git a/internal-api/src/main/java/datadog/trace/api/git/EmbeddedGitInfoBuilder.java b/internal-api/src/main/java/datadog/trace/api/git/EmbeddedGitInfoBuilder.java index c388f5471d0..5b0c71ce149 100644 --- a/internal-api/src/main/java/datadog/trace/api/git/EmbeddedGitInfoBuilder.java +++ b/internal-api/src/main/java/datadog/trace/api/git/EmbeddedGitInfoBuilder.java @@ -1,5 +1,7 @@ package datadog.trace.api.git; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderDiscrepant; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderExpected; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; @@ -89,4 +91,14 @@ public GitInfo build(@Nullable String repositoryPath) { public int order() { return Integer.MAX_VALUE; } + + @Override + public GitProviderExpected providerAsExpected() { + return GitProviderExpected.EMBEDDED; + } + + @Override + public GitProviderDiscrepant providerAsDiscrepant() { + return GitProviderDiscrepant.EMBEDDED; + } } diff --git a/internal-api/src/main/java/datadog/trace/api/git/GitInfoBuilder.java b/internal-api/src/main/java/datadog/trace/api/git/GitInfoBuilder.java index a498407532b..7deb594d25b 100644 --- a/internal-api/src/main/java/datadog/trace/api/git/GitInfoBuilder.java +++ b/internal-api/src/main/java/datadog/trace/api/git/GitInfoBuilder.java @@ -1,9 +1,20 @@ package datadog.trace.api.git; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderDiscrepant; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderExpected; import javax.annotation.Nullable; public interface GitInfoBuilder { GitInfo build(@Nullable String repositoryPath); int order(); + + /** + * Used for SHA discrepancies telemetry. Two enums are needed, one for each tag: + * `expected_provider`, `discrepant_provider`. A provider can act as either of them depending on + * the discrepancy found. + */ + GitProviderExpected providerAsExpected(); + + GitProviderDiscrepant providerAsDiscrepant(); } diff --git a/internal-api/src/main/java/datadog/trace/api/git/GitInfoProvider.java b/internal-api/src/main/java/datadog/trace/api/git/GitInfoProvider.java index 02f95eedbb5..1eb767d33c3 100644 --- a/internal-api/src/main/java/datadog/trace/api/git/GitInfoProvider.java +++ b/internal-api/src/main/java/datadog/trace/api/git/GitInfoProvider.java @@ -2,15 +2,24 @@ import datadog.trace.api.cache.DDCache; import datadog.trace.api.cache.DDCaches; +import datadog.trace.api.civisibility.InstrumentationBridge; +import datadog.trace.api.civisibility.telemetry.CiVisibilityCountMetric; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderDiscrepant; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderExpected; +import datadog.trace.api.civisibility.telemetry.tag.GitShaDiscrepancyType; +import datadog.trace.api.civisibility.telemetry.tag.GitShaMatch; import datadog.trace.util.Strings; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; import javax.annotation.Nullable; @@ -51,30 +60,42 @@ public GitInfo getGitInfo(@Nullable String repositoryPath) { private GitInfo buildGitInfo(String repositoryPath) { Evaluator evaluator = new Evaluator(repositoryPath, builders); - return new GitInfo( - evaluator.get( - gi -> GitUtils.filterSensitiveInfo(gi.getRepositoryURL()), - GitInfoProvider::validateGitRemoteUrl), - evaluator.get(GitInfo::getBranch, Strings::isNotBlank), - evaluator.get(GitInfo::getTag, Strings::isNotBlank), - new CommitInfo( - evaluator.get(gi1 -> gi1.getCommit().getSha(), Strings::isNotBlank), - new PersonInfo( + GitInfo gitInfo = + new GitInfo( + evaluator.get( + gi -> GitUtils.filterSensitiveInfo(gi.getRepositoryURL()), + GitInfoProvider::validateGitRemoteUrl), + evaluator.get(GitInfo::getBranch, Strings::isNotBlank), + evaluator.get(GitInfo::getTag, Strings::isNotBlank), + new CommitInfo( + evaluator.get(gi1 -> gi1.getCommit().getSha(), Strings::isNotBlank), + new PersonInfo( + evaluator.getIfCommitShaMatches( + gi -> gi.getCommit().getAuthor().getName(), Strings::isNotBlank), + evaluator.getIfCommitShaMatches( + gi -> gi.getCommit().getAuthor().getEmail(), Strings::isNotBlank), + evaluator.getIfCommitShaMatches( + gi -> gi.getCommit().getAuthor().getIso8601Date(), Strings::isNotBlank)), + new PersonInfo( + evaluator.getIfCommitShaMatches( + gi -> gi.getCommit().getCommitter().getName(), Strings::isNotBlank), + evaluator.getIfCommitShaMatches( + gi -> gi.getCommit().getCommitter().getEmail(), Strings::isNotBlank), + evaluator.getIfCommitShaMatches( + gi -> gi.getCommit().getCommitter().getIso8601Date(), Strings::isNotBlank)), evaluator.getIfCommitShaMatches( - gi -> gi.getCommit().getAuthor().getName(), Strings::isNotBlank), - evaluator.getIfCommitShaMatches( - gi -> gi.getCommit().getAuthor().getEmail(), Strings::isNotBlank), - evaluator.getIfCommitShaMatches( - gi -> gi.getCommit().getAuthor().getIso8601Date(), Strings::isNotBlank)), - new PersonInfo( - evaluator.getIfCommitShaMatches( - gi -> gi.getCommit().getCommitter().getName(), Strings::isNotBlank), - evaluator.getIfCommitShaMatches( - gi -> gi.getCommit().getCommitter().getEmail(), Strings::isNotBlank), - evaluator.getIfCommitShaMatches( - gi -> gi.getCommit().getCommitter().getIso8601Date(), Strings::isNotBlank)), - evaluator.getIfCommitShaMatches( - gi -> gi.getCommit().getFullMessage(), Strings::isNotBlank))); + gi -> gi.getCommit().getFullMessage(), Strings::isNotBlank))); + + InstrumentationBridge.getMetricCollector() + .add( + CiVisibilityCountMetric.GIT_COMMIT_SHA_MATCH, + 1, + evaluator.shaDiscrepancies.isEmpty() ? GitShaMatch.TRUE : GitShaMatch.FALSE); + for (ShaDiscrepancy mismatch : evaluator.shaDiscrepancies) { + mismatch.addTelemetry(); + } + + return gitInfo; } private static boolean validateGitRemoteUrl(String s) { @@ -82,6 +103,46 @@ private static boolean validateGitRemoteUrl(String s) { return Strings.isNotBlank(s) && !s.startsWith("file:"); } + private static final class ShaDiscrepancy { + private final GitProviderExpected expectedGitProvider; + private final GitProviderDiscrepant discrepantGitProvider; + private final GitShaDiscrepancyType discrepancyType; + + private ShaDiscrepancy( + GitProviderExpected expectedGitProvider, + GitProviderDiscrepant discrepantGitProvider, + GitShaDiscrepancyType discrepancyType) { + this.expectedGitProvider = expectedGitProvider; + this.discrepantGitProvider = discrepantGitProvider; + this.discrepancyType = discrepancyType; + } + + private void addTelemetry() { + InstrumentationBridge.getMetricCollector() + .add( + CiVisibilityCountMetric.GIT_COMMIT_SHA_DISCREPANCY, + 1, + expectedGitProvider, + discrepantGitProvider, + discrepancyType); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + ShaDiscrepancy that = (ShaDiscrepancy) obj; + return expectedGitProvider.equals(that.expectedGitProvider) + && discrepantGitProvider.equals(that.discrepantGitProvider) + && discrepancyType.equals(that.discrepancyType); + } + + @Override + public int hashCode() { + return Objects.hash(expectedGitProvider, discrepantGitProvider, discrepancyType); + } + } + /** * Uses provided GitInfoBuilder instances to get GitInfo data. * @@ -95,10 +156,12 @@ private static boolean validateGitRemoteUrl(String s) { private static final class Evaluator { private final String repositoryPath; private final Map infos; + private final Set shaDiscrepancies; private Evaluator(String repositoryPath, Collection builders) { this.repositoryPath = repositoryPath; this.infos = new LinkedHashMap<>(); + this.shaDiscrepancies = new HashSet<>(); for (GitInfoBuilder builder : builders) { infos.put(builder, null); } @@ -121,7 +184,10 @@ private String get( Function function, Predicate validator, boolean checkShaIntegrity) { - String commitSha = null; + String expectedCommitSha = null; + String expectedRepoUrl = null; + GitProviderExpected expectedGitProvider = null; + for (Map.Entry e : infos.entrySet()) { GitInfo info = e.getValue(); if (info == null) { @@ -134,11 +200,22 @@ private String get( CommitInfo currentCommit = info.getCommit(); String currentCommitSha = currentCommit != null ? currentCommit.getSha() : null; if (Strings.isNotBlank(currentCommitSha)) { - if (commitSha == null) { - commitSha = currentCommitSha; - } else if (!commitSha.equals(currentCommitSha)) { + if (expectedCommitSha == null) { + expectedCommitSha = currentCommitSha; + expectedRepoUrl = info.getRepositoryURL(); + expectedGitProvider = e.getKey().providerAsExpected(); + } else if (!expectedCommitSha.equals(currentCommitSha)) { // We already have a commit SHA from source that has higher priority. // Commit SHA from current source is different, so we have to skip it + GitShaDiscrepancyType discrepancyType = GitShaDiscrepancyType.COMMIT_DISCREPANCY; + String repoUrl = info.getRepositoryURL(); + if (expectedRepoUrl != null && repoUrl != null && !repoUrl.equals(expectedRepoUrl)) { + discrepancyType = GitShaDiscrepancyType.REPOSITORY_DISCREPANCY; + } + + shaDiscrepancies.add( + new ShaDiscrepancy( + expectedGitProvider, e.getKey().providerAsDiscrepant(), discrepancyType)); continue; } } diff --git a/internal-api/src/main/java/datadog/trace/api/git/UserSuppliedGitInfoBuilder.java b/internal-api/src/main/java/datadog/trace/api/git/UserSuppliedGitInfoBuilder.java index 31751ff3bb6..215e439562b 100644 --- a/internal-api/src/main/java/datadog/trace/api/git/UserSuppliedGitInfoBuilder.java +++ b/internal-api/src/main/java/datadog/trace/api/git/UserSuppliedGitInfoBuilder.java @@ -1,6 +1,8 @@ package datadog.trace.api.git; import datadog.trace.api.Config; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderDiscrepant; +import datadog.trace.api.civisibility.telemetry.tag.GitProviderExpected; import datadog.trace.api.config.GeneralConfig; import datadog.trace.bootstrap.config.provider.ConfigProvider; import datadog.trace.bootstrap.instrumentation.api.Tags; @@ -106,4 +108,14 @@ public GitInfo build(@Nullable String repositoryPath) { public int order() { return 0; } + + @Override + public GitProviderExpected providerAsExpected() { + return GitProviderExpected.USER_SUPPLIED; + } + + @Override + public GitProviderDiscrepant providerAsDiscrepant() { + return GitProviderDiscrepant.USER_SUPPLIED; + } } diff --git a/internal-api/src/test/groovy/datadog/trace/api/git/GitInfoProviderTest.groovy b/internal-api/src/test/groovy/datadog/trace/api/git/GitInfoProviderTest.groovy index 73219b9ba0d..c6177f24901 100644 --- a/internal-api/src/test/groovy/datadog/trace/api/git/GitInfoProviderTest.groovy +++ b/internal-api/src/test/groovy/datadog/trace/api/git/GitInfoProviderTest.groovy @@ -1,5 +1,12 @@ package datadog.trace.api.git +import datadog.trace.api.civisibility.InstrumentationBridge +import datadog.trace.api.civisibility.telemetry.CiVisibilityCountMetric +import datadog.trace.api.civisibility.telemetry.CiVisibilityMetricCollector +import datadog.trace.api.civisibility.telemetry.tag.GitProviderDiscrepant +import datadog.trace.api.civisibility.telemetry.tag.GitProviderExpected +import datadog.trace.api.civisibility.telemetry.tag.GitShaDiscrepancyType +import datadog.trace.api.civisibility.telemetry.tag.GitShaMatch import spock.lang.Specification class GitInfoProviderTest extends Specification { @@ -238,6 +245,81 @@ class GitInfoProviderTest extends Specification { actualGitInfo.commit.committer.iso8601Date == null } + def "test adds correct telemetry metrics when SHA discrepancies are found"() { + setup: + def metricCollector = Mock(CiVisibilityMetricCollector) + InstrumentationBridge.registerMetricCollector(metricCollector) + + def gitInfoA = new GitInfo("repoUrlA", null, null, + new CommitInfo("shaA", + PersonInfo.NOOP, + PersonInfo.NOOP, + "message" + )) + def gitInfoB = new GitInfo("repoUrlA", null, null, + new CommitInfo("shaB", + new PersonInfo("author name", "author email", "author date"), + new PersonInfo("committer name", "committer email", "committer date"), + "message" + )) + def gitInfoC = new GitInfo("repoUrlB", null, null, + new CommitInfo("shaC", + new PersonInfo("author name", "author email", "author date"), + new PersonInfo("committer name", "committer email", "committer date"), + "message" + )) + + def gitInfoBuilderA = givenABuilderReturning(gitInfoA, 1, GitProviderExpected.CI_PROVIDER, GitProviderDiscrepant.CI_PROVIDER) + def gitInfoBuilderB = givenABuilderReturning(gitInfoB, 2, GitProviderExpected.LOCAL_GIT, GitProviderDiscrepant.LOCAL_GIT) + def gitInfoBuilderC = givenABuilderReturning(gitInfoC, 3, GitProviderExpected.GIT_CLIENT, GitProviderDiscrepant.GIT_CLIENT) + + def gitInfoProvider = new GitInfoProvider() + gitInfoProvider.registerGitInfoBuilder(gitInfoBuilderA) + gitInfoProvider.registerGitInfoBuilder(gitInfoBuilderB) + gitInfoProvider.registerGitInfoBuilder(gitInfoBuilderC) + + when: + gitInfoProvider.getGitInfo(REPO_PATH) + + then: + 1 * metricCollector.add(CiVisibilityCountMetric.GIT_COMMIT_SHA_MATCH, 1, GitShaMatch.FALSE) + 1 * metricCollector.add(CiVisibilityCountMetric.GIT_COMMIT_SHA_DISCREPANCY, 1, GitProviderExpected.CI_PROVIDER, GitProviderDiscrepant.LOCAL_GIT, GitShaDiscrepancyType.COMMIT_DISCREPANCY) + 1 * metricCollector.add(CiVisibilityCountMetric.GIT_COMMIT_SHA_DISCREPANCY, 1, GitProviderExpected.CI_PROVIDER, GitProviderDiscrepant.GIT_CLIENT, GitShaDiscrepancyType.REPOSITORY_DISCREPANCY) + } + + def "test adds correct telemetry metrics when no SHA discrepancies are found"() { + setup: + def metricCollector = Mock(CiVisibilityMetricCollector) + InstrumentationBridge.registerMetricCollector(metricCollector) + + def gitInfoA = new GitInfo("repoUrlA", null, null, + new CommitInfo("shaA", + PersonInfo.NOOP, + PersonInfo.NOOP, + "message" + )) + def gitInfoB = new GitInfo("repoUrlA", null, null, + new CommitInfo("shaA", + new PersonInfo("author name", "author email", "author date"), + new PersonInfo("committer name", "committer email", "committer date"), + "message" + )) + + def gitInfoBuilderA = givenABuilderReturning(gitInfoA, 1, GitProviderExpected.CI_PROVIDER, GitProviderDiscrepant.CI_PROVIDER) + def gitInfoBuilderB = givenABuilderReturning(gitInfoB, 2, GitProviderExpected.LOCAL_GIT, GitProviderDiscrepant.LOCAL_GIT) + + def gitInfoProvider = new GitInfoProvider() + gitInfoProvider.registerGitInfoBuilder(gitInfoBuilderA) + gitInfoProvider.registerGitInfoBuilder(gitInfoBuilderB) + + when: + gitInfoProvider.getGitInfo(REPO_PATH) + + then: + 1 * metricCollector.add(CiVisibilityCountMetric.GIT_COMMIT_SHA_MATCH, 1, GitShaMatch.TRUE) + 0 * metricCollector.add(CiVisibilityCountMetric.GIT_COMMIT_SHA_DISCREPANCY, *_) + } + def "test ignores remote URLs starting with file protocol"() { setup: def gitInfoBuilderA = givenABuilderReturning( @@ -264,9 +346,15 @@ class GitInfoProviderTest extends Specification { } private GitInfoBuilder givenABuilderReturning(GitInfo gitInfo, int order) { + givenABuilderReturning(gitInfo, order, GitProviderExpected.USER_SUPPLIED, GitProviderDiscrepant.USER_SUPPLIED) + } + + private GitInfoBuilder givenABuilderReturning(GitInfo gitInfo, int order, GitProviderExpected expected, GitProviderDiscrepant discrepant) { def gitInfoBuilder = Stub(GitInfoBuilder) gitInfoBuilder.build(REPO_PATH) >> gitInfo gitInfoBuilder.order() >> order + gitInfoBuilder.providerAsExpected() >> expected + gitInfoBuilder.providerAsDiscrepant() >> discrepant gitInfoBuilder } }