fix(tests): stop pi-lifetime asserting the ceiling on a racing boundary - #6082
Conversation
`keeps the ceiling when the run outlives it` passed a deadline of exactly `PI_SANDBOX_MAX_LIFETIME_MS`, then asserted the resolved lifetime equalled that ceiling. But the lifetime is `Math.min(ceiling, deadline - Date.now())`, so the remaining budget decays below the ceiling as soon as one millisecond of test time elapses and `Math.min` returns the budget instead. It passed only when zero milliseconds happened to pass, which is why it failed CI as `expected 5399999 to be 5400000` — 1 failure in 16,047. Demonstrated: with the old input, a 5ms delay before the assertion yields 5399994 (off by 6ms); with a deadline 60s past the ceiling it yields 5400000 exactly, regardless of elapsed time. An equal deadline was also not the case the test name describes — the run has to *outlive* the ceiling, not match it — so raising it past the ceiling fixes the assertion and the intent together. Derives the input from `PI_SANDBOX_MAX_LIFETIME_MS` rather than restating 90 minutes, so the test cannot drift if the async execution ceiling moves. Also drops the old comment's claim that "the provider cap still wins": the provider cap is 24h, far above the 90m async ceiling, so the ceiling is what wins here.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryLow Risk Overview The test now uses a timeout deadline of Comments were updated to document that boundary behavior and drop the incorrect note about the provider cap winning over the async ceiling. Reviewed by Cursor Bugbot for commit f40c410. Configure here. |
Greptile SummaryFixes a flaky unit test by setting the abort deadline strictly above the PI sandbox lifetime ceiling so
Confidence Score: 5/5Safe to merge; the change only stabilizes a flaky test assertion with no production behavior change. The deadline is derived from the same constant the assertion checks, so remaining budget stays above the ceiling for the duration of the test and the equality holds without fake timers.
|
| Filename | Overview |
|---|---|
| apps/sim/lib/execution/remote-sandbox/pi-lifetime.test.ts | Correctly raises the test deadline past the lifetime ceiling so the clamp assertion is stable and matches the test name. |
Reviews (1): Last reviewed commit: "fix(tests): stop pi-lifetime asserting t..." | Re-trigger Greptile
Summary
pi-lifetime.test.ts > keeps the ceiling when the run outlives itis flaky. It failed CI tonight asAssertionError: expected 5399999 to be 5400000— 1 failure out of 16,047 tests.Root cause
The test passed a deadline of exactly
PI_SANDBOX_MAX_LIFETIME_MS(90 min), then asserted the resolved lifetime equalled that ceiling:But the resolved lifetime is
Math.min(ceiling, remaining), whereremainingisgetRemainingExecutionMs()=deadline - Date.now(). With the deadline set equal to the ceiling,remainingstarts at the ceiling and decays below it the instant any time elapses — soMath.minreturnsremaining, not the ceiling. The assertion held only when zero milliseconds passed between constructing the controller and reading it. A coin flip weighted by runner speed.Demonstrated, not guessed
The old input drifts by exactly the elapsed time. The new one is exact regardless.
The fix also repairs the test's intent
The name says the run outlives the ceiling — but a deadline equal to the ceiling isn't outliving it. Raising the deadline past the ceiling fixes the assertion and the intent together, and it's the case actually worth covering: a run whose deadline exceeds the ceiling should be clamped to the ceiling.
Derived from
PI_SANDBOX_MAX_LIFETIME_MS + 60_000rather than restating90 * 60 * 1000, so the test can't silently drift if the async execution ceiling moves — which is exactly how the original hardcoded value came to sit on the boundary.Also drops the old comment's claim that "the provider cap still wins". The provider cap is 24 h, far above the 90 min async ceiling, so the ceiling is what wins — the comment described the opposite of the mechanism.
Notes
Deliberately not reached for
vi.useFakeTimers(). Freezing the clock would mask the boundary rather than fix it, and the assertion would still be testing an input that contradicts the test's name. The sibling assertions in this file that compare against the ceiling (lines 103-104, 145) are safe — they use signals with no deadline, sogetRemainingExecutionMsreturnsundefinedand the ceiling is returned unconditionally.Type of Change
Testing
Fixed test run 5x, 16/16 passing each time. Mechanism verified directly against the real helpers (output above) rather than inferred from a green run — the old version passed most of the time too, so repetition alone proves nothing here.