Skip to content

fix(tests): make testLastDayCron deterministic#15809

Merged
AcevedoR merged 1 commit intodevelopfrom
fix/schedule-test-last-day-cron-flaky
Apr 30, 2026
Merged

fix(tests): make testLastDayCron deterministic#15809
AcevedoR merged 1 commit intodevelopfrom
fix/schedule-test-last-day-cron-flaky

Conversation

@AcevedoR
Copy link
Copy Markdown
Contributor

Summary

  • ScheduleTest.testLastDayCron() fails on the last day of any month because ZonedDateTime.now() is used as the previous trigger date
  • On a last-day (e.g. April 30), nextEvaluationDate correctly returns the last day of the next month, but the test expected the current month's last day
  • Fix: anchor now to withDayOfMonth(1) so the test always executes as if it is early in the month, making the next L-cron hit predictably within the same month

Root cause

The cron 0 12 L * * fires at noon on the last day of each month. When the test ran on April 30 at noon, the previous-trigger date was April 30 12:00, so nextEvaluationDate returned May 31 (day 31) — but the assertion expected day 30 (April's last day).

Test plan

  • ./gradlew :core:test --tests "io.kestra.plugin.core.trigger.ScheduleTest.testLastDayCron" passes locally
  • 1-line change, no production code touched

…rst of month

The test used ZonedDateTime.now() as the previous trigger date, which caused it
to fail whenever run on the last day of any month (e.g. April 30). On such days,
nextEvaluationDate correctly returns the last day of the *next* month, not the
current month, making the assertion fail. Forcing withDayOfMonth(1) ensures the
test always runs as if it is early in the month, so the next L-cron hit is
always within the same month.
@tchiotludo
Copy link
Copy Markdown
Member

OpenAPI Spec Changes (EE-generated)

No EE spec drift (EE branch: develop).

@AcevedoR AcevedoR requested a review from nkwiatkowski April 30, 2026 11:15
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

🐋 Docker image

ghcr.io/kestra-io/kestra-pr:15809
docker run --pull=always --rm -it -p 8080:8080 --user=root -v /var/run/docker.sock:/var/run/docker.sock -v /tmp:/tmp ghcr.io/kestra-io/kestra-pr:15809 server local

🧪 Java Unit Tests

TestsPassed ✅Skipped ⚠️FailedTime ⏱
Java Tests Report5304 ran5284 ✅20 ⚠️0 ❌51m 43s 437ms

@github-actions
Copy link
Copy Markdown
Contributor

Tests report quick summary:

success ✅ > tests: 5304, success: 5284, skipped: 20, failed: 0

unfold for details
Project Status Success Skipped Failed
cli success ✅ 47 0 0
core success ✅ 2447 0 0
executor success ✅ 45 0 0
jdbc success ✅ 15 0 0
jdbc-h2 success ✅ 647 0 0
jdbc-mysql success ✅ 639 0 0
jdbc-postgres success ✅ 642 0 0
processor success ✅ 7 0 0
queue success ✅ 39 0 0
runner-memory success ✅ 1 0 0
scheduler success ✅ 74 0 0
script success ✅ 37 0 0
storage-local success ✅ 64 0 0
tests success ✅ 2 0 0
webserver success ✅ 457 0 0
worker success ✅ 52 0 0
worker-controller success ✅ 89 0 0

Develocity build scan: https://develocity.kestra.io/s/4rkk65ntcjfeg


Flaky tests report quick summary:

failed ❌ > tests: 38, success: 36, skipped: 0, failed: 2

Project Status Success Skipped Failed
cli success ✅ 2 0 0
core success ✅ 5 0 0
jdbc-h2 success ✅ 6 0 0
jdbc-mysql success ✅ 7 0 0
jdbc-postgres success ✅ 6 0 0
scheduler failed ❌ 1 0 1
script success ✅ 2 0 0
webserver success ✅ 7 0 0
worker failed ❌ 0 0 1

Failed tests:

scheduler > io.kestra.scheduler.TriggerSchedulerTest > shouldSucceedScheduleConditionalScheduleTriggerGivenValidTimeZone() failed ❌ in 1.077
org.opentest4j.AssertionFailedError: 
expected: 1
 but was: 0

org.opentest4j.AssertionFailedError: 
expected: 1
 but was: 0
	at io.kestra.scheduler.TriggerSchedulerTest.shouldSucceedScheduleConditionalScheduleTriggerGivenValidTimeZone(TriggerSchedulerTest.java:306)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at io.micronaut.test.extensions.junit5.MicronautJunit5Extension$2.proceed(MicronautJunit5Extension.java:154)
	at io.micronaut.test.extensions.AbstractMicronautExtension.interceptEach(AbstractMicronautExtension.java:171)
	at io.micronaut.test.extensions.AbstractMicronautExtension$3.proceed(AbstractMicronautExtension.java:183)
	at io.micronaut.test.context.TestMethodInterceptor.interceptTest(TestMethodInterceptor.java:46)
	at io.micronaut.transaction.test.DefaultTestTransactionExecutionListener.lambda$interceptTest$0(DefaultTestTransactionExecutionListener.java:93)
	at io.micronaut.transaction.support.AbstractPropagatedStatusTransactionOperations.lambda$execute$2(AbstractPropagatedStatusTransactionOperations.java:68)
	at io.micronaut.transaction.TransactionCallback.apply(TransactionCallback.java:37)
	at io.micronaut.transaction.support.AbstractTransactionOperations.executeTransactional(AbstractTransactionOperations.java:339)
	at io.micronaut.transaction.support.AbstractTransactionOperations.executeWithNewTransaction(AbstractTransactionOperations.java:321)
	at io.micronaut.transaction.support.AbstractTransactionOperations.executeNew(AbstractTransactionOperations.java:235)
	at io.micronaut.transaction.support.AbstractTransactionOperations.doExecute(AbstractTransactionOperations.java:137)
	at io.micronaut.transaction.support.AbstractTransactionOperations.lambda$doExecute$0(AbstractTransactionOperations.java:122)
	at io.micronaut.data.connection.support.AbstractConnectionOperations.executeWithNewConnection(AbstractConnectionOperations.java:174)
	at io.micronaut.data.connection.support.AbstractConnectionOperations.execute(AbstractConnectionOperations.java:114)
	at io.micronaut.transaction.support.AbstractTransactionOperations.doExecute(AbstractTransactionOperations.java:120)
	at io.micronaut.transaction.support.AbstractPropagatedStatusTransactionOperations.execute(AbstractPropagatedStatusTransactionOperations.java:65)
	at io.micronaut.transaction.test.DefaultTestTransactionExecutionListener.interceptTest(DefaultTestTransactionExecutionListener.java:91)
	at io.micronaut.test.extensions.AbstractMicronautExtension.interceptEach(AbstractMicronautExtension.java:175)
	at io.micronaut.test.extensions.AbstractMicronautExtension.interceptTest(AbstractMicronautExtension.java:128)
	at io.micronaut.test.extensions.junit5.MicronautJunit5Extension.interceptTestMethod(MicronautJunit5Extension.java:141)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)

