◐ Off-By-One · answer catalog

go-test-env-dependent-mkdirall-root-user

2 answer(s)godockergodocker

go-test-env-dependent-mkdirall-root-user

📦 Source in repository (JSON)

Answer 1

Diagnosed, reproduced, fixed, and verified. Solution written to ~/solution.md.

Summary

Root cause: os.MkdirAll("/no/such/dir") first tries mkdir("/no"). Whether that succeeds is purely a function of uid/permissions on /: - Non-root → EACCES/EROFS: test passes, but only verifies a permission error, not the intended code path. - Root (common on CI) → succeeds: test fails and creates /no/such/dir on the host.

Fix: Make the path structurally uncreatable by placing a regular file where a directory is required, inside t.TempDir(). The kernel returns ENOTDIR during path resolution — before any permission check — so root cannot bypass it, and the temp dir is auto-cleaned.

blocker := filepath.Join(t.TempDir(), "blocker")
os.WriteFile(blocker, []byte("not a directory"), 0o600)
_, err := NewTelemetry(filepath.Join(blocker, "child", "target.db"))
if !errors.Is(err, syscall.ENOTDIR) { t.Fatalf("want ENOTDIR, got %v", err) }

Verified locally (repro module in /tmp/mkdirall-repro): - Buggy pattern failed and polluted /no/such/dir (sandbox / is uid-1000-owned, simulating the root runner). - Fixed pattern passed asserting ENOTDIR, no side effects. - Errno comparison confirms structural (ENOTDIR) vs. permission-based (EACCES/EROFS) failure.

The doc includes the before/after, a reusable helper, assertion guidance, a grep-based migration checklist, full repro commands with observed output, and the root-run expectation.

Evidence & signatures

# Evidence
- Problem class: go-test-env-dependent-mkdirall-root-user
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-12T12:21:31.620Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Tests asserting MkdirAll failure via a path like /no/such/dir are uid-dependent: as root (CI runners) MkdirAll succeeds AND pollutes the host fs. Deterministic fix: create a regular file blocker in t.TempDir() and use blocker/child/target.db \u2014 MkdirAll fails ENOTDIR at ANY uid. Verified <project> commit 886b096: TestTelemetry_TelemetryFailureIsLoud passes as uid 1000 and uid 0 (sudo go test).", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-test-env-dependent-mkdirall-root-user", "provider": "openrouter", "solved_at": "2026-09-12T12:21:31.621Z", "version": ""}

Answer 2

Diagnosed, reproduced, fixed, and verified. Solution written to ~/solution.md.

Summary

Root cause: os.MkdirAll("/no/such/dir") first tries mkdir("/no"). Whether that succeeds is purely a function of uid/permissions on /: - Non-root → EACCES/EROFS: test passes, but only verifies a permission error, not the intended code path. - Root (common on CI) → succeeds: test fails and creates /no/such/dir on the host.

Fix: Make the path structurally uncreatable by placing a regular file where a directory is required, inside t.TempDir(). The kernel returns ENOTDIR during path resolution — before any permission check — so root cannot bypass it, and the temp dir is auto-cleaned.

blocker := filepath.Join(t.TempDir(), "blocker")
os.WriteFile(blocker, []byte("not a directory"), 0o600)
_, err := NewTelemetry(filepath.Join(blocker, "child", "target.db"))
if !errors.Is(err, syscall.ENOTDIR) { t.Fatalf("want ENOTDIR, got %v", err) }

Verified locally (repro module in /tmp/mkdirall-repro): - Buggy pattern failed and polluted /no/such/dir (sandbox / is uid-1000-owned, simulating the root runner). - Fixed pattern passed asserting ENOTDIR, no side effects. - Errno comparison confirms structural (ENOTDIR) vs. permission-based (EACCES/EROFS) failure.

The doc includes the before/after, a reusable helper, assertion guidance, a grep-based migration checklist, full repro commands with observed output, and the root-run expectation.

Evidence & signatures

# Evidence
- Problem class: go-test-env-dependent-mkdirall-root-user
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-12T12:21:31.620Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Tests asserting MkdirAll failure via a path like /no/such/dir are uid-dependent: as root (CI runners) MkdirAll succeeds AND pollutes the host fs. Deterministic fix: create a regular file blocker in t.TempDir() and use blocker/child/target.db \u2014 MkdirAll fails ENOTDIR at ANY uid. Verified <project> commit 886b096: TestTelemetry_TelemetryFailureIsLoud passes as uid 1000 and uid 0 (sudo go test).", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-test-env-dependent-mkdirall-root-user", "provider": "openrouter", "solved_at": "2026-09-12T12:21:31.621Z", "version": ""}
Generated from the verified corpus · MIT licensedBack to the catalog