From 0176671e9385abf737675d9bc93b4d487a527a5a Mon Sep 17 00:00:00 2001 From: Nikita Tkachenko Date: Wed, 29 Jan 2025 16:29:29 +0100 Subject: [PATCH] Generalize TestRetryPolicy to TestExecutionPolicy --- .../domain/TestFrameworkModule.java | 4 +- .../domain/buildsystem/ProxyTestModule.java | 6 +-- .../domain/headless/HeadlessTestModule.java | 6 +-- .../events/NoOpTestEventsHandler.java | 8 ++-- .../events/TestEventsHandlerImpl.java | 6 +-- .../Regular.java} | 13 +++--- .../RetryUntilSuccessful.java} | 16 ++++--- .../RunNTimes.java} | 14 +++--- .../civisibility/test/ExecutionStrategy.java | 19 ++++---- .../buildsystem/ProxyTestModuleTest.groovy | 6 +-- .../headless/HeadlessTestModuleTest.groovy | 6 +-- .../junit4/CucumberTracingListener.java | 8 ++-- .../junit4/JUnit4CucumberInstrumentation.java | 6 +-- .../Cucumber4ExecutionInstrumentation.java} | 42 ++++++++--------- .../junit4/MUnitInstrumentation.java | 6 +-- .../junit4/MUnitTracingListener.java | 8 ++-- .../MUnitExecutionInstrumentation.java} | 45 ++++++++++--------- .../junit4/JUnit4Instrumentation.java | 6 +-- .../junit4/JUnit4TracingListener.java | 8 ++-- .../FailureSuppressingNotifier.java} | 14 +++--- .../JUnit4ExecutionInstrumentation.java} | 43 +++++++++--------- ...arameterizedExecutionInstrumentation.java} | 14 +++--- ...va => JUnit5ExecutionInstrumentation.java} | 33 +++++++------- ...it5NodeTestTaskContextInstrumentation.java | 3 +- ...etryContext.java => ExecutionContext.java} | 20 ++++----- ...va => KarateExecutionInstrumentation.java} | 45 ++++++++++--------- .../scalatest/DatadogReporter.java | 6 +-- .../instrumentation/scalatest/RunContext.java | 23 +++++----- .../scalatest/ScalatestInstrumentation.java | 2 +- .../ScalatestExecutionInstrumentation.java} | 20 +++++---- .../SuppressedTestFailedException.java | 2 +- .../TestExecutionWrapper.java | 14 +++--- .../testng/TestNGInstrumentation.java | 8 ++-- .../testng/TracingListener.java | 2 +- .../{retry => execution}/RetryAnalyzer.java | 19 ++++---- .../RetryAnnotationTransformer.java | 2 +- ...va => TestNGExecutionInstrumentation.java} | 15 ++++--- .../main/java/datadog/trace/api/Config.java | 2 +- .../events/TestEventsHandler.java | 4 +- .../execution/TestExecutionPolicy.java | 35 +++++++++++++++ .../civisibility/retry/TestRetryPolicy.java | 29 ------------ 41 files changed, 309 insertions(+), 279 deletions(-) rename dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/{retry/NeverRetry.java => execution/Regular.java} (54%) rename dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/{retry/RetryIfFailed.java => execution/RetryUntilSuccessful.java} (71%) rename dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/{retry/RetryNTimes.java => execution/RunNTimes.java} (71%) rename dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/{retry/Cucumber4RetryInstrumentation.java => execution/Cucumber4ExecutionInstrumentation.java} (74%) rename dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/{retry/MUnitRetryInstrumentation.java => execution/MUnitExecutionInstrumentation.java} (72%) rename dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/{retry/RetryAwareNotifier.java => execution/FailureSuppressingNotifier.java} (74%) rename dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/{retry/JUnit4RetryInstrumentation.java => execution/JUnit4ExecutionInstrumentation.java} (73%) rename dd-java-agent/instrumentation/junit-5.3/spock-junit-5/src/main/java/datadog/trace/instrumentation/junit5/retry/{JUnit5SpockParameterizedRetryInstrumentation.java => JUnit5SpockParameterizedExecutionInstrumentation.java} (82%) rename dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/retry/{JUnit5RetryInstrumentation.java => JUnit5ExecutionInstrumentation.java} (87%) rename dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/{RetryContext.java => ExecutionContext.java} (60%) rename dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/{KarateRetryInstrumentation.java => KarateExecutionInstrumentation.java} (70%) rename dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/{retry/ScalatestRetryInstrumentation.java => execution/ScalatestExecutionInstrumentation.java} (86%) rename dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/{retry => execution}/SuppressedTestFailedException.java (82%) rename dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/{retry => execution}/TestExecutionWrapper.java (73%) rename dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/{retry => execution}/RetryAnalyzer.java (61%) rename dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/{retry => execution}/RetryAnnotationTransformer.java (92%) rename dd-java-agent/instrumentation/testng/testng-7/src/main/java/datadog/trace/instrumentation/testng7/{TestNGRetryInstrumentation.java => TestNGExecutionInstrumentation.java} (81%) create mode 100644 internal-api/src/main/java/datadog/trace/api/civisibility/execution/TestExecutionPolicy.java delete mode 100644 internal-api/src/main/java/datadog/trace/api/civisibility/retry/TestRetryPolicy.java diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/TestFrameworkModule.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/TestFrameworkModule.java index 9055ceaf3aa..3a5d64b3b28 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/TestFrameworkModule.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/TestFrameworkModule.java @@ -2,7 +2,7 @@ import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.SkipReason; import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation; import javax.annotation.Nonnull; @@ -41,7 +41,7 @@ TestSuiteImpl testSuiteStart( SkipReason skipReason(TestIdentifier test); @Nonnull - TestRetryPolicy retryPolicy(TestIdentifier test, TestSourceData testSource); + TestExecutionPolicy executionPolicy(TestIdentifier test, TestSourceData testSource); void end(Long startTime); } diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/buildsystem/ProxyTestModule.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/buildsystem/ProxyTestModule.java index 9506402afb7..4d49b9b0423 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/buildsystem/ProxyTestModule.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/buildsystem/ProxyTestModule.java @@ -5,7 +5,7 @@ import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; import datadog.trace.api.civisibility.coverage.CoverageStore; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.CiVisibilityMetricCollector; import datadog.trace.api.civisibility.telemetry.tag.SkipReason; import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation; @@ -111,8 +111,8 @@ public SkipReason skipReason(TestIdentifier test) { @Override @Nonnull - public TestRetryPolicy retryPolicy(TestIdentifier test, TestSourceData testSource) { - return executionStrategy.retryPolicy(test, testSource); + public TestExecutionPolicy executionPolicy(TestIdentifier test, TestSourceData testSource) { + return executionStrategy.executionPolicy(test, testSource); } @Override diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/headless/HeadlessTestModule.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/headless/HeadlessTestModule.java index 83302b8fc31..97687b3ca30 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/headless/HeadlessTestModule.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/domain/headless/HeadlessTestModule.java @@ -6,7 +6,7 @@ import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; import datadog.trace.api.civisibility.coverage.CoverageStore; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.CiVisibilityMetricCollector; import datadog.trace.api.civisibility.telemetry.tag.SkipReason; import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation; @@ -96,8 +96,8 @@ public SkipReason skipReason(TestIdentifier test) { @Override @Nonnull - public TestRetryPolicy retryPolicy(TestIdentifier test, TestSourceData testSource) { - return executionStrategy.retryPolicy(test, testSource); + public TestExecutionPolicy executionPolicy(TestIdentifier test, TestSourceData testSource) { + return executionStrategy.executionPolicy(test, testSource); } @Override diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/events/NoOpTestEventsHandler.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/events/NoOpTestEventsHandler.java index f7c7598a731..b2a73bcab16 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/events/NoOpTestEventsHandler.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/events/NoOpTestEventsHandler.java @@ -5,12 +5,12 @@ import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; import datadog.trace.api.civisibility.events.TestEventsHandler; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.RetryReason; import datadog.trace.api.civisibility.telemetry.tag.SkipReason; import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation; import datadog.trace.bootstrap.ContextStore; -import datadog.trace.civisibility.retry.NeverRetry; +import datadog.trace.civisibility.execution.Regular; import java.util.Collection; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -99,8 +99,8 @@ public SkipReason skipReason(TestIdentifier test) { @NotNull @Override - public TestRetryPolicy retryPolicy(TestIdentifier test, TestSourceData source) { - return NeverRetry.INSTANCE; + public TestExecutionPolicy executionPolicy(TestIdentifier test, TestSourceData source) { + return Regular.INSTANCE; } @Override diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/events/TestEventsHandlerImpl.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/events/TestEventsHandlerImpl.java index c0b9d2b73e4..bb040afd7e4 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/events/TestEventsHandlerImpl.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/events/TestEventsHandlerImpl.java @@ -8,7 +8,7 @@ import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; import datadog.trace.api.civisibility.events.TestEventsHandler; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.CiVisibilityCountMetric; import datadog.trace.api.civisibility.telemetry.CiVisibilityMetricCollector; import datadog.trace.api.civisibility.telemetry.tag.EventType; @@ -264,8 +264,8 @@ public void onTestIgnore( @Override @Nonnull - public TestRetryPolicy retryPolicy(TestIdentifier test, TestSourceData testSource) { - return testModule.retryPolicy(test, testSource); + public TestExecutionPolicy executionPolicy(TestIdentifier test, TestSourceData testSource) { + return testModule.executionPolicy(test, testSource); } @Override diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/retry/NeverRetry.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/execution/Regular.java similarity index 54% rename from dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/retry/NeverRetry.java rename to dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/execution/Regular.java index 6d7c9de940c..320170d7ba6 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/retry/NeverRetry.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/execution/Regular.java @@ -1,17 +1,18 @@ -package datadog.trace.civisibility.retry; +package datadog.trace.civisibility.execution; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.RetryReason; import org.jetbrains.annotations.Nullable; -public class NeverRetry implements TestRetryPolicy { +/** Regular test case execution with no alterations. */ +public class Regular implements TestExecutionPolicy { - public static final TestRetryPolicy INSTANCE = new NeverRetry(); + public static final TestExecutionPolicy INSTANCE = new Regular(); - private NeverRetry() {} + private Regular() {} @Override - public boolean retriesLeft() { + public boolean applicable() { return false; } diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/retry/RetryIfFailed.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/execution/RetryUntilSuccessful.java similarity index 71% rename from dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/retry/RetryIfFailed.java rename to dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/execution/RetryUntilSuccessful.java index 8d443ecbbc5..9b3b256bf30 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/retry/RetryIfFailed.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/execution/RetryUntilSuccessful.java @@ -1,12 +1,12 @@ -package datadog.trace.civisibility.retry; +package datadog.trace.civisibility.execution; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.RetryReason; import java.util.concurrent.atomic.AtomicInteger; import org.jetbrains.annotations.Nullable; /** Retries a test case if it failed, up to a maximum number of times. */ -public class RetryIfFailed implements TestRetryPolicy { +public class RetryUntilSuccessful implements TestExecutionPolicy { private final int maxExecutions; private int executions; @@ -14,22 +14,24 @@ public class RetryIfFailed implements TestRetryPolicy { /** Total execution counter that is shared by all retry policies */ private final AtomicInteger totalExecutions; - public RetryIfFailed(int maxExecutions, AtomicInteger totalExecutions) { + public RetryUntilSuccessful(int maxExecutions, AtomicInteger totalExecutions) { this.maxExecutions = maxExecutions; this.totalExecutions = totalExecutions; this.executions = 0; } @Override - public boolean retriesLeft() { + public boolean applicable() { + // the last execution is not altered by the policy + // (no retries, no exceptions suppressing) return executions < maxExecutions - 1; } @Override public boolean suppressFailures() { - // if this isn't the last attempt, + // if this isn't the last execution, // possible failures should be suppressed - return retriesLeft(); + return applicable(); } @Override diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/retry/RetryNTimes.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/execution/RunNTimes.java similarity index 71% rename from dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/retry/RetryNTimes.java rename to dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/execution/RunNTimes.java index f61d775b833..a79e43c8786 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/retry/RetryNTimes.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/execution/RunNTimes.java @@ -1,25 +1,27 @@ -package datadog.trace.civisibility.retry; +package datadog.trace.civisibility.execution; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.RetryReason; import datadog.trace.civisibility.config.EarlyFlakeDetectionSettings; import org.jetbrains.annotations.Nullable; -/** Retries a test case N times (N depends on test duration) regardless of success or failure. */ -public class RetryNTimes implements TestRetryPolicy { +/** Runs a test case N times (N depends on test duration) regardless of success or failure. */ +public class RunNTimes implements TestExecutionPolicy { private final EarlyFlakeDetectionSettings earlyFlakeDetectionSettings; private int executions; private int maxExecutions; - public RetryNTimes(EarlyFlakeDetectionSettings earlyFlakeDetectionSettings) { + public RunNTimes(EarlyFlakeDetectionSettings earlyFlakeDetectionSettings) { this.earlyFlakeDetectionSettings = earlyFlakeDetectionSettings; this.executions = 0; this.maxExecutions = earlyFlakeDetectionSettings.getExecutions(0); } @Override - public boolean retriesLeft() { + public boolean applicable() { + // the last execution is not altered by the policy + // (no retries, no exceptions suppressing) return executions < maxExecutions - 1; } diff --git a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/test/ExecutionStrategy.java b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/test/ExecutionStrategy.java index 52ef2a6a713..42b33ed921e 100644 --- a/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/test/ExecutionStrategy.java +++ b/dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/test/ExecutionStrategy.java @@ -4,13 +4,13 @@ import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestMetadata; import datadog.trace.api.civisibility.config.TestSourceData; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.SkipReason; import datadog.trace.civisibility.config.EarlyFlakeDetectionSettings; import datadog.trace.civisibility.config.ExecutionSettings; -import datadog.trace.civisibility.retry.NeverRetry; -import datadog.trace.civisibility.retry.RetryIfFailed; -import datadog.trace.civisibility.retry.RetryNTimes; +import datadog.trace.civisibility.execution.Regular; +import datadog.trace.civisibility.execution.RetryUntilSuccessful; +import datadog.trace.civisibility.execution.RunNTimes; import datadog.trace.civisibility.source.LinesResolver; import datadog.trace.civisibility.source.SourcePathResolver; import java.lang.reflect.Method; @@ -80,9 +80,9 @@ public SkipReason skipReason(TestIdentifier test) { } @Nonnull - public TestRetryPolicy retryPolicy(TestIdentifier test, TestSourceData testSource) { + public TestExecutionPolicy executionPolicy(TestIdentifier test, TestSourceData testSource) { if (test == null) { - return NeverRetry.INSTANCE; + return Regular.INSTANCE; } EarlyFlakeDetectionSettings efdSettings = executionSettings.getEarlyFlakeDetectionSettings(); @@ -91,7 +91,7 @@ public TestRetryPolicy retryPolicy(TestIdentifier test, TestSourceData testSourc // check-then-act with "earlyFlakeDetectionsUsed" is not atomic here, // but we don't care if we go "a bit" over the limit, it does not have to be precise earlyFlakeDetectionsUsed.incrementAndGet(); - return new RetryNTimes(efdSettings); + return new RunNTimes(efdSettings); } } @@ -101,10 +101,11 @@ public TestRetryPolicy retryPolicy(TestIdentifier test, TestSourceData testSourc && autoRetriesUsed.get() < config.getCiVisibilityTotalFlakyRetryCount()) { // check-then-act with "autoRetriesUsed" is not atomic here, // but we don't care if we go "a bit" over the limit, it does not have to be precise - return new RetryIfFailed(config.getCiVisibilityFlakyRetryCount(), autoRetriesUsed); + return new RetryUntilSuccessful(config.getCiVisibilityFlakyRetryCount(), autoRetriesUsed); } } - return NeverRetry.INSTANCE; + + return Regular.INSTANCE; } public boolean isEFDLimitReached() { diff --git a/dd-java-agent/agent-ci-visibility/src/test/groovy/datadog/trace/civisibility/domain/buildsystem/ProxyTestModuleTest.groovy b/dd-java-agent/agent-ci-visibility/src/test/groovy/datadog/trace/civisibility/domain/buildsystem/ProxyTestModuleTest.groovy index 5e6f4bdef74..812addd0b4d 100644 --- a/dd-java-agent/agent-ci-visibility/src/test/groovy/datadog/trace/civisibility/domain/buildsystem/ProxyTestModuleTest.groovy +++ b/dd-java-agent/agent-ci-visibility/src/test/groovy/datadog/trace/civisibility/domain/buildsystem/ProxyTestModuleTest.groovy @@ -56,21 +56,21 @@ class ProxyTestModuleTest extends DDSpecification { ) when: - def retryPolicy1 = proxyTestModule.retryPolicy(new TestIdentifier("suite", "test-1", null), TestSourceData.UNKNOWN) + def retryPolicy1 = proxyTestModule.executionPolicy(new TestIdentifier("suite", "test-1", null), TestSourceData.UNKNOWN) then: retryPolicy1.retry(false, 1L) // 2nd test execution, 1st retry globally !retryPolicy1.retry(false, 1L) // asking for 3rd test execution - local limit reached when: - def retryPolicy2 = proxyTestModule.retryPolicy(new TestIdentifier("suite", "test-2", null), TestSourceData.UNKNOWN) + def retryPolicy2 = proxyTestModule.executionPolicy(new TestIdentifier("suite", "test-2", null), TestSourceData.UNKNOWN) then: retryPolicy2.retry(false, 1L) // 2nd test execution, 2nd retry globally (since previous test was retried too) !retryPolicy2.retry(false, 1L) // asking for 3rd test execution - local limit reached when: - def retryPolicy3 = proxyTestModule.retryPolicy(new TestIdentifier("suite", "test-3", null), TestSourceData.UNKNOWN) + def retryPolicy3 = proxyTestModule.executionPolicy(new TestIdentifier("suite", "test-3", null), TestSourceData.UNKNOWN) then: !retryPolicy3.retry(false, 1L) // asking for 3rd retry globally - global limit reached diff --git a/dd-java-agent/agent-ci-visibility/src/test/groovy/datadog/trace/civisibility/domain/headless/HeadlessTestModuleTest.groovy b/dd-java-agent/agent-ci-visibility/src/test/groovy/datadog/trace/civisibility/domain/headless/HeadlessTestModuleTest.groovy index 4daf9dc7c44..ad28f394d12 100644 --- a/dd-java-agent/agent-ci-visibility/src/test/groovy/datadog/trace/civisibility/domain/headless/HeadlessTestModuleTest.groovy +++ b/dd-java-agent/agent-ci-visibility/src/test/groovy/datadog/trace/civisibility/domain/headless/HeadlessTestModuleTest.groovy @@ -48,21 +48,21 @@ class HeadlessTestModuleTest extends DDSpecification { ) when: - def retryPolicy1 = headlessTestModule.retryPolicy(new TestIdentifier("suite", "test-1", null), TestSourceData.UNKNOWN) + def retryPolicy1 = headlessTestModule.executionPolicy(new TestIdentifier("suite", "test-1", null), TestSourceData.UNKNOWN) then: retryPolicy1.retry(false, 1L) // 2nd test execution, 1st retry globally !retryPolicy1.retry(false, 1L) // asking for 3rd test execution - local limit reached when: - def retryPolicy2 = headlessTestModule.retryPolicy(new TestIdentifier("suite", "test-2", null), TestSourceData.UNKNOWN) + def retryPolicy2 = headlessTestModule.executionPolicy(new TestIdentifier("suite", "test-2", null), TestSourceData.UNKNOWN) then: retryPolicy2.retry(false, 1L) // 2nd test execution, 2nd retry globally (since previous test was retried too) !retryPolicy2.retry(false, 1L) // asking for 3rd test execution - local limit reached when: - def retryPolicy3 = headlessTestModule.retryPolicy(new TestIdentifier("suite", "test-3", null), TestSourceData.UNKNOWN) + def retryPolicy3 = headlessTestModule.executionPolicy(new TestIdentifier("suite", "test-3", null), TestSourceData.UNKNOWN) then: !retryPolicy3.retry(false, 1L) // asking for 3rd retry globally - global limit reached diff --git a/dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/CucumberTracingListener.java b/dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/CucumberTracingListener.java index d85e5c0670b..9d80fc40828 100644 --- a/dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/CucumberTracingListener.java +++ b/dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/CucumberTracingListener.java @@ -4,7 +4,7 @@ import datadog.trace.api.civisibility.coverage.CoveragePerTestBridge; import datadog.trace.api.civisibility.events.TestDescriptor; import datadog.trace.api.civisibility.events.TestSuiteDescriptor; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation; import datadog.trace.bootstrap.ContextStore; import io.cucumber.core.gherkin.Pickle; @@ -29,11 +29,11 @@ public class CucumberTracingListener extends TracingListener { public static final String FRAMEWORK_NAME = "cucumber"; public static final String FRAMEWORK_VERSION = CucumberUtils.getVersion(); - private final ContextStore retryPolicies; + private final ContextStore retryPolicies; private final Map pickleById; public CucumberTracingListener( - ContextStore retryPolicies, + ContextStore retryPolicies, List> featureRunners) { this.retryPolicies = retryPolicies; pickleById = CucumberUtils.getPicklesById(featureRunners); @@ -71,7 +71,7 @@ public void testStarted(final Description description) { String testName = CucumberUtils.getTestNameForScenario(description); List categories = getCategories(description); - TestRetryPolicy retryPolicy = retryPolicies.get(description); + TestExecutionPolicy retryPolicy = retryPolicies.get(description); TestEventsHandlerHolder.TEST_EVENTS_HANDLER.onTestStart( new TestSuiteDescriptor(testSuiteName, null), CucumberUtils.toTestDescriptor(description), diff --git a/dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/JUnit4CucumberInstrumentation.java b/dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/JUnit4CucumberInstrumentation.java index 55ab788ee60..6101c51f18c 100644 --- a/dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/JUnit4CucumberInstrumentation.java +++ b/dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/JUnit4CucumberInstrumentation.java @@ -7,7 +7,7 @@ import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.agent.tooling.muzzle.Reference; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.bootstrap.InstrumentationContext; import java.util.Collections; import java.util.List; @@ -46,7 +46,7 @@ public String[] helperClassNames() { @Override public Map contextStore() { return Collections.singletonMap( - "org.junit.runner.Description", TestRetryPolicy.class.getName()); + "org.junit.runner.Description", TestExecutionPolicy.class.getName()); } @Override @@ -84,7 +84,7 @@ public static void addTracingListener( replacedNotifier.addListener( new CucumberTracingListener( - InstrumentationContext.get(Description.class, TestRetryPolicy.class), children)); + InstrumentationContext.get(Description.class, TestExecutionPolicy.class), children)); runNotifier = replacedNotifier; } } diff --git a/dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/retry/Cucumber4RetryInstrumentation.java b/dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/execution/Cucumber4ExecutionInstrumentation.java similarity index 74% rename from dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/retry/Cucumber4RetryInstrumentation.java rename to dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/execution/Cucumber4ExecutionInstrumentation.java index 5c85c9117ae..f7f673aa04d 100644 --- a/dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/retry/Cucumber4RetryInstrumentation.java +++ b/dd-java-agent/instrumentation/junit-4.10/cucumber-junit-4/src/main/java/datadog/trace/instrumentation/junit4/execution/Cucumber4ExecutionInstrumentation.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.junit4.retry; +package datadog.trace.instrumentation.junit4.execution; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; @@ -10,7 +10,7 @@ import datadog.trace.api.Config; import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.instrumentation.junit4.CucumberUtils; import datadog.trace.instrumentation.junit4.JUnit4Utils; @@ -27,18 +27,19 @@ import org.junit.runners.ParentRunner; @AutoService(InstrumenterModule.class) -public class Cucumber4RetryInstrumentation extends InstrumenterModule.CiVisibility +public class Cucumber4ExecutionInstrumentation extends InstrumenterModule.CiVisibility implements Instrumenter.ForSingleType, Instrumenter.HasMethodAdvice { private final String parentPackageName = Strings.getPackageName(JUnit4Utils.class.getName()); - public Cucumber4RetryInstrumentation() { + public Cucumber4ExecutionInstrumentation() { super("ci-visibility", "junit-4", "junit-4-cucumber", "test-retry"); } @Override public boolean isApplicable(Set enabledSystems) { - return super.isApplicable(enabledSystems) && Config.get().isCiVisibilityTestRetryEnabled(); + return super.isApplicable(enabledSystems) + && Config.get().isCiVisibilityExecutionPoliciesEnabled(); } @Override @@ -54,14 +55,14 @@ public String[] helperClassNames() { parentPackageName + ".JUnit4Utils", parentPackageName + ".TracingListener", parentPackageName + ".TestEventsHandlerHolder", - packageName + ".RetryAwareNotifier", + packageName + ".FailureSuppressingNotifier", }; } @Override public Map contextStore() { return Collections.singletonMap( - "org.junit.runner.Description", TestRetryPolicy.class.getName()); + "org.junit.runner.Description", TestExecutionPolicy.class.getName()); } @Override @@ -75,49 +76,50 @@ public void methodAdvice(MethodTransformer transformer) { named("runChild") .and(takesArgument(0, named("io.cucumber.junit.PickleRunners$PickleRunner"))) .and(takesArgument(1, named("org.junit.runner.notification.RunNotifier"))), - Cucumber4RetryInstrumentation.class.getName() + "$RetryAdvice"); + Cucumber4ExecutionInstrumentation.class.getName() + "$ExecutionAdvice"); } - public static class RetryAdvice { + public static class ExecutionAdvice { @SuppressWarnings("bytebuddy-exception-suppression") @SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL") @Advice.OnMethodEnter(skipOn = Boolean.class) - public static Boolean retryIfNeeded( + public static Boolean execute( @Advice.SelfCallHandle(bound = false) MethodHandle runPickle, @Advice.This ParentRunner /* io.cucumber.junit.FeatureRunner */ featureRunner, @Advice.Argument(0) Object /* io.cucumber.junit.PickleRunners.PickleRunner */ pickleRunner, @Advice.Argument(1) RunNotifier notifier) { - if (notifier instanceof RetryAwareNotifier) { + if (notifier instanceof FailureSuppressingNotifier) { // notifier already wrapped, run original method return null; } Description description = CucumberUtils.getPickleRunnerDescription(pickleRunner); TestIdentifier testIdentifier = CucumberUtils.toTestIdentifier(description); - TestRetryPolicy retryPolicy = - TestEventsHandlerHolder.TEST_EVENTS_HANDLER.retryPolicy( + TestExecutionPolicy executionPolicy = + TestEventsHandlerHolder.TEST_EVENTS_HANDLER.executionPolicy( testIdentifier, TestSourceData.UNKNOWN); - if (!retryPolicy.retriesLeft()) { + if (!executionPolicy.applicable()) { // retries not applicable, run original method return null; } - InstrumentationContext.get(Description.class, TestRetryPolicy.class) - .put(description, retryPolicy); + InstrumentationContext.get(Description.class, TestExecutionPolicy.class) + .put(description, executionPolicy); - RetryAwareNotifier retryAwareNotifier = new RetryAwareNotifier(retryPolicy, notifier); + FailureSuppressingNotifier failureSuppressingNotifier = + new FailureSuppressingNotifier(executionPolicy, notifier); long duration; boolean testFailed; do { long startTimestamp = System.currentTimeMillis(); try { - runPickle.invokeWithArguments(featureRunner, pickleRunner, retryAwareNotifier); - testFailed = retryAwareNotifier.getAndResetFailedFlag(); + runPickle.invokeWithArguments(featureRunner, pickleRunner, failureSuppressingNotifier); + testFailed = failureSuppressingNotifier.getAndResetFailedFlag(); } catch (Throwable throwable) { testFailed = true; } duration = System.currentTimeMillis() - startTimestamp; - } while (retryPolicy.retry(!testFailed, duration)); + } while (executionPolicy.retry(!testFailed, duration)); // skip original method return Boolean.TRUE; diff --git a/dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/MUnitInstrumentation.java b/dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/MUnitInstrumentation.java index 4d392d324f7..26329630dcd 100644 --- a/dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/MUnitInstrumentation.java +++ b/dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/MUnitInstrumentation.java @@ -6,7 +6,7 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.bootstrap.InstrumentationContext; import java.util.Collections; import java.util.List; @@ -44,7 +44,7 @@ public String[] helperClassNames() { @Override public Map contextStore() { return Collections.singletonMap( - "org.junit.runner.Description", TestRetryPolicy.class.getName()); + "org.junit.runner.Description", TestExecutionPolicy.class.getName()); } @Override @@ -75,7 +75,7 @@ public static void addTracingListener( replacedNotifier.addListener( new MUnitTracingListener( - InstrumentationContext.get(Description.class, TestRetryPolicy.class))); + InstrumentationContext.get(Description.class, TestExecutionPolicy.class))); runNotifier = replacedNotifier; } } diff --git a/dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/MUnitTracingListener.java b/dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/MUnitTracingListener.java index 5a802139cf3..49a785d126c 100644 --- a/dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/MUnitTracingListener.java +++ b/dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/MUnitTracingListener.java @@ -2,7 +2,7 @@ import datadog.trace.api.civisibility.events.TestDescriptor; import datadog.trace.api.civisibility.events.TestSuiteDescriptor; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation; import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.instrumentation.api.AgentScope; @@ -23,9 +23,9 @@ public class MUnitTracingListener extends TracingListener { public static final String FRAMEWORK_NAME = "munit"; public static final String FRAMEWORK_VERSION = getVersion(); - private final ContextStore retryPolicies; + private final ContextStore retryPolicies; - public MUnitTracingListener(ContextStore retryPolicies) { + public MUnitTracingListener(ContextStore retryPolicies) { this.retryPolicies = retryPolicies; } @@ -76,7 +76,7 @@ public void testStarted(final Description description) { TestDescriptor testDescriptor = MUnitUtils.toTestDescriptor(description); String testName = description.getMethodName(); List categories = getCategories(description); - TestRetryPolicy retryPolicy = retryPolicies.get(description); + TestExecutionPolicy retryPolicy = retryPolicies.get(description); TestEventsHandlerHolder.TEST_EVENTS_HANDLER.onTestStart( suiteDescriptor, testDescriptor, diff --git a/dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/retry/MUnitRetryInstrumentation.java b/dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/execution/MUnitExecutionInstrumentation.java similarity index 72% rename from dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/retry/MUnitRetryInstrumentation.java rename to dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/execution/MUnitExecutionInstrumentation.java index 36b733fbf6a..7d929694c75 100644 --- a/dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/retry/MUnitRetryInstrumentation.java +++ b/dd-java-agent/instrumentation/junit-4.10/munit-junit-4/src/main/java/datadog/trace/instrumentation/junit4/execution/MUnitExecutionInstrumentation.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.junit4.retry; +package datadog.trace.instrumentation.junit4.execution; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; @@ -9,7 +9,7 @@ import datadog.trace.api.Config; import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.instrumentation.junit4.JUnit4Utils; import datadog.trace.instrumentation.junit4.MUnitUtils; @@ -27,18 +27,19 @@ import scala.concurrent.Future; @AutoService(InstrumenterModule.class) -public class MUnitRetryInstrumentation extends InstrumenterModule.CiVisibility +public class MUnitExecutionInstrumentation extends InstrumenterModule.CiVisibility implements Instrumenter.ForSingleType, Instrumenter.HasMethodAdvice { private final String parentPackageName = Strings.getPackageName(JUnit4Utils.class.getName()); - public MUnitRetryInstrumentation() { + public MUnitExecutionInstrumentation() { super("ci-visibility", "junit-4", "junit-4-munit", "test-retry"); } @Override public boolean isApplicable(Set enabledSystems) { - return super.isApplicable(enabledSystems) && Config.get().isCiVisibilityTestRetryEnabled(); + return super.isApplicable(enabledSystems) + && Config.get().isCiVisibilityExecutionPoliciesEnabled(); } @Override @@ -54,32 +55,32 @@ public String[] helperClassNames() { parentPackageName + ".JUnit4Utils", parentPackageName + ".TracingListener", parentPackageName + ".TestEventsHandlerHolder", - packageName + ".RetryAwareNotifier" + packageName + ".FailureSuppressingNotifier" }; } @Override public Map contextStore() { return Collections.singletonMap( - "org.junit.runner.Description", TestRetryPolicy.class.getName()); + "org.junit.runner.Description", TestExecutionPolicy.class.getName()); } @Override public void methodAdvice(MethodTransformer transformer) { transformer.applyAdvice( named("runTest").and(takesArgument(0, named("org.junit.runner.notification.RunNotifier"))), - MUnitRetryInstrumentation.class.getName() + "$RetryAdvice"); + MUnitExecutionInstrumentation.class.getName() + "$ExecutionAdvice"); } - public static class RetryAdvice { + public static class ExecutionAdvice { @SuppressWarnings("bytebuddy-exception-suppression") @Advice.OnMethodEnter(skipOn = Future.class) - public static Future retryIfNeeded( + public static Future apply( @Advice.Origin Method runTest, @Advice.This MUnitRunner runner, @Advice.Argument(0) RunNotifier notifier, @Advice.Argument(1) Object test) { - if (notifier instanceof RetryAwareNotifier) { + if (notifier instanceof FailureSuppressingNotifier) { // notifier already wrapped, run original method return null; } @@ -88,32 +89,34 @@ public static Future retryIfNeeded( TestIdentifier testIdentifier = JUnit4Utils.toTestIdentifier(description); TestSourceData testSourceData = JUnit4Utils.toTestSourceData(description); - TestRetryPolicy retryPolicy = - TestEventsHandlerHolder.TEST_EVENTS_HANDLER.retryPolicy(testIdentifier, testSourceData); - if (!retryPolicy.retriesLeft()) { + TestExecutionPolicy executionPolicy = + TestEventsHandlerHolder.TEST_EVENTS_HANDLER.executionPolicy( + testIdentifier, testSourceData); + if (!executionPolicy.applicable()) { // retries not applicable, run original method return null; } - InstrumentationContext.get(Description.class, TestRetryPolicy.class) - .put(description, retryPolicy); + InstrumentationContext.get(Description.class, TestExecutionPolicy.class) + .put(description, executionPolicy); Future result = Future.successful(false); - RetryAwareNotifier retryAwareNotifier = new RetryAwareNotifier(retryPolicy, notifier); + FailureSuppressingNotifier failureSuppressingNotifier = + new FailureSuppressingNotifier(executionPolicy, notifier); long duration; boolean testFailed; do { long startTimestamp = System.currentTimeMillis(); try { runTest.setAccessible(true); - result = (Future) runTest.invoke(runner, retryAwareNotifier, test); - testFailed = retryAwareNotifier.getAndResetFailedFlag(); + result = (Future) runTest.invoke(runner, failureSuppressingNotifier, test); + testFailed = failureSuppressingNotifier.getAndResetFailedFlag(); } catch (Throwable throwable) { testFailed = true; } duration = System.currentTimeMillis() - startTimestamp; - } while (retryPolicy.retry(!testFailed, duration)); + } while (executionPolicy.retry(!testFailed, duration)); // skip original method return result; @@ -124,7 +127,7 @@ public static Future retryIfNeeded( value = "UC_USELESS_OBJECT", justification = "result is the return value of the original method") @Advice.OnMethodExit - public static void returnRetryResult( + public static void returnResult( @Advice.Enter Future overriddenResult, @Advice.Return(readOnly = false) Future result) { if (overriddenResult != null) { diff --git a/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/JUnit4Instrumentation.java b/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/JUnit4Instrumentation.java index 816ed835cc4..86671bf134e 100644 --- a/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/JUnit4Instrumentation.java +++ b/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/JUnit4Instrumentation.java @@ -9,7 +9,7 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.bootstrap.InstrumentationContext; import java.util.Collections; import java.util.List; @@ -75,7 +75,7 @@ public String[] helperClassNames() { @Override public Map contextStore() { return Collections.singletonMap( - "org.junit.runner.Description", TestRetryPolicy.class.getName()); + "org.junit.runner.Description", TestExecutionPolicy.class.getName()); } @Override @@ -116,7 +116,7 @@ public static void addTracingListener( final TracingListener tracingListener = new JUnit4TracingListener( - InstrumentationContext.get(Description.class, TestRetryPolicy.class)); + InstrumentationContext.get(Description.class, TestExecutionPolicy.class)); runNotifier.addListener(tracingListener); } diff --git a/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/JUnit4TracingListener.java b/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/JUnit4TracingListener.java index d6a92460ff8..de0ecc306d0 100644 --- a/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/JUnit4TracingListener.java +++ b/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/JUnit4TracingListener.java @@ -3,7 +3,7 @@ import datadog.trace.api.civisibility.config.TestSourceData; import datadog.trace.api.civisibility.events.TestDescriptor; import datadog.trace.api.civisibility.events.TestSuiteDescriptor; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation; import datadog.trace.bootstrap.ContextStore; import java.lang.reflect.Method; @@ -18,9 +18,9 @@ public class JUnit4TracingListener extends TracingListener { private static final String FRAMEWORK_NAME = "junit4"; private static final String FRAMEWORK_VERSION = Version.id(); - private final ContextStore retryPolicies; + private final ContextStore retryPolicies; - public JUnit4TracingListener(ContextStore retryPolicies) { + public JUnit4TracingListener(ContextStore retryPolicies) { this.retryPolicies = retryPolicies; } @@ -74,7 +74,7 @@ public void testStarted(final Description description) { String testParameters = JUnit4Utils.getParameters(description); List categories = JUnit4Utils.getCategories(testSourceData.getTestClass(), testSourceData.getTestMethod()); - TestRetryPolicy retryPolicy = retryPolicies.get(description); + TestExecutionPolicy retryPolicy = retryPolicies.get(description); TestEventsHandlerHolder.TEST_EVENTS_HANDLER.onTestStart( suiteDescriptor, diff --git a/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/retry/RetryAwareNotifier.java b/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/execution/FailureSuppressingNotifier.java similarity index 74% rename from dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/retry/RetryAwareNotifier.java rename to dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/execution/FailureSuppressingNotifier.java index b4437b558e3..d09c5878e3a 100644 --- a/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/retry/RetryAwareNotifier.java +++ b/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/execution/FailureSuppressingNotifier.java @@ -1,6 +1,6 @@ -package datadog.trace.instrumentation.junit4.retry; +package datadog.trace.instrumentation.junit4.execution; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.instrumentation.junit4.JUnit4Utils; import datadog.trace.instrumentation.junit4.TracingListener; import java.util.List; @@ -8,14 +8,14 @@ import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; -public class RetryAwareNotifier extends RunNotifier { +public class FailureSuppressingNotifier extends RunNotifier { - private final TestRetryPolicy retryPolicy; + private final TestExecutionPolicy executionPolicy; private boolean failed; - public RetryAwareNotifier(TestRetryPolicy retryPolicy, RunNotifier notifier) { - this.retryPolicy = retryPolicy; + public FailureSuppressingNotifier(TestExecutionPolicy executionPolicy, RunNotifier notifier) { + this.executionPolicy = executionPolicy; List listeners = JUnit4Utils.runListenersFromRunNotifier(notifier); for (RunListener listener : listeners) { @@ -27,7 +27,7 @@ public RetryAwareNotifier(TestRetryPolicy retryPolicy, RunNotifier notifier) { public void fireTestFailure(Failure failure) { this.failed = true; - if (!retryPolicy.suppressFailures()) { + if (!executionPolicy.suppressFailures()) { super.fireTestFailure(failure); return; } diff --git a/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/retry/JUnit4RetryInstrumentation.java b/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/execution/JUnit4ExecutionInstrumentation.java similarity index 73% rename from dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/retry/JUnit4RetryInstrumentation.java rename to dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/execution/JUnit4ExecutionInstrumentation.java index def177dbab4..75ad0ca68ca 100644 --- a/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/retry/JUnit4RetryInstrumentation.java +++ b/dd-java-agent/instrumentation/junit-4.10/src/main/java/datadog/trace/instrumentation/junit4/execution/JUnit4ExecutionInstrumentation.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.junit4.retry; +package datadog.trace.instrumentation.junit4.execution; import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.extendsClass; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; @@ -10,7 +10,7 @@ import datadog.trace.api.Config; import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.instrumentation.junit4.JUnit4Utils; import datadog.trace.instrumentation.junit4.TestEventsHandlerHolder; @@ -30,18 +30,19 @@ import org.junit.runners.model.Statement; @AutoService(InstrumenterModule.class) -public class JUnit4RetryInstrumentation extends InstrumenterModule.CiVisibility +public class JUnit4ExecutionInstrumentation extends InstrumenterModule.CiVisibility implements Instrumenter.ForTypeHierarchy, Instrumenter.HasMethodAdvice { private final String parentPackageName = Strings.getPackageName(JUnit4Utils.class.getName()); - public JUnit4RetryInstrumentation() { + public JUnit4ExecutionInstrumentation() { super("ci-visibility", "junit-4", "test-retry"); } @Override public boolean isApplicable(Set enabledSystems) { - return super.isApplicable(enabledSystems) && Config.get().isCiVisibilityTestRetryEnabled(); + return super.isApplicable(enabledSystems) + && Config.get().isCiVisibilityExecutionPoliciesEnabled(); } @Override @@ -61,14 +62,14 @@ public String[] helperClassNames() { parentPackageName + ".JUnit4Utils", parentPackageName + ".TracingListener", parentPackageName + ".TestEventsHandlerHolder", - packageName + ".RetryAwareNotifier" + packageName + ".FailureSuppressingNotifier" }; } @Override public Map contextStore() { return Collections.singletonMap( - "org.junit.runner.Description", TestRetryPolicy.class.getName()); + "org.junit.runner.Description", TestExecutionPolicy.class.getName()); } @Override @@ -78,50 +79,52 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(0, named("org.junit.runners.model.Statement"))) .and(takesArgument(1, named("org.junit.runner.Description"))) .and(takesArgument(2, named("org.junit.runner.notification.RunNotifier"))), - JUnit4RetryInstrumentation.class.getName() + "$RetryAdvice"); + JUnit4ExecutionInstrumentation.class.getName() + "$ExecutionAdvice"); } - public static class RetryAdvice { + public static class ExecutionAdvice { @SuppressWarnings("bytebuddy-exception-suppression") @SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL") @Advice.OnMethodEnter(skipOn = Boolean.class) - public static Boolean retryIfNeeded( + public static Boolean apply( @Advice.Origin Method runTest, @Advice.This ParentRunner runner, @Advice.Argument(0) Statement statement, @Advice.Argument(1) Description description, @Advice.Argument(2) RunNotifier notifier) { - if (notifier instanceof RetryAwareNotifier) { + if (notifier instanceof FailureSuppressingNotifier) { // notifier already wrapped, run original method return null; } TestIdentifier testIdentifier = JUnit4Utils.toTestIdentifier(description); TestSourceData testSourceData = JUnit4Utils.toTestSourceData(description); - TestRetryPolicy retryPolicy = - TestEventsHandlerHolder.TEST_EVENTS_HANDLER.retryPolicy(testIdentifier, testSourceData); - if (!retryPolicy.retriesLeft()) { + TestExecutionPolicy executionPolicy = + TestEventsHandlerHolder.TEST_EVENTS_HANDLER.executionPolicy( + testIdentifier, testSourceData); + if (!executionPolicy.applicable()) { // retries not applicable, run original method return null; } - InstrumentationContext.get(Description.class, TestRetryPolicy.class) - .put(description, retryPolicy); + InstrumentationContext.get(Description.class, TestExecutionPolicy.class) + .put(description, executionPolicy); - RetryAwareNotifier retryAwareNotifier = new RetryAwareNotifier(retryPolicy, notifier); + FailureSuppressingNotifier failureSuppressingNotifier = + new FailureSuppressingNotifier(executionPolicy, notifier); long duration; boolean testFailed; do { long startTimestamp = System.currentTimeMillis(); try { runTest.setAccessible(true); - runTest.invoke(runner, statement, description, retryAwareNotifier); - testFailed = retryAwareNotifier.getAndResetFailedFlag(); + runTest.invoke(runner, statement, description, failureSuppressingNotifier); + testFailed = failureSuppressingNotifier.getAndResetFailedFlag(); } catch (Throwable throwable) { testFailed = true; } duration = System.currentTimeMillis() - startTimestamp; - } while (retryPolicy.retry(!testFailed, duration)); + } while (executionPolicy.retry(!testFailed, duration)); // skip original method return Boolean.TRUE; diff --git a/dd-java-agent/instrumentation/junit-5.3/spock-junit-5/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5SpockParameterizedRetryInstrumentation.java b/dd-java-agent/instrumentation/junit-5.3/spock-junit-5/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5SpockParameterizedExecutionInstrumentation.java similarity index 82% rename from dd-java-agent/instrumentation/junit-5.3/spock-junit-5/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5SpockParameterizedRetryInstrumentation.java rename to dd-java-agent/instrumentation/junit-5.3/spock-junit-5/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5SpockParameterizedExecutionInstrumentation.java index a6ad4ea135d..9074313fbed 100644 --- a/dd-java-agent/instrumentation/junit-5.3/spock-junit-5/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5SpockParameterizedRetryInstrumentation.java +++ b/dd-java-agent/instrumentation/junit-5.3/spock-junit-5/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5SpockParameterizedExecutionInstrumentation.java @@ -21,19 +21,21 @@ * parameterized tests */ @AutoService(InstrumenterModule.class) -public class JUnit5SpockParameterizedRetryInstrumentation extends InstrumenterModule.CiVisibility +public class JUnit5SpockParameterizedExecutionInstrumentation + extends InstrumenterModule.CiVisibility implements Instrumenter.ForSingleType, Instrumenter.HasMethodAdvice { private final String parentPackageName = Strings.getPackageName(JUnitPlatformUtils.class.getName()); - public JUnit5SpockParameterizedRetryInstrumentation() { + public JUnit5SpockParameterizedExecutionInstrumentation() { super("ci-visibility", "junit-5", "junit-5-spock", "test-retry"); } @Override public boolean isApplicable(Set enabledSystems) { - return super.isApplicable(enabledSystems) && Config.get().isCiVisibilityTestRetryEnabled(); + return super.isApplicable(enabledSystems) + && Config.get().isCiVisibilityExecutionPoliciesEnabled(); } @Override @@ -53,11 +55,11 @@ public String[] helperClassNames() { public void methodAdvice(MethodTransformer transformer) { transformer.applyAdvice( isConstructor(), - JUnit5SpockParameterizedRetryInstrumentation.class.getName() - + "$SpockParameterizedRetryAdvice"); + JUnit5SpockParameterizedExecutionInstrumentation.class.getName() + + "$SpockParameterizedExecutionAdvice"); } - public static class SpockParameterizedRetryAdvice { + public static class SpockParameterizedExecutionAdvice { @SuppressWarnings("bytebuddy-exception-suppression") @SuppressFBWarnings( diff --git a/dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5RetryInstrumentation.java b/dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5ExecutionInstrumentation.java similarity index 87% rename from dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5RetryInstrumentation.java rename to dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5ExecutionInstrumentation.java index 76bbf6499a4..5cf7a6b87a5 100644 --- a/dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5RetryInstrumentation.java +++ b/dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5ExecutionInstrumentation.java @@ -13,7 +13,7 @@ import datadog.trace.api.Config; import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.bootstrap.CallDepthThreadLocalMap; import datadog.trace.bootstrap.InstrumentationContext; import datadog.trace.instrumentation.junit5.JUnitPlatformUtils; @@ -34,19 +34,20 @@ import org.junit.platform.engine.support.hierarchical.ThrowableCollector; @AutoService(InstrumenterModule.class) -public class JUnit5RetryInstrumentation extends InstrumenterModule.CiVisibility +public class JUnit5ExecutionInstrumentation extends InstrumenterModule.CiVisibility implements Instrumenter.ForSingleType, Instrumenter.HasMethodAdvice { private final String parentPackageName = Strings.getPackageName(JUnitPlatformUtils.class.getName()); - public JUnit5RetryInstrumentation() { + public JUnit5ExecutionInstrumentation() { super("ci-visibility", "junit-5", "test-retry"); } @Override public boolean isApplicable(Set enabledSystems) { - return super.isApplicable(enabledSystems) && Config.get().isCiVisibilityTestRetryEnabled(); + return super.isApplicable(enabledSystems) + && Config.get().isCiVisibilityExecutionPoliciesEnabled(); } @Override @@ -70,7 +71,7 @@ public String[] helperClassNames() { public Map contextStore() { return Collections.singletonMap( "org.junit.platform.engine.TestDescriptor", - "datadog.trace.api.civisibility.retry.TestRetryPolicy"); + "datadog.trace.api.civisibility.execution.TestExecutionPolicy"); } @Override @@ -100,10 +101,10 @@ public void methodAdvice(MethodTransformer transformer) { 3, named( "org.junit.platform.engine.support.hierarchical.ThrowableCollector.Factory"))), - JUnit5RetryInstrumentation.class.getName() + "$BeforeTaskConstructor"); + JUnit5ExecutionInstrumentation.class.getName() + "$BeforeTaskConstructor"); transformer.applyAdvice( named("execute").and(takesNoArguments()), - JUnit5RetryInstrumentation.class.getName() + "$RetryIfNeeded"); + JUnit5ExecutionInstrumentation.class.getName() + "$ExecutionAdvice"); } public static class BeforeTaskConstructor { @@ -115,7 +116,7 @@ public static void replaceThrowableCollectorFactory( } } - public static class RetryIfNeeded { + public static class ExecutionAdvice { @SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL") @Advice.OnMethodEnter(skipOn = Boolean.class) public static Boolean execute(@Advice.This HierarchicalTestExecutorService.TestTask testTask) { @@ -144,9 +145,9 @@ public static Boolean execute(@Advice.This HierarchicalTestExecutorService.TestT TestIdentifier testIdentifier = TestDataFactory.createTestIdentifier(testDescriptor); TestSourceData testSource = TestDataFactory.createTestSourceData(testDescriptor); - TestRetryPolicy retryPolicy = - TestEventsHandlerHolder.TEST_EVENTS_HANDLER.retryPolicy(testIdentifier, testSource); - if (!retryPolicy.retriesLeft()) { + TestExecutionPolicy executionPolicy = + TestEventsHandlerHolder.TEST_EVENTS_HANDLER.executionPolicy(testIdentifier, testSource); + if (!executionPolicy.applicable()) { return null; } @@ -158,7 +159,7 @@ public static Boolean execute(@Advice.This HierarchicalTestExecutorService.TestT int retryAttemptIdx = 0; boolean retry; while (true) { - factory.setSuppressFailures(retryPolicy.suppressFailures()); + factory.setSuppressFailures(executionPolicy.suppressFailures()); long startTimestamp = System.currentTimeMillis(); CallDepthThreadLocalMap.incrementCallDepth(HierarchicalTestExecutorService.TestTask.class); @@ -170,7 +171,7 @@ public static Boolean execute(@Advice.This HierarchicalTestExecutorService.TestT factory.setSuppressFailures(false); // restore default behavior boolean success = error == null || JUnitPlatformUtils.isAssumptionFailure(error); - retry = retryPolicy.retry(success, duration); + retry = executionPolicy.retry(success, duration); if (!retry) { break; } @@ -183,13 +184,13 @@ public static Boolean execute(@Advice.This HierarchicalTestExecutorService.TestT TestDescriptor retryDescriptor = descriptorHandle.withIdSuffix( JUnitPlatformUtils.RETRY_DESCRIPTOR_REASON_SUFFIX, - retryPolicy.currentExecutionRetryReason(), + executionPolicy.currentExecutionRetryReason(), JUnitPlatformUtils.RETRY_DESCRIPTOR_ID_SUFFIX, String.valueOf(++retryAttemptIdx)); taskHandle.setTestDescriptor(retryDescriptor); taskHandle.setNode((Node) retryDescriptor); taskHandle.getListener().dynamicTestRegistered(retryDescriptor); - InstrumentationContext.get(TestDescriptor.class, TestRetryPolicy.class) - .put(retryDescriptor, retryPolicy); + InstrumentationContext.get(TestDescriptor.class, TestExecutionPolicy.class) + .put(retryDescriptor, executionPolicy); // restore parent context, since the reference is overwritten with null after execution taskHandle.setParentContext(parentContext); diff --git a/dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5NodeTestTaskContextInstrumentation.java b/dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5NodeTestTaskContextInstrumentation.java index 3a46fec2031..2525ba73829 100644 --- a/dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5NodeTestTaskContextInstrumentation.java +++ b/dd-java-agent/instrumentation/junit-5.3/src/main/java/datadog/trace/instrumentation/junit5/retry/JUnit5NodeTestTaskContextInstrumentation.java @@ -26,7 +26,8 @@ public JUnit5NodeTestTaskContextInstrumentation() { @Override public boolean isApplicable(Set enabledSystems) { - return super.isApplicable(enabledSystems) && Config.get().isCiVisibilityTestRetryEnabled(); + return super.isApplicable(enabledSystems) + && Config.get().isCiVisibilityExecutionPoliciesEnabled(); } @Override diff --git a/dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/RetryContext.java b/dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/ExecutionContext.java similarity index 60% rename from dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/RetryContext.java rename to dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/ExecutionContext.java index cdde1ea395a..d1c223e25a8 100644 --- a/dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/RetryContext.java +++ b/dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/ExecutionContext.java @@ -3,16 +3,16 @@ import com.intuit.karate.core.Scenario; import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; -public class RetryContext { +public class ExecutionContext { - private final TestRetryPolicy retryPolicy; + private final TestExecutionPolicy executionPolicy; private boolean failed; private long startTimestamp; - public RetryContext(TestRetryPolicy retryPolicy) { - this.retryPolicy = retryPolicy; + public ExecutionContext(TestExecutionPolicy executionPolicy) { + this.executionPolicy = executionPolicy; } public void setStartTimestamp(long startTimestamp) { @@ -33,14 +33,14 @@ public boolean getAndResetFailed() { return failed; } - public TestRetryPolicy getRetryPolicy() { - return retryPolicy; + public TestExecutionPolicy getExecutionPolicy() { + return executionPolicy; } - public static RetryContext create(Scenario scenario) { + public static ExecutionContext create(Scenario scenario) { TestIdentifier testIdentifier = KarateUtils.toTestIdentifier(scenario); - return new RetryContext( - TestEventsHandlerHolder.TEST_EVENTS_HANDLER.retryPolicy( + return new ExecutionContext( + TestEventsHandlerHolder.TEST_EVENTS_HANDLER.executionPolicy( testIdentifier, TestSourceData.UNKNOWN)); } } diff --git a/dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/KarateRetryInstrumentation.java b/dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/KarateExecutionInstrumentation.java similarity index 70% rename from dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/KarateRetryInstrumentation.java rename to dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/KarateExecutionInstrumentation.java index 7c551d4a488..4cd782b2c96 100644 --- a/dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/KarateRetryInstrumentation.java +++ b/dd-java-agent/instrumentation/karate/src/main/java/datadog/trace/instrumentation/karate/KarateExecutionInstrumentation.java @@ -14,7 +14,7 @@ import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.api.Config; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.bootstrap.InstrumentationContext; import java.util.Collections; import java.util.Map; @@ -22,16 +22,17 @@ import net.bytebuddy.asm.Advice; @AutoService(InstrumenterModule.class) -public class KarateRetryInstrumentation extends InstrumenterModule.CiVisibility +public class KarateExecutionInstrumentation extends InstrumenterModule.CiVisibility implements Instrumenter.ForKnownTypes, Instrumenter.HasMethodAdvice { - public KarateRetryInstrumentation() { + public KarateExecutionInstrumentation() { super("ci-visibility", "karate", "test-retry"); } @Override public boolean isApplicable(Set enabledSystems) { - return super.isApplicable(enabledSystems) && Config.get().isCiVisibilityTestRetryEnabled(); + return super.isApplicable(enabledSystems) + && Config.get().isCiVisibilityExecutionPoliciesEnabled(); } @Override @@ -47,14 +48,14 @@ public String[] helperClassNames() { packageName + ".TestEventsHandlerHolder", packageName + ".KarateUtils", packageName + ".KarateTracingHook", - packageName + ".RetryContext" + packageName + ".ExecutionContext" }; } @Override public Map contextStore() { return Collections.singletonMap( - "com.intuit.karate.core.Scenario", packageName + ".RetryContext"); + "com.intuit.karate.core.Scenario", packageName + ".ExecutionContext"); } @Override @@ -62,40 +63,40 @@ public void methodAdvice(MethodTransformer transformer) { // ScenarioRuntime transformer.applyAdvice( named("run").and(takesNoArguments()), - KarateRetryInstrumentation.class.getName() + "$RetryAdvice"); + KarateExecutionInstrumentation.class.getName() + "$RetryAdvice"); // ScenarioResult transformer.applyAdvice( named("addStepResult") .and(takesArguments(1)) .and(takesArgument(0, named("com.intuit.karate.core.StepResult"))), - KarateRetryInstrumentation.class.getName() + "$SuppressErrorAdvice"); + KarateExecutionInstrumentation.class.getName() + "$SuppressErrorAdvice"); } public static class RetryAdvice { @Advice.OnMethodEnter public static void beforeExecute(@Advice.This ScenarioRuntime scenarioRuntime) { - InstrumentationContext.get(Scenario.class, RetryContext.class) - .computeIfAbsent(scenarioRuntime.scenario, RetryContext::create) + InstrumentationContext.get(Scenario.class, ExecutionContext.class) + .computeIfAbsent(scenarioRuntime.scenario, ExecutionContext::create) .setStartTimestamp(System.currentTimeMillis()); } @Advice.OnMethodExit public static void afterExecute(@Advice.This ScenarioRuntime scenarioRuntime) { Scenario scenario = scenarioRuntime.scenario; - RetryContext retryContext = - InstrumentationContext.get(Scenario.class, RetryContext.class).get(scenario); - if (retryContext == null) { + ExecutionContext context = + InstrumentationContext.get(Scenario.class, ExecutionContext.class).get(scenario); + if (context == null) { return; } - TestRetryPolicy retryPolicy = retryContext.getRetryPolicy(); - long duration = System.currentTimeMillis() - retryContext.getStartTimestamp(); - if (retryPolicy.retry(!retryContext.getAndResetFailed(), duration)) { + TestExecutionPolicy executionPolicy = context.getExecutionPolicy(); + long duration = System.currentTimeMillis() - context.getStartTimestamp(); + if (executionPolicy.retry(!context.getAndResetFailed(), duration)) { ScenarioRuntime retry = new ScenarioRuntime(scenarioRuntime.featureRuntime, scenarioRuntime.scenario); retry.magicVariables.put( - KarateUtils.RETRY_MAGIC_VARIABLE, retryPolicy.currentExecutionRetryReason()); + KarateUtils.RETRY_MAGIC_VARIABLE, executionPolicy.currentExecutionRetryReason()); retry.run(); retry.featureRuntime.result.addResult(retry.result); } @@ -115,15 +116,15 @@ public static void onAddingStepResult( Result result = stepResult.getResult(); if (result.isFailed()) { - RetryContext retryContext = - InstrumentationContext.get(Scenario.class, RetryContext.class).get(scenario); - if (retryContext == null) { + ExecutionContext executionContext = + InstrumentationContext.get(Scenario.class, ExecutionContext.class).get(scenario); + if (executionContext == null) { return; } - retryContext.setFailed(true); + executionContext.setFailed(true); - TestRetryPolicy retryPolicy = retryContext.getRetryPolicy(); + TestExecutionPolicy retryPolicy = executionContext.getExecutionPolicy(); if (retryPolicy.suppressFailures()) { stepResult = new StepResult(stepResult.getStep(), KarateUtils.abortedResult()); stepResult.setFailedReason(result.getError()); diff --git a/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/DatadogReporter.java b/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/DatadogReporter.java index 8351688c1f7..079cfee63b8 100644 --- a/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/DatadogReporter.java +++ b/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/DatadogReporter.java @@ -6,10 +6,10 @@ import datadog.trace.api.civisibility.events.TestDescriptor; import datadog.trace.api.civisibility.events.TestEventsHandler; import datadog.trace.api.civisibility.events.TestSuiteDescriptor; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.SkipReason; import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation; -import datadog.trace.instrumentation.scalatest.retry.SuppressedTestFailedException; +import datadog.trace.instrumentation.scalatest.execution.SuppressedTestFailedException; import java.util.Collection; import java.util.Collections; import org.scalatest.events.Event; @@ -145,7 +145,7 @@ private static void onTestStart(TestStarting event) { categories = Collections.emptyList(); } Class testClass = ScalatestUtils.getClass(event.suiteClassName()); - TestRetryPolicy retryPolicy = context.popRetryPolicy(testIdentifier); + TestExecutionPolicy retryPolicy = context.popExecutionPolicy(testIdentifier); eventHandler.onTestStart( new TestSuiteDescriptor(testSuiteName, testClass), diff --git a/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/RunContext.java b/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/RunContext.java index e6165ce9ec8..bce38d35c10 100644 --- a/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/RunContext.java +++ b/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/RunContext.java @@ -6,7 +6,7 @@ import datadog.trace.api.civisibility.events.TestDescriptor; import datadog.trace.api.civisibility.events.TestEventsHandler; import datadog.trace.api.civisibility.events.TestSuiteDescriptor; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.SkipReason; import java.util.ArrayList; import java.util.concurrent.ConcurrentHashMap; @@ -38,7 +38,7 @@ public static void destroy(int runStamp) { private final java.util.Map skipReasonByTest = new ConcurrentHashMap<>(); private final java.util.Set itrUnskippableTests = ConcurrentHashMap.newKeySet(); - private final java.util.Map retryPolicies = + private final java.util.Map executionPolicies = new ConcurrentHashMap<>(); public RunContext(int runStamp) { @@ -128,19 +128,20 @@ private boolean isItrUnskippable(TestIdentifier test, Map> t return testTags != null && testTags.contains(InstrumentationBridge.ITR_UNSKIPPABLE_TAG); } - public TestRetryPolicy retryPolicy(TestIdentifier testIdentifier, TestSourceData testSourceData) { - return retryPolicies.computeIfAbsent( - testIdentifier, test -> eventHandler.retryPolicy(test, testSourceData)); + public TestExecutionPolicy executionPolicy( + TestIdentifier testIdentifier, TestSourceData testSourceData) { + return executionPolicies.computeIfAbsent( + testIdentifier, test -> eventHandler.executionPolicy(test, testSourceData)); } @Nullable - public TestRetryPolicy popRetryPolicy(TestIdentifier testIdentifier) { - TestRetryPolicy[] holder = new TestRetryPolicy[1]; - retryPolicies.computeIfPresent( + public TestExecutionPolicy popExecutionPolicy(TestIdentifier testIdentifier) { + TestExecutionPolicy[] holder = new TestExecutionPolicy[1]; + executionPolicies.computeIfPresent( testIdentifier, - (ti, retryPolicy) -> { - holder[0] = retryPolicy; - return retryPolicy.retriesLeft() ? retryPolicy : null; + (ti, policy) -> { + holder[0] = policy; + return policy.applicable() ? policy : null; }); return holder[0]; } diff --git a/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/ScalatestInstrumentation.java b/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/ScalatestInstrumentation.java index 1a8eff402fc..b5ad3ee30cb 100644 --- a/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/ScalatestInstrumentation.java +++ b/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/ScalatestInstrumentation.java @@ -32,7 +32,7 @@ public String instrumentedType() { @Override public String[] helperClassNames() { return new String[] { - packageName + ".retry.SuppressedTestFailedException", + packageName + ".execution.SuppressedTestFailedException", packageName + ".ScalatestUtils", packageName + ".RunContext", packageName + ".DatadogReporter", diff --git a/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/retry/ScalatestRetryInstrumentation.java b/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/execution/ScalatestExecutionInstrumentation.java similarity index 86% rename from dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/retry/ScalatestRetryInstrumentation.java rename to dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/execution/ScalatestExecutionInstrumentation.java index bfe9c35f07e..a006bf757d0 100644 --- a/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/retry/ScalatestRetryInstrumentation.java +++ b/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/execution/ScalatestExecutionInstrumentation.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.scalatest.retry; +package datadog.trace.instrumentation.scalatest.execution; import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.extendsClass; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; @@ -10,7 +10,7 @@ import datadog.trace.api.Config; import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.instrumentation.scalatest.RunContext; import datadog.trace.instrumentation.scalatest.ScalatestUtils; import datadog.trace.util.Strings; @@ -26,18 +26,19 @@ import org.scalatest.SuperEngine; @AutoService(InstrumenterModule.class) -public class ScalatestRetryInstrumentation extends InstrumenterModule.CiVisibility +public class ScalatestExecutionInstrumentation extends InstrumenterModule.CiVisibility implements Instrumenter.ForTypeHierarchy, Instrumenter.HasMethodAdvice { private final String parentPackageName = Strings.getPackageName(ScalatestUtils.class.getName()); - public ScalatestRetryInstrumentation() { + public ScalatestExecutionInstrumentation() { super("ci-visibility", "scalatest", "test-retry"); } @Override public boolean isApplicable(Set enabledSystems) { - return super.isApplicable(enabledSystems) && Config.get().isCiVisibilityTestRetryEnabled(); + return super.isApplicable(enabledSystems) + && Config.get().isCiVisibilityExecutionPoliciesEnabled(); } @Override @@ -68,10 +69,10 @@ public void methodAdvice(MethodTransformer transformer) { .and(takesArgument(0, named("org.scalatest.Suite"))) .and(takesArgument(1, String.class)) .and(takesArgument(2, named("org.scalatest.Args"))), - ScalatestRetryInstrumentation.class.getName() + "$RetryAdvice"); + ScalatestExecutionInstrumentation.class.getName() + "$ExecutionAdvice"); } - public static class RetryAdvice { + public static class ExecutionAdvice { @Advice.OnMethodEnter public static void beforeTest( @Advice.Argument(value = 0) Suite suite, @@ -85,9 +86,10 @@ public static void beforeTest( RunContext context = RunContext.getOrCreate(runStamp); TestIdentifier testIdentifier = new TestIdentifier(suite.suiteId(), testName, null); TestSourceData testSourceData = new TestSourceData(suite.getClass(), null, null); - TestRetryPolicy retryPolicy = context.retryPolicy(testIdentifier, testSourceData); + TestExecutionPolicy executionPolicy = + context.executionPolicy(testIdentifier, testSourceData); - invokeWithFixture = new TestExecutionWrapper(invokeWithFixture, retryPolicy); + invokeWithFixture = new TestExecutionWrapper(invokeWithFixture, executionPolicy); } } diff --git a/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/retry/SuppressedTestFailedException.java b/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/execution/SuppressedTestFailedException.java similarity index 82% rename from dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/retry/SuppressedTestFailedException.java rename to dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/execution/SuppressedTestFailedException.java index abf6e7a0b1d..0cbadb26597 100644 --- a/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/retry/SuppressedTestFailedException.java +++ b/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/execution/SuppressedTestFailedException.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.scalatest.retry; +package datadog.trace.instrumentation.scalatest.execution; import org.scalatest.exceptions.TestCanceledException; diff --git a/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/retry/TestExecutionWrapper.java b/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/execution/TestExecutionWrapper.java similarity index 73% rename from dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/retry/TestExecutionWrapper.java rename to dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/execution/TestExecutionWrapper.java index e08e2089984..3741f5aa2e3 100644 --- a/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/retry/TestExecutionWrapper.java +++ b/dd-java-agent/instrumentation/scalatest/src/main/java/datadog/trace/instrumentation/scalatest/execution/TestExecutionWrapper.java @@ -1,6 +1,6 @@ -package datadog.trace.instrumentation.scalatest.retry; +package datadog.trace.instrumentation.scalatest.execution; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import org.scalatest.Canceled; import org.scalatest.Outcome; import org.scalatest.SuperEngine; @@ -8,15 +8,15 @@ public class TestExecutionWrapper implements scala.Function1.TestLeaf, Outcome> { private final scala.Function1.TestLeaf, Outcome> delegate; - private final TestRetryPolicy retryPolicy; + private final TestExecutionPolicy executionPolicy; private boolean executionFailed; private long duration; public TestExecutionWrapper( - Function1.TestLeaf, Outcome> delegate, TestRetryPolicy retryPolicy) { + Function1.TestLeaf, Outcome> delegate, TestExecutionPolicy executionPolicy) { this.delegate = delegate; - this.retryPolicy = retryPolicy; + this.executionPolicy = executionPolicy; } @Override @@ -29,7 +29,7 @@ public Outcome apply(SuperEngine.TestLeaf testLeaf) { if (outcome.isFailed()) { executionFailed = true; - if (retryPolicy.suppressFailures()) { + if (executionPolicy.suppressFailures()) { Throwable t = outcome.toOption().get(); return Canceled.apply( new SuppressedTestFailedException("Test failed and will be retried", t, 0)); @@ -40,6 +40,6 @@ public Outcome apply(SuperEngine.TestLeaf testLeaf) { } public boolean retry() { - return retryPolicy.retriesLeft() && retryPolicy.retry(!executionFailed, duration); + return executionPolicy.retry(!executionFailed, duration); } } diff --git a/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/TestNGInstrumentation.java b/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/TestNGInstrumentation.java index c831e370e6b..b4e6b9f5d6d 100644 --- a/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/TestNGInstrumentation.java +++ b/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/TestNGInstrumentation.java @@ -7,7 +7,7 @@ import datadog.trace.api.civisibility.DDTest; import datadog.trace.bootstrap.ContextStore; import datadog.trace.bootstrap.InstrumentationContext; -import datadog.trace.instrumentation.testng.retry.RetryAnnotationTransformer; +import datadog.trace.instrumentation.testng.execution.RetryAnnotationTransformer; import java.util.Collections; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -44,8 +44,8 @@ public String[] helperClassNames() { packageName + ".TestNGClassListener", packageName + ".TestEventsHandlerHolder", packageName + ".TracingListener", - packageName + ".retry.RetryAnalyzer", - packageName + ".retry.RetryAnnotationTransformer", + packageName + ".execution.RetryAnalyzer", + packageName + ".execution.RetryAnnotationTransformer", }; } @@ -75,7 +75,7 @@ public static void addTracingListener(@Advice.This final TestNG testNG) { TestNGSuiteListener suiteListener = new TestNGSuiteListener(tracingListener); testNG.addListener((ITestNGListener) suiteListener); - if (Config.get().isCiVisibilityFlakyRetryEnabled()) { + if (Config.get().isCiVisibilityExecutionPoliciesEnabled()) { final RetryAnnotationTransformer transformer = new RetryAnnotationTransformer(testNG.getAnnotationTransformer()); testNG.addListener(transformer); diff --git a/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/TracingListener.java b/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/TracingListener.java index 4c97fe5cb30..6237acd9ddd 100644 --- a/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/TracingListener.java +++ b/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/TracingListener.java @@ -4,7 +4,7 @@ import datadog.trace.api.civisibility.events.TestSuiteDescriptor; import datadog.trace.api.civisibility.telemetry.tag.RetryReason; import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation; -import datadog.trace.instrumentation.testng.retry.RetryAnalyzer; +import datadog.trace.instrumentation.testng.execution.RetryAnalyzer; import java.util.List; import org.testng.IConfigurationListener; import org.testng.IRetryAnalyzer; diff --git a/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/retry/RetryAnalyzer.java b/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/execution/RetryAnalyzer.java similarity index 61% rename from dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/retry/RetryAnalyzer.java rename to dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/execution/RetryAnalyzer.java index dfe3f9a52d2..7d3b1a7d0a4 100644 --- a/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/retry/RetryAnalyzer.java +++ b/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/execution/RetryAnalyzer.java @@ -1,8 +1,8 @@ -package datadog.trace.instrumentation.testng.retry; +package datadog.trace.instrumentation.testng.execution; import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.RetryReason; import datadog.trace.instrumentation.testng.TestEventsHandlerHolder; import datadog.trace.instrumentation.testng.TestNGUtils; @@ -11,28 +11,29 @@ public class RetryAnalyzer implements IRetryAnalyzer { - private volatile TestRetryPolicy retryPolicy; + private volatile TestExecutionPolicy executionPolicy; @Override public boolean retry(ITestResult result) { if (TestEventsHandlerHolder.TEST_EVENTS_HANDLER == null) { return false; } - if (retryPolicy == null) { + if (executionPolicy == null) { synchronized (this) { - if (retryPolicy == null) { + if (executionPolicy == null) { TestIdentifier testIdentifier = TestNGUtils.toTestIdentifier(result); TestSourceData testSourceData = TestNGUtils.toTestSourceData(result); - retryPolicy = - TestEventsHandlerHolder.TEST_EVENTS_HANDLER.retryPolicy( + executionPolicy = + TestEventsHandlerHolder.TEST_EVENTS_HANDLER.executionPolicy( testIdentifier, testSourceData); } } } - return retryPolicy.retry(result.isSuccess(), result.getEndMillis() - result.getStartMillis()); + return executionPolicy.retry( + result.isSuccess(), result.getEndMillis() - result.getStartMillis()); } public RetryReason currentExecutionRetryReason() { - return retryPolicy != null ? retryPolicy.currentExecutionRetryReason() : null; + return executionPolicy != null ? executionPolicy.currentExecutionRetryReason() : null; } } diff --git a/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/retry/RetryAnnotationTransformer.java b/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/execution/RetryAnnotationTransformer.java similarity index 92% rename from dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/retry/RetryAnnotationTransformer.java rename to dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/execution/RetryAnnotationTransformer.java index 22f46b385d5..471716729eb 100644 --- a/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/retry/RetryAnnotationTransformer.java +++ b/dd-java-agent/instrumentation/testng/src/main/java/datadog/trace/instrumentation/testng/execution/RetryAnnotationTransformer.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.testng.retry; +package datadog.trace.instrumentation.testng.execution; import java.lang.reflect.Constructor; import java.lang.reflect.Method; diff --git a/dd-java-agent/instrumentation/testng/testng-7/src/main/java/datadog/trace/instrumentation/testng7/TestNGRetryInstrumentation.java b/dd-java-agent/instrumentation/testng/testng-7/src/main/java/datadog/trace/instrumentation/testng7/TestNGExecutionInstrumentation.java similarity index 81% rename from dd-java-agent/instrumentation/testng/testng-7/src/main/java/datadog/trace/instrumentation/testng7/TestNGRetryInstrumentation.java rename to dd-java-agent/instrumentation/testng/testng-7/src/main/java/datadog/trace/instrumentation/testng7/TestNGExecutionInstrumentation.java index ddecbbbf531..838a04cb93c 100644 --- a/dd-java-agent/instrumentation/testng/testng-7/src/main/java/datadog/trace/instrumentation/testng7/TestNGRetryInstrumentation.java +++ b/dd-java-agent/instrumentation/testng/testng-7/src/main/java/datadog/trace/instrumentation/testng7/TestNGExecutionInstrumentation.java @@ -8,7 +8,7 @@ import datadog.trace.agent.tooling.InstrumenterModule; import datadog.trace.api.Config; import datadog.trace.instrumentation.testng.TestNGUtils; -import datadog.trace.instrumentation.testng.retry.RetryAnalyzer; +import datadog.trace.instrumentation.testng.execution.RetryAnalyzer; import datadog.trace.util.Strings; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.Set; @@ -18,18 +18,19 @@ import org.testng.ITestResult; @AutoService(InstrumenterModule.class) -public class TestNGRetryInstrumentation extends InstrumenterModule.CiVisibility +public class TestNGExecutionInstrumentation extends InstrumenterModule.CiVisibility implements Instrumenter.ForSingleType, Instrumenter.HasMethodAdvice { private final String commonPackageName = Strings.getPackageName(TestNGUtils.class.getName()); - public TestNGRetryInstrumentation() { + public TestNGExecutionInstrumentation() { super("ci-visibility", "testng", "test-retry"); } @Override public boolean isApplicable(Set enabledSystems) { - return super.isApplicable(enabledSystems) && Config.get().isCiVisibilityTestRetryEnabled(); + return super.isApplicable(enabledSystems) + && Config.get().isCiVisibilityExecutionPoliciesEnabled(); } @Override @@ -41,7 +42,7 @@ public String instrumentedType() { public void methodAdvice(MethodTransformer transformer) { transformer.applyAdvice( named("shouldRetryTestMethod").and(takesArgument(1, named("org.testng.ITestResult"))), - TestNGRetryInstrumentation.class.getName() + "$RetryAdvice"); + TestNGExecutionInstrumentation.class.getName() + "$ExecutionAdvice"); } @Override @@ -50,11 +51,11 @@ public String[] helperClassNames() { commonPackageName + ".TestNGUtils", commonPackageName + ".TestEventsHandlerHolder", commonPackageName + ".TestNGClassListener", - commonPackageName + ".retry.RetryAnalyzer", + commonPackageName + ".execution.RetryAnalyzer", }; } - public static class RetryAdvice { + public static class ExecutionAdvice { @SuppressWarnings("bytebuddy-exception-suppression") @SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL") @Advice.OnMethodExit diff --git a/internal-api/src/main/java/datadog/trace/api/Config.java b/internal-api/src/main/java/datadog/trace/api/Config.java index 37da6f30c4a..0a6e906057b 100644 --- a/internal-api/src/main/java/datadog/trace/api/Config.java +++ b/internal-api/src/main/java/datadog/trace/api/Config.java @@ -2931,7 +2931,7 @@ public int getCiVisibilityEarlyFlakeDetectionLowerLimit() { return ciVisibilityEarlyFlakeDetectionLowerLimit; } - public boolean isCiVisibilityTestRetryEnabled() { + public boolean isCiVisibilityExecutionPoliciesEnabled() { return ciVisibilityFlakyRetryEnabled || ciVisibilityEarlyFlakeDetectionEnabled; } diff --git a/internal-api/src/main/java/datadog/trace/api/civisibility/events/TestEventsHandler.java b/internal-api/src/main/java/datadog/trace/api/civisibility/events/TestEventsHandler.java index 7f81b6f21ab..801ff7b642f 100644 --- a/internal-api/src/main/java/datadog/trace/api/civisibility/events/TestEventsHandler.java +++ b/internal-api/src/main/java/datadog/trace/api/civisibility/events/TestEventsHandler.java @@ -4,7 +4,7 @@ import datadog.trace.api.civisibility.DDTestSuite; import datadog.trace.api.civisibility.config.TestIdentifier; import datadog.trace.api.civisibility.config.TestSourceData; -import datadog.trace.api.civisibility.retry.TestRetryPolicy; +import datadog.trace.api.civisibility.execution.TestExecutionPolicy; import datadog.trace.api.civisibility.telemetry.tag.RetryReason; import datadog.trace.api.civisibility.telemetry.tag.SkipReason; import datadog.trace.api.civisibility.telemetry.tag.TestFrameworkInstrumentation; @@ -86,7 +86,7 @@ void onTestIgnore( @Nullable String reason); @Nonnull - TestRetryPolicy retryPolicy(TestIdentifier test, TestSourceData source); + TestExecutionPolicy executionPolicy(TestIdentifier test, TestSourceData source); /** * Returns the reason for skipping a test IF it can be skipped. diff --git a/internal-api/src/main/java/datadog/trace/api/civisibility/execution/TestExecutionPolicy.java b/internal-api/src/main/java/datadog/trace/api/civisibility/execution/TestExecutionPolicy.java new file mode 100644 index 00000000000..594568a03b0 --- /dev/null +++ b/internal-api/src/main/java/datadog/trace/api/civisibility/execution/TestExecutionPolicy.java @@ -0,0 +1,35 @@ +package datadog.trace.api.civisibility.execution; + +import datadog.trace.api.civisibility.telemetry.tag.RetryReason; +import javax.annotation.Nullable; + +public interface TestExecutionPolicy { + + /** + * @return {@code true} if the next execution of the test will be altered in any way. This method + * is used to avoid unnecessary performance penalty: if it returns {@code false}, + * instrumentation code needed to alter test behavior will be skipped. + */ + boolean applicable(); + + /** + * @return {@code true} if failure of the next execution of the test should not affect build + * result + */ + boolean suppressFailures(); + + /** + * @param successful {@code true} if current test execution passed or was skipped, {@code false} + * otherwise + * @param durationMillis duration of current test execution in milliseconds + * @return {@code true} if another execution of the same test should be done + */ + boolean retry(boolean successful, long durationMillis); + + /** + * @return retry reason for current test execution ({@code null} if current execution is not a + * retry) + */ + @Nullable + RetryReason currentExecutionRetryReason(); +} diff --git a/internal-api/src/main/java/datadog/trace/api/civisibility/retry/TestRetryPolicy.java b/internal-api/src/main/java/datadog/trace/api/civisibility/retry/TestRetryPolicy.java deleted file mode 100644 index 7bec4bf1f12..00000000000 --- a/internal-api/src/main/java/datadog/trace/api/civisibility/retry/TestRetryPolicy.java +++ /dev/null @@ -1,29 +0,0 @@ -package datadog.trace.api.civisibility.retry; - -import datadog.trace.api.civisibility.telemetry.tag.RetryReason; -import javax.annotation.Nullable; - -public interface TestRetryPolicy { - - /** @return {@code true} if failure of this test should not affect the build result */ - boolean suppressFailures(); - - /** - * @return {@code true} if this test can be retried. Current execution is NOT taken into account - */ - boolean retriesLeft(); - - /** - * @param successful {@code true} if test passed or was skipped, {@code false} otherwise - * @param durationMillis test duration in milliseconds - * @return {@code true} if this test should be retried - */ - boolean retry(boolean successful, long durationMillis); - - /** - * Returns retry reason for current execution (will be {@code null} if current execution is not a - * retry) - */ - @Nullable - RetryReason currentExecutionRetryReason(); -}