test(ingestion): raw swap-race tests do not join the swapper goroutine; TempDir cleanup flakes CI #162

Closed
opened 2026-10-03 16:20:37 +00:00 by mathias · 1 comment
Owner

Found while reviewing PR #160. CI run 8912 (head 504feb3) went red on a test that PR does not touch.

--- FAIL: TestRawReadersLeakNothingUnderASymlinkSwapRace (1.50s)
    raw_race_test.go:89: 34972 iterations, 0 leaks
    testing.go:1464: TempDir RemoveAll cleanup: unlinkat .../001/raw: directory not empty

Cause: ingestion/internal/api/raw_race_test.go:77-90 starts go swap(raw, outside, false, &stop) and only does defer stop.Store(true). Nothing waits for the swapper to exit. t.TempDir's RemoveAll can therefore run while the swapper is still creating its tmp file in raw/, and the cleanup fails. The assertion itself passed (0 leaks). The FIFO sibling test (TestRawReadersDoNotHangUnderAFIFOSwapRace) probably has the same shape.

Fix: have swap signal completion (a WaitGroup or done channel), and wait on it before the test returns. A t.Cleanup registered after raceBrain runs before the TempDir cleanups, so it is the right place for that wait.

Done when: go test -race -count=50 ./internal/api/ -run SwapRace passes with zero cleanup errors.

Introduced by #156 (raw/ os.Root readers).

Found while reviewing PR #160. CI run 8912 (head 504feb3) went red on a test that PR does not touch. ``` --- FAIL: TestRawReadersLeakNothingUnderASymlinkSwapRace (1.50s) raw_race_test.go:89: 34972 iterations, 0 leaks testing.go:1464: TempDir RemoveAll cleanup: unlinkat .../001/raw: directory not empty ``` **Cause:** `ingestion/internal/api/raw_race_test.go:77-90` starts `go swap(raw, outside, false, &stop)` and only does `defer stop.Store(true)`. Nothing waits for the swapper to exit. `t.TempDir`'s RemoveAll can therefore run while the swapper is still creating its tmp file in `raw/`, and the cleanup fails. The assertion itself passed (0 leaks). The FIFO sibling test (`TestRawReadersDoNotHangUnderAFIFOSwapRace`) probably has the same shape. **Fix:** have `swap` signal completion (a WaitGroup or done channel), and wait on it before the test returns. A `t.Cleanup` registered after `raceBrain` runs before the TempDir cleanups, so it is the right place for that wait. **Done when:** `go test -race -count=50 ./internal/api/ -run SwapRace` passes with zero cleanup errors. Introduced by #156 (raw/ os.Root readers).
Author
Owner

Fixed in #160 (c986df6 on main). Every swap-race swapper (api raw races, the docmark race, the watcher FIFO race, and the search races from #161) is now stopped and awaited in a t.Cleanup registered after t.TempDir, so it runs before the directory is removed.

Done-when, verified on main: go test -race -count=50 ./internal/api/ -run SwapRace passes (226 s), with zero cleanup errors. Closing.


Created via git-mcp on behalf of @mathias

Fixed in #160 (`c986df6` on main). Every swap-race swapper (api raw races, the docmark race, the watcher FIFO race, and the search races from #161) is now stopped and awaited in a `t.Cleanup` registered after `t.TempDir`, so it runs before the directory is removed. Done-when, verified on main: `go test -race -count=50 ./internal/api/ -run SwapRace` passes (226 s), with zero cleanup errors. Closing. --- _Created via git-mcp on behalf of @mathias_
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/hyperguild#162