Skip to content

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

Open
ashproto wants to merge 2 commits into
nextfrom
fix/flaky-init-repo-tempdir
Open

fix: make the init-repo test fixture collision-proof under parallel threads#25
ashproto wants to merge 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant