Skip to content

the #387 bounded-diff test exceeds its 5s budget on windows-latest, then EBUSY on cleanup #542

Description

@SUaDtL

The failure

farm.test.ts > farm artifact publication (#397 / #387) > #387: the unavailable-diff list is bounded and still reports the true total fails on windows-latest with two errors:

Error: Test timed out in 5000ms.
 ❯ farm.test.ts:1730:3

Error: EBUSY: resource busy or locked, rmdir
'C:\Users\RUNNER~1\AppData\Local\Temp\farm-artifacts-…'
 ❯ farm.test.ts:1488:5   (afterEach)

Observed at 5331ms against a 5000ms budget — it is over by ~7%, not by an order of magnitude. Passes on ubuntu-latest; passes locally on Windows.

Two distinct problems, in order

  1. The budget. This case plans 12 tasks at FARM_CONCURRENCY: 6, each spawning a gate process. A GitHub Windows runner is materially slower at process creation than a developer box, and it is the heaviest case in the file.
  2. The cleanup. The afterEach rmSync then hits EBUSY, because the timeout abandoned the run mid-flight and something still holds the temp directory. This is the more interesting half: a timed-out run leaks a live handle, and the teardown reports it as a second failure that obscures the first.

Why it is NOT #515

#515 was a genuine race — concurrent git worktree add reading a sibling's half-written commondir, fixed under a worktree lock in #534, with the failure signature worktree add failed: … failed to read .git/worktrees/<other>/commondir.

That signature does not appear here. This is a wall-clock budget on a slow host, and the escalation #515 described is absent. Same test, different cause — worth stating plainly, because the obvious reading is that #515 regressed and it did not.

Note the lock added in #534 serializes the (short) registry calls; on a host this slow that is a plausible contributor to the margin and should be measured rather than assumed.

How it surfaced

plugins/ca/tools had never run on Windows in CI — the tools job is ubuntu-latest only. #521's coverage-union job added a windows-latest cell, and #539 cleared the containment failure that was masking everything behind it.

Acceptance criteria

  • AC-1: the margin is measured on windows-latest rather than guessed — how long this case actually takes there, and how much of it is process creation versus the serialized registry calls.
  • AC-2: the budget fits the slowest supported host with headroom, or the case is made cheaper without weakening what it asserts. It must still prove the unavailable-diff list is bounded at 11 while reporting a true total of 12, and FARM_CONCURRENCY must stay at 6 — flaky: a task escalates under full-suite load, flipping exit 0 to 2 in the farm artifact-publication tests #515 AC-4 applies unchanged.
  • AC-3: a timed-out run releases its handles, so afterEach cannot fail with EBUSY and bury the real error. A teardown failure must never be the loudest thing in the log.
  • AC-4: the test passes across repeated windows-latest runs.

Not in scope

Found while closing #539. Filed separately from #515 (fixed, different cause) and #541 (a worktree-fs refusal in the same CI run).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions