Skip to content

Stop a losing rm -rf race from failing a passing test - #613

Merged
jeremy merged 1 commit into
mainfrom
ci/nix-bats-teardown-flake
Aug 4, 2026
Merged

Stop a losing rm -rf race from failing a passing test#613
jeremy merged 1 commit into
mainfrom
ci/nix-bats-teardown-flake

Conversation

@jeremy

@jeremyjeremy commented Aug 4, 2026

Copy link
Copy Markdown
Member

Not part of the SDK stack — a flake I kept hitting while running bin/ci
against it, in a file #609 last touched.

What is observed

e2e/update_nix_flake.bats builds a throwaway git repo per test. Under
bats -j (which e2e/run.sh uses by default), teardown's rm -rf "$WORK"
intermittently fails with ENOTEMPTY:

not ok 365 records a corrected hash only after a rebuild proves it
# (from function `teardown' in test file update_nix_flake.bats, line 41)
# `rm -rf "$WORK"' failed
# rm: /var/folders/.../repo/.git/objects: Directory not empty
# rm: /var/folders/.../repo/.git: Directory not empty

bats counts a failing teardown as a failing test, so the assertion passed and
the test was reported red. The test name it lands on varies between runs — I saw
it on two different tests, which is itself the tell.

It hit twice in six local bin/ci runs, so it is frequent enough to cost
real CI runs and, worse, to train people to re-run on red.

What is not claimed

ENOTEMPTY says only that the directory was not empty when rm reached it during
parallel execution. It does not identify what put entries back, and I have not
established that. An earlier revision of this description asserted that something
"still holds .git/objects" — that was a guess dressed as a finding, and it is
withdrawn. The evidence supports "cleanup lost a race under -j", nothing
narrower.

That uncertainty is exactly why the fix is at the teardown rather than at a
presumed cause.

Fix

Retry briefly, then give up quietly. Cleanup should not decide whether a test
passed, and a leftover directory under $TMPDIR is worth less than a signal
people trust. This is a policy choice about teardown, and it holds regardless of
which actor wins the race.

Verification

  • 6 serial runs and 3 parallel (-j 10) runs of that file: 0 failures.
  • bin/ci exit 0.
  • Full remote suite on the exact head: 22 success / 2 skipped / 1 neutral /
    0 failures.

CopilotAI balanced review requested due to automatic review settings August 4, 2026 02:58
@github-actionsgithub-actionsBot added the tests Tests (unit and e2e) label Aug 4, 2026

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the teardown() function in e2e/update_nix_flake.bats to prevent a cleanup race from turning a passing test red. Under bats -j (parallel), each test builds a throwaway git repo in $TMPDIR; on macOS, rm -rf "$WORK" intermittently loses a race for .git/objects and fails with ENOTEMPTY. Since BATS counts a failing teardown as a failing test, this produced false CI failures. The fix retries the removal briefly and then gives up quietly so cleanup can never decide the test outcome. It fits into the broader e2e test suite added/touched by #609.

Changes:

  • Replace the single rm -rf "$WORK" in teardown with a short retry loop (3 attempts, 0.1s apart) that returns success on first successful removal.
  • Fall back to a final best-effort rm -rf ... || true and explicit return 0 so teardown always succeeds.
  • Add an explanatory comment documenting the race and rationale.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

update_nix_flake.bats builds a throwaway git repo per test, and under
`bats -j` teardown's `rm -rf` intermittently fails with ENOTEMPTY on
.git/objects. bats counts a failing teardown as a failing test, so a
green assertion gets reported red — twice in six local bin/ci runs,
landing on a different test name each time.
ENOTEMPTY says the directory was not empty when rm reached it. It does
not say what refilled it, and I have not established that, so the fix
goes at the teardown rather than at a presumed cause: retry briefly,
then give up quietly. Cleanup should not decide whether a test passed,
and a leftover directory under TMPDIR is worth less than a signal people
trust.
CopilotAI review requested due to automatic review settings August 4, 2026 04:14
@jeremy
jeremyforce-pushed the ci/nix-bats-teardown-flake branch from ded56b3 to b028138CompareAugust 4, 2026 04:14

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@jeremy
jeremy merged commit 7ca4336 into mainAug 4, 2026
25 checks passed
@jeremy
jeremy deleted the ci/nix-bats-teardown-flake branch August 4, 2026 04:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testsTests (unit and e2e)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jeremy