worker > io.kestra.worker.WorkerTest > shouldKillTasksWhenExecutionKillEventReceived() failed ❌ in 14.266
java.lang.AssertionError: 
Expected size: 3 but was: 2 in:
[State.History(state=CREATED, date=2026-04-30T11:25:28.301635879Z),
    State.History(state=KILLED, date=2026-04-30T11:25:28.967000395Z)]

java.lang.AssertionError: 
Expected size: 3 but was: 2 in:
[State.History(state=CREATED, date=2026-04-30T11:25:28.301635879Z),
    State.History(state=KILLED, date=2026-04-30T11:25:28.967000395Z)]
	at io.kestra.worker.WorkerTest.shouldKillTasksWhenExecutionKillEventReceived(WorkerTest.java:192)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at io.micronaut.test.extensions.junit5.MicronautJunit5Extension$2.proceed(MicronautJunit5Extension.java:154)
	at io.micronaut.test.extensions.AbstractMicronautExtension.interceptEach(AbstractMicronautExtension.java:171)
	at io.micronaut.test.extensions.AbstractMicronautExtension.interceptTest(AbstractMicronautExtension.java:128)
	at io.micronaut.test.extensions.junit5.MicronautJunit5Extension.interceptTestMethod(MicronautJunit5Extension.java:141)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)

Copy link
Copy Markdown
Contributor

@nkwiatkowski nkwiatkowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@AcevedoR AcevedoR merged commit 2d5245c into develop Apr 30, 2026
11 of 12 checks passed
@AcevedoR AcevedoR deleted the fix/schedule-test-last-day-cron-flaky branch April 30, 2026 12:16
@github-project-automation github-project-automation Bot moved this from To review to Done in Pull Requests Apr 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants