docs/stripe-mock-port-steal.md
Rama main · réplica de lectura del repositorio original.
# The stripe-mock start-count test read a port somebody else had taken
This note is the worked example that AGENTS.md cites for "A written-down
diagnosis is a hypothesis, not a finding". It records a diagnosis that was
wrong, the correction, and the fixes that followed. It is documentation, not a
job. The wider port question it points at is issue #2296.
`test/scripts/stripe-mock/lifecycle.test.ts` — "stops trying once the mock has
been started as many times as asked" — failed on CI twice on commits that
changed only Markdown (PR #2065 run 31501332067, and PR #2104 run 32130150568 at
24,020 of 24,021 passing), and passed reliably locally.
**The first diagnosis recorded for this failure was wrong.** It said the parent
read the count file before the last `/bin/sh` had appended its line. It cannot:
a failing attempt ends at `await stopProcess(spawned.process, ...)`, and
`stopProcess` awaits the child's `status` on both of its branches —
`beforeTimeout` resolves when the status does, and the timeout branch awaits it
after the SIGKILL. Every spawned child has therefore exited, and written, before
`startStripeMock` rejects.
The real cause is a stolen port. `attemptStartStripeMock` has exactly one early
return before it spawns: the port is already listening, so an unpinned attempt
gives up and asks for another. `withUnusedPort` picks a free port and lets go of
it before the start binds it, so another suite can take it in between — and that
attempt never spawns, so the count comes up one short. The sibling test at
"gives a mock time to shut itself down" already guarded against exactly this
with `retryWhilePortTaken`; `triesBeforeGivingUp` did not.
`triesBeforeGivingUp` now takes the count it wants and retries on a fresh port
while it comes up short, over the same shared helper. `retryWhilePortTaken`
takes an optional description, read only once every try is spent, so a run that
never gets a clean port reports what it actually saw.