Skip to content

fluentcart-mcp: stop the cancellation test racing the clock - #126

Merged
vcode-sh merged 1 commit into
mainfrom
fix/http-cancellation-flake
Aug 7, 2026
Merged

fluentcart-mcp: stop the cancellation test racing the clock#126
vcode-sh merged 1 commit into
mainfrom
fix/http-cancellation-flake

Conversation

@vcode-sh

@vcode-sh vcode-sh commented Aug 7, 2026

Copy link
Copy Markdown
Owner

removes active listeners on timeout and service shutdown slept a real 20ms against a 10ms timeout, then asserted the entry had expired. True on an idle machine; false whenever a loaded runner stretched the gap.

It failed the Node 26 lane and passed the Node 24 lane in the same CI run on #125 — about as clear a statement of wall-clock dependence as a test can make — then passed clean on re-run.

The fix

Fake timers, matching the tombstone test directly above it in the same file, with the clock advanced by exactly the timeout. Expiry becomes a fact rather than a margin.

Mutation-checked, because this is an easy thing to get wrong

A fake-timer test is a convenient way to write one that passes regardless of behaviour. Advancing 0 instead of 10 reproduces the original failure exactly — expected true to be false — so the assertion still tests expiry rather than the timer call. Restored, then run five times: 19/19 every time.

The close() in the new finally is a deliberate no-op: close() returns early on this.closed, and the test closes mid-body on purpose to exercise shutdown.

The other real-timer sleeps stay

Three remain in the suite — two in commerce/cache.test.ts, one in code-mode/sandbox.test.ts. They are a different shape: the sleep sits inside a loader or handler to simulate latency, so a slower runner lengthens the simulated work rather than invalidating the assertion. Coalescing still coalesces; a slow read is still slow. Only the cancellation test raced a deadline.

2823 unit tests, lint across 310 files, tests typecheck — all clean.

'removes active listeners on timeout and service shutdown' slept a real
20ms against a 10ms timeout and then asserted the entry had expired. True
on an idle machine; false whenever a loaded runner stretched the gap.
It failed the Node 26 lane and passed the Node 24 lane in the same CI
run, which is as clear a statement of wall-clock dependence as a test can
make.

Now on fake timers, matching the tombstone test directly above it, with
the clock advanced by exactly the timeout. Expiry becomes a fact rather
than a margin.

Mutation-checked, because a fake-timer test is an easy way to write one
that passes regardless: advancing 0 instead of 10 reproduces the original
failure exactly — expected true to be false — so the assertion still
tests expiry. Restored, then run five times: 19/19 each time.

The close() in the new finally block is a no-op, since close() returns
early on this.closed and the test closes mid-body on purpose.

The three remaining real-timer sleeps in the suite are a different shape:
they sit inside a loader or handler to simulate latency, so a slower
runner lengthens the simulated work rather than invalidating an
assertion. Left alone.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@vcode-sh
vcode-sh merged commit 24be99a into main Aug 7, 2026
7 checks passed
@vcode-sh
vcode-sh deleted the fix/http-cancellation-flake branch August 7, 2026 23:38
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