test(plugins): the update-status test raced the millisecond clock - #74
Merged
Merged
Conversation
`UpdateScheduler.tick()` stamps its summary with
checkedAt: new Date().toISOString()
which has millisecond resolution. "replaces the previous pass rather than
accumulating" runs two ticks back to back with nothing slow between them
and asserted only that the two timestamps DIFFER:
expect(second.checkedAt).not.toBe(first.checkedAt);
When both ticks start inside the same millisecond the timestamps are
identical and the assertion fails:
AssertionError: expected '2026-08-22T11:43:29.404Z'
not to be '2026-08-22T11:43:29.404Z'
On this machine the unmodified test fails 23 times out of 30 runs. It has
been red intermittently across every PR opened today, and the failure
carries no hint of a clock — it reads like a logic bug in the scheduler,
which is worse than a test that simply fails.
Fakes Date for that one test and stamps the two passes six hours apart.
Only Date is faked, not setTimeout/setInterval, so the scheduler's real
async filesystem work is untouched and there is nothing to advance.
useFakeTimers is already used in four other backend suites.
The assertion is now stronger, not merely stable: with a controlled clock
it can pin both exact values rather than just their inequality, so a
summary that carried the OLD timestamp forward also fails — which the
previous version would have missed.
Restores real timers in afterEach so a failure inside that test cannot
leak a frozen clock into the rest of the file.
Fixed: 15/15 runs green. Full backend suite: 290/290, twice.
This was referenced Aug 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
backend/src/plugins/UpdateScheduler.status.test.js > replaces the previous pass rather than accumulatinghas been intermittently red onmainand on every PR opened today. This is the cause and the fix.Standalone and independent — one test file, no production code, no overlap with #70, #71, #72 or #73.
The race
UpdateScheduler.tick()stamps its summary with a millisecond-resolution timestamp:The test runs two ticks back to back with nothing slow between them, and asserted only that the two timestamps differ:
When both ticks start inside the same millisecond, the timestamps are identical:
On this machine the unmodified test fails 23 times out of 30 runs. It passes only when something happens to be slow enough between the two ticks.
The failure message is the part that makes this worth fixing rather than tolerating: it names no clock and reads like a logic bug in the scheduler, so anyone who hits it starts by investigating
UpdateScheduler— which is fine.The fix
Fake
Datefor that one test and stamp the two passes six hours apart.Dateis faked, notsetTimeout/setInterval, so the scheduler's real async filesystem work is untouched and there is nothing to advance.useFakeTimersis already used in four other backend suites (rateLimit,remoteTokenVerifier, and bothWorkflowProcessBridgesuites), so this is house style.That also catches a summary that carried the old timestamp forward, which
not.toBewould have reported as a pass in the very case the test exists to detect.afterEachrestores real timers, so a failure inside this test cannot leak a frozen clock into the rest of the file.Verification
Note
I previously described this as order-dependent, on the strength of a single isolated run that happened to pass. With a ~77% failure rate, one passing run is a 23% event — not evidence. Measuring it properly showed it fails in isolation too, and the real cause is the clock. Correcting that here so the record is right.