From aa57bcf6e37f3dc6fad332dc005281d7902110fc Mon Sep 17 00:00:00 2001 From: bm1549 Date: Tue, 10 Mar 2026 15:43:51 -0400 Subject: [PATCH 1/2] Fix flaky cron trigger test by closing context before assertions The "schedule trigger test according to cron expression" test was flaky because the cron expression (every 5 seconds) could fire a second time between blockUntilExecute() returning and the assertTraces() call completing, producing 3 or 4 traces instead of the expected 2. Fix by closing the Spring application context immediately after the first execution completes, before entering the expect block. The ScheduledTasksEndpoint bean reference is captured before closing so the endpoint assertion in the and: block still works. Co-Authored-By: Claude Opus 4.6 --- .../src/latestDepTest/groovy/SpringSchedulingTest.groovy | 7 ++++--- .../src/test/groovy/SpringSchedulingTest.groovy | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/latestDepTest/groovy/SpringSchedulingTest.groovy b/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/latestDepTest/groovy/SpringSchedulingTest.groovy index 6e3b1760c11..523dd209a2c 100644 --- a/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/latestDepTest/groovy/SpringSchedulingTest.groovy +++ b/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/latestDepTest/groovy/SpringSchedulingTest.groovy @@ -25,8 +25,12 @@ class SpringSchedulingTest extends InstrumentationSpecification { setup: def context = new AnnotationConfigApplicationContext(TriggerTaskConfig, SchedulingConfig) def task = context.getBean(TriggerTask) + def scheduledTaskEndpoint = context.getBean(ScheduledTasksEndpoint) task.blockUntilExecute() + // Close the context immediately after the first execution to prevent a second cron + // firing before assertions complete, which would produce extra traces and cause flakiness. + context.close() expect: assert task != null @@ -54,13 +58,10 @@ class SpringSchedulingTest extends InstrumentationSpecification { } } and: - def scheduledTaskEndpoint = context.getBean(ScheduledTasksEndpoint) assert scheduledTaskEndpoint != null scheduledTaskEndpoint.scheduledTasks().getCron().each { it.getRunnable().getTarget() == TriggerTask.getName() } - cleanup: - context.close() } def "schedule interval test"() { diff --git a/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/test/groovy/SpringSchedulingTest.groovy b/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/test/groovy/SpringSchedulingTest.groovy index 6e3b1760c11..523dd209a2c 100644 --- a/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/test/groovy/SpringSchedulingTest.groovy +++ b/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/test/groovy/SpringSchedulingTest.groovy @@ -25,8 +25,12 @@ class SpringSchedulingTest extends InstrumentationSpecification { setup: def context = new AnnotationConfigApplicationContext(TriggerTaskConfig, SchedulingConfig) def task = context.getBean(TriggerTask) + def scheduledTaskEndpoint = context.getBean(ScheduledTasksEndpoint) task.blockUntilExecute() + // Close the context immediately after the first execution to prevent a second cron + // firing before assertions complete, which would produce extra traces and cause flakiness. + context.close() expect: assert task != null @@ -54,13 +58,10 @@ class SpringSchedulingTest extends InstrumentationSpecification { } } and: - def scheduledTaskEndpoint = context.getBean(ScheduledTasksEndpoint) assert scheduledTaskEndpoint != null scheduledTaskEndpoint.scheduledTasks().getCron().each { it.getRunnable().getTarget() == TriggerTask.getName() } - cleanup: - context.close() } def "schedule interval test"() { From 072361c6b52ffd1c534f95e6251fb13c4a2105d3 Mon Sep 17 00:00:00 2001 From: bm1549 Date: Tue, 10 Mar 2026 16:01:41 -0400 Subject: [PATCH 2/2] Fix ConditionNotSatisfiedError by capturing cron tasks before context close The scheduledTaskEndpoint.scheduledTasks() call fails after context.close() because the endpoint is no longer available. Capture the cron tasks list in setup: before closing the context so the and: assertion block uses the pre-captured value. Co-Authored-By: Claude Sonnet 4.6 --- .../src/latestDepTest/groovy/SpringSchedulingTest.groovy | 4 +++- .../src/test/groovy/SpringSchedulingTest.groovy | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/latestDepTest/groovy/SpringSchedulingTest.groovy b/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/latestDepTest/groovy/SpringSchedulingTest.groovy index 523dd209a2c..f604744aa39 100644 --- a/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/latestDepTest/groovy/SpringSchedulingTest.groovy +++ b/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/latestDepTest/groovy/SpringSchedulingTest.groovy @@ -28,6 +28,8 @@ class SpringSchedulingTest extends InstrumentationSpecification { def scheduledTaskEndpoint = context.getBean(ScheduledTasksEndpoint) task.blockUntilExecute() + // Capture cron tasks before closing the context (endpoint is unavailable after close). + def cronTasks = scheduledTaskEndpoint.scheduledTasks().getCron() // Close the context immediately after the first execution to prevent a second cron // firing before assertions complete, which would produce extra traces and cause flakiness. context.close() @@ -59,7 +61,7 @@ class SpringSchedulingTest extends InstrumentationSpecification { } and: assert scheduledTaskEndpoint != null - scheduledTaskEndpoint.scheduledTasks().getCron().each { + cronTasks.each { it.getRunnable().getTarget() == TriggerTask.getName() } } diff --git a/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/test/groovy/SpringSchedulingTest.groovy b/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/test/groovy/SpringSchedulingTest.groovy index 523dd209a2c..f604744aa39 100644 --- a/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/test/groovy/SpringSchedulingTest.groovy +++ b/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/test/groovy/SpringSchedulingTest.groovy @@ -28,6 +28,8 @@ class SpringSchedulingTest extends InstrumentationSpecification { def scheduledTaskEndpoint = context.getBean(ScheduledTasksEndpoint) task.blockUntilExecute() + // Capture cron tasks before closing the context (endpoint is unavailable after close). + def cronTasks = scheduledTaskEndpoint.scheduledTasks().getCron() // Close the context immediately after the first execution to prevent a second cron // firing before assertions complete, which would produce extra traces and cause flakiness. context.close() @@ -59,7 +61,7 @@ class SpringSchedulingTest extends InstrumentationSpecification { } and: assert scheduledTaskEndpoint != null - scheduledTaskEndpoint.scheduledTasks().getCron().each { + cronTasks.each { it.getRunnable().getTarget() == TriggerTask.getName() } }