Skip to content

fix: make the init-repo test fixture collision-proof under parallel threads - #25

Merged
ashproto merged 2 commits into
nextfrom
fix/flaky-init-repo-tempdir
Aug 8, 2026
Merged

fix: make the init-repo test fixture collision-proof under parallel threads#25
ashproto merged 2 commits into
nextfrom
fix/flaky-init-repo-tempdir

Conversation

@ashproto

@ashproto ashproto commented Aug 8, 2026

Copy link
Copy Markdown
Owner

What

cargo test intermittently failed one of the four git_ops::tests::initialize_repository_* tests. Pre-existing flake, unrelated to any feature work.

Cause

TempFolder::new() built its path as git-it-init-test-{pid}-{nanos} and then called fs::create_dir(&path).unwrap(). All four tests run on parallel threads in one process, so the pid is shared and two threads can read the same nanosecond; create_dir then fails with AlreadyExists and the unwrap() panics. A different one of the four failed on each run, which is what made it look random.

Fix

Replace the wall-clock stamp with a process-wide AtomicU32 counter — the pattern the TempRepo fixtures in ops.rs and ops_worktree.rs already use. pid + counter cannot collide by construction.

Kept create_dir over create_dir_all deliberately: a collision is now impossible, so if one ever happens it should panic loudly rather than be absorbed. The now-unused SystemTime/UNIX_EPOCH import is removed.

Test plan

  • cargo test -p git-core initialize_repository -- --test-threads=1 — 4/4 pass
  • Five consecutive full cargo test runs, all green (the flake needed repetition to surface)
  • Rebuild produces no new warnings; the two that appear (git_may_fail, read_file) are pre-existing dead test helpers in other files

Note

Other TempRepo fixtures (ops_rewrite.rs, ops_remote.rs, graph.rs, ops_merge.rs) each define their own. Any that derive uniqueness from a timestamp rather than a counter could flake the same way under enough parallelism — not touched here since none are currently failing.

🤖 Generated with Claude Code

…hreads

TempFolder::new() named its directory git-it-init-test-{pid}-{nanos}. The
four initialize_repository tests run on parallel threads in one process, so
the pid is shared and two threads could read the same nanosecond; fs::create_dir
then failed with AlreadyExists and the unwrap() panicked. A different one of
the four failed on each run, which is what made it look random.

Replace the wall-clock stamp with a process-wide AtomicU32 counter, matching
the TempRepo fixtures in ops.rs and ops_worktree.rs. pid + counter cannot
collide by construction, so create_dir is kept over create_dir_all: a
collision should now be impossible, and would be a real bug worth panicking on.

Verified with five consecutive full cargo test runs, all green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4480001d54

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/git-core/src/git_ops.rs Outdated
The previous commit claimed pid + counter "cannot collide by construction"
and kept `create_dir` over `create_dir_all` on that basis. That reasoning
only holds among LIVE processes. The counter restarts at zero every run, so
uniqueness rests entirely on the pid never repeating — and a pid is unique
only while its process is alive. A run killed before `Drop` (Ctrl-C on
cargo test, or a panic=abort) leaves its directories behind; once the OS
recycles that pid, a fresh process counting from zero reproduces the exact
same path and `create_dir(...).unwrap()` panics with AlreadyExists.

Not hypothetical: this machine currently holds 36 orphaned `gte-*` fixture
directories spanning 18 distinct pids.

Remove any leftover first, then `create_dir_all` — the same two lines the
TempRepo fixtures in ops.rs, ops_worktree.rs, ops_merge.rs, ops_rewrite.rs
and graph.rs already use. Those fixtures were right and this one was the
outlier; the extra line is the point, not redundancy.

Reported by Codex review on #25. cargo test -p git-core: 183 passed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ashproto ashproto added the skip-build Infra/bootstrap PR: skip release build; may target main directly label Aug 8, 2026
@ashproto
ashproto merged commit 67db4c7 into next Aug 8, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-build Infra/bootstrap PR: skip release build; may target main directly

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant