This commit is contained in:
+11
-10
@@ -84,7 +84,7 @@ test('a fully grounded fleet freezes the world clock (#135)', async ({ page }) =
|
||||
expect(after.simState.clockMs - c0, 'the grounded clock must stay frozen').toBe(0);
|
||||
});
|
||||
|
||||
test('a grounded fleet never starves: ignoring every open package cannot empty the market (#135 follow-up)', async ({ page }) => {
|
||||
test('a grounded fleet never starves: draining every open package cannot empty the market (#135 follow-up)', async ({ page }) => {
|
||||
// Self-heal to a fully grounded fleet first — that is what freezes the world clock (#135), and
|
||||
// the freeze is exactly what used to let the drain stick (no frozen tick spawned replacements).
|
||||
await expect
|
||||
@@ -100,23 +100,24 @@ test('a grounded fleet never starves: ignoring every open package cannot empty t
|
||||
expect(before.planes.every((p) => p.status === 'available'), 'fleet should be grounded at spec start').toBe(true);
|
||||
const clockBefore = before.simState.clockMs;
|
||||
|
||||
// Drain: ignore every open package, pass after pass. Pre-fix (v0.62.0) a frozen tick never
|
||||
// spawned replacements, so this reached zero and stayed there — the soft-lock. Post-fix every
|
||||
// request's tick re-tops-up BEFORE its removal, so the market can never empty; cap the passes to
|
||||
// bound runtime either way (a zero-open snapshot would mean the bug is back). v0.65.0: ignoring
|
||||
// starts each slot's refill cooldown (seconds in CI via FLIGHT_JOB_*_REFILL_MS), so the board
|
||||
// comes back a few seconds after the drain, not instantly.
|
||||
// Drain: expire every open package via the test hook (FLIGHT_TEST_HOOKS=1), pass after pass —
|
||||
// ignore was removed in v0.69.0 and loading can't drain a pool either (the starter's payload fits
|
||||
// only the lightest band). Pre-fix (v0.62.0) a frozen tick never spawned replacements, so this
|
||||
// reached zero and stayed there — the soft-lock. Post-fix every request's tick re-tops-up around
|
||||
// its removal, so the market can never empty; cap the passes to bound runtime either way (a
|
||||
// zero-open snapshot would mean the bug is back). Expired slots carry no refill cooldown, so the
|
||||
// board comes back on the very next tick.
|
||||
for (let pass = 0; pass < 3; pass++) {
|
||||
const s = await getState(page);
|
||||
const open = s.packages.filter((p) => p.status === 'open');
|
||||
if (open.length === 0) break; // drained — the pre-fix soft-lock state
|
||||
for (const p of open) {
|
||||
expect((await page.request.post(`/api/packages/${p.id}/ignore`)).status()).toBe(200);
|
||||
expect((await page.request.post('/api/test/expire-package', { data: { packageId: p.id } })).status()).toBe(200);
|
||||
}
|
||||
}
|
||||
|
||||
// The ~1 s background tick must refill the pool once the cooldowns lapse — within ~15 s of real
|
||||
// time (CI's heavy-job refill delay is 5 s, so allow headroom for dind slowness)…
|
||||
// Expired slots respawn immediately (no cooldown), so the ~1 s background tick must refill the
|
||||
// pool right away — within ~15 s of real time, with headroom for dind slowness…
|
||||
let topped: StateBody | undefined;
|
||||
await expect
|
||||
.poll(async () => {
|
||||
|
||||
Reference in New Issue
Block a user