Skip to content

test: stop a background writer failing teardown's rm - #23

Merged
ttncode merged 1 commit into
mainfrom
fix/flaky-workdir-teardown
Sep 13, 2026
Merged

ttncode merged 1 commit into
mainfrom
fix/flaky-workdir-teardown

Conversation

@ttncode

@ttncode ttncode commented Sep 13, 2026

Copy link
Copy Markdown
Owner

What this changes

tests/compose.bats has been failing on CI in teardown, not in any
assertion:

not ok 19 install.sh generates a password for every service that has one
# (from function `teardown' in test file tests/compose.bats, line 9)
#   `rm -rf "$WORKDIR"' failed
# rm: cannot remove '/tmp/tmp.K0zZ6SlOXR/demo': Directory not empty

rm -rf reports "Directory not empty" when an entry appears after it has
already walked the directory β€” something is still writing into the generated
project while the test that generated it is being torn down. compose.bats
generates a project per test and the lane runs --jobs $(nproc), so on a
four-core runner several laravel generations overlap.

It is a race, not a defect in any test: a different test loses it each run.
Across five runs of the same job it took down {12, 19, 26}, then {19}, then
{20}.

It is also not new, and not this branch's. Measured by re-running the same job
on the same commits: main fails one run in three, and every not ok is this
same teardown.

Two changes:

  • git config --global gc.auto 0 in the suite's own git configuration.
    scaffold new commits what it creates, and a commit can hand the repository
    to a detached git gc that outlives the command and keeps writing into
    .git. That is the likeliest writer this races. It was never caught in the
    act, so this is the suspect removed rather than the cause proven β€” a
    throwaway repository has nothing worth maintaining either way.
  • remove_workdir replaces the bare rm -rf "$WORKDIR" in all thirteen
    teardowns. It retries for five seconds, and if the tree is genuinely stuck it
    still fails the test and prints what is left in it β€” so the next occurrence
    arrives as a diagnosis instead of another mystery.

No test's assertions change.

How it was verified

  • bats tests/compose.bats β€” 17/17, the suite the failure lands in
  • mise run test-unit β€” no failures
  • mise run test-runner β€” both lanes
  • shellcheck on tests/helpers/setup.bash β€” clean for the added function
  • This PR's own CI

The retry cannot be proven to fire from here: the race has never reproduced
locally, across a full test-runner, three repeats of the individual test that
failed, and a probe that looked for processes holding the generated tree the
instant scaffold new returned. That is why the failure path reports rather
than just giving up.

Checklist

  • mise run lint passes
  • mise run test-runner passes
  • New behaviour has a test that fails without the change β€” n/a, and left
    unticked rather than claimed: this changes test infrastructure, and the
    race it removes has never reproduced outside CI, so there is nothing to
    write a failing test against
  • Docs that describe changed behaviour were updated in the same commit
  • No unrelated changes

@ttncode
ttncode merged commit e170714 into main Sep 13, 2026
22 checks passed
@ttncode
ttncode deleted the fix/flaky-workdir-teardown branch September 13, 2026 21:48
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