Development record
Tests that build a throwaway git repository through gittest.Env and their own git init still let git spawn detached background maintenance (gc --auto, maintenance.auto), which races the test's cleanup and its own tree walks: the merge queue dropped PR 590 twice on this class within one hour — TestTagAndExplicitKeyShapesAreRecognised (internal/core/reading/assemble_test.go:1241) failed on 'TempDir RemoveAll cleanup: .git/objects: directory not empty', and TestAssembleDryRunWritesNothing (internal/surface/cli/reading_surface_test.go:218) failed on 'lstat .git/objects/maintenance.lock: no such file or directory' on the macOS leg. iss-252 closed this for gittest.NewRepo by writing gc.auto=0, gc.autodetach=false and maintenance.auto=false into the fixture repo's local config, but a test that inits its own repository under gittest.Env gets none of that, and gitutil's isolated environment deliberately scrubs the parent's GIT_CONFIG_COUNT injection without supplying its own. The lifeboat package works around it with a TestMain and an allowlist exemption from the hermetic-git rule. The class remedy is to carry the three async-disable keys in the isolated environment itself, so every isolated git call, abcd's own subprocesses included, runs without detached maintenance and every fixture inherits it.
Tests that build a throwaway git repository through gittest.Env and their own git init still let git spawn detached background maintenance (gc --auto, maintenance.auto), which races the test's cleanup and its own tree walks: the merge queue dropped PR 590 twice on this class within one hour — TestTagAndExplicitKeyShapesAreRecognised (internal/core/reading/assemble_test.go:1241) failed on 'TempDir RemoveAll cleanup: .git/objects: directory not empty', and TestAssembleDryRunWritesNothing (internal/surface/cli/reading_surface_test.go:218) failed on 'lstat .git/objects/maintenance.lock: no such file or directory' on the macOS leg. iss-252 closed this for gittest.NewRepo by writing gc.auto=0, gc.autodetach=false and maintenance.auto=false into the fixture repo's local config, but a test that inits its own repository under gittest.Env gets none of that, and gitutil's isolated environment deliberately scrubs the parent's GIT_CONFIG_COUNT injection without supplying its own. The lifeboat package works around it with a TestMain and an allowlist exemption from the hermetic-git rule. The class remedy is to carry the three async-disable keys in the isolated environment itself, so every isolated git call, abcd's own subprocesses included, runs without detached maintenance and every fixture inherits it.
Grounds
- pursued: the race is a property of the environment every fixture inherits, so the environment is the one canonical home for the remedy; a per-fixture config (iss-252) reaches only the fixtures that use it, as two queue drops in one hour showed
Frontmatter
| id | iss-2609020319494139 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | major |
.abcd/work/issues/resolved/iss-2609020319494139-tests-that-build-a-throwaway-git.md
open on GitHub ↗ · commit history ↗
mentions1
- iss-252TestEmitRefuses/an_added_record_carries_no_impact flakes on CI teardown: t.TempDir RemoveAll fails with 'unlinkat .../001/.git/objects: directory not empty' — the subtest's assertions pass, but a background git process spawned in the scratch repo (auto-gc/maintenance or fsmonitor) is still writing objects when cleanup runs. First observed on the v0.5.0 release verify job (run 31960563726), where it fail-closed the whole release after the tag was pushed; a rerun recovered it. Fix direction: the gittest scratch-repo helper should disable background maintenance (gc.auto=0, maintenance.auto=false, core.fsmonitor=false) at init so no child process outlives the test. Detector: the release verify Test step; acceptance: the suite survives teardown on CI without rerun.