Skip to content

test: fix flaky test_scheduler_runs_due_task_and_advances near minute boundaries#209

Open
CyberDefenseOperations wants to merge 1 commit into
andrewyng:mainfrom
CyberDefenseOperations:contrib/fix-flaky-scheduler-test
Open

test: fix flaky test_scheduler_runs_due_task_and_advances near minute boundaries#209
CyberDefenseOperations wants to merge 1 commit into
andrewyng:mainfrom
CyberDefenseOperations:contrib/fix-flaky-scheduler-test

Conversation

@CyberDefenseOperations

Copy link
Copy Markdown

The test forces an every-minute cron task due and sleeps a fixed 0.2s with tick_seconds=0.05. After the first (catch-up) run the scheduler correctly advances next_run to the next minute boundary; when the test happens to start within ~0.2s of a minute boundary, that recomputed boundary falls inside the sleep window and the task legitimately fires a second time, failing assert ran == [t.id] with ['task-X','task-X'].

This is a harness race, not a scheduler bug — the running-guard (_running_ids) and the synchronous post-run advance are correct, and the second fire is the next real cron occurrence. Reproduced deterministically by shifting the store clock to 0.1s before a minute boundary.

Fix: wait on an asyncio.Event set by the fake runner instead of sleeping a fixed window, and stop the scheduler immediately after the first run — the advance completes synchronously once the runner returns, so no further tick can fire. Verified 15/15 in a loop plus the adversarial minute-boundary repro; the single-fire and advance assertions are unchanged.

… boundaries

The test forces an every-minute cron task due and sleeps a fixed 0.2s with
tick_seconds=0.05. After the first (catch-up) run the scheduler correctly
advances next_run to the next minute boundary; when the test happens to start
within ~0.2s of a boundary, that boundary falls inside the sleep window and
the task legitimately fires a second time, failing 'assert ran == [t.id]'.
Harness race, not a scheduler bug (the running-guard and post-run advance are
correct). Wait on an event set by the fake runner and stop the scheduler
immediately after the first run - the advance is synchronous once the runner
returns, so no second tick can fire. Verified 15/15 plus an adversarial
shifted-clock repro at the minute boundary.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant