Skip to content

test: fix temp-fixture directory collisions in parser test suites - #399

Merged
adamgell merged 1 commit into
mainfrom
claude/practical-leavitt-af7990
Aug 1, 2026
Merged

test: fix temp-fixture directory collisions in parser test suites#399
adamgell merged 1 commit into
mainfrom
claude/practical-leavitt-af7990

Conversation

@adamgell

@adamgell adamgell commented Jul 31, 2026

Copy link
Copy Markdown
Owner

Problem

src-tauri/tests/cmtlog_parser.rs had a race that made the whole test binary intermittently fail:

---- header_entry_parsed_correctly stdout ----
thread 'header_entry_parsed_correctly' panicked at src-tauri/tests/cmtlog_parser.rs:135:30:
index out of bounds: the len is 0 but the index is 0
test result: FAILED. 8 passed; 1 failed

TempLogFixture::new derived its temp directory name from SystemTime::now().duration_since(UNIX_EPOCH).as_nanos(). as_nanos() does not guarantee distinct values between calls; macOS clock granularity is coarser than a nanosecond, so two fixtures constructed within the same observed tick got the same directory path.

Each fixture also implemented Drop as fs::remove_dir_all(&self.dir). The test harness runs a binary's tests on parallel threads, so whichever test finished first deleted the other test's fixture file. The victim then read an empty/missing file, parsed zero entries, and panicked on result.entries[0].

This reproduced roughly 1 run in 5 of the full cargo test --locked suite on an M-series Mac. Running the single binary alone rarely reproduced it, since there is far less scheduling pressure.

Scope

The same time-derived pattern had been copied into four places, all with the same remove_dir_all destructor:

File Prefix
src-tauri/tests/cmtlog_parser.rs cmtrace-open-cmtlog-test-
src-tauri/tests/parser_regression_corpus.rs cmtrace-open-parser-regression-
src-tauri/tests/parser_expanded_corpus.rs cmtrace-open-expanded-
src-tauri/tests/common/mod.rs (TempBenchFile) cmtrace-open-bench-

tests/common/mod.rs is also pulled into benches/intune_pipeline.rs via #[path = "../tests/common/mod.rs"], so the benchmark fixture carried the defect too.

Fix

tempfile = "3" was already in [dev-dependencies], so each fixture now holds a TempDir built with TempDir::with_prefix(...). That takes uniqueness from the OS (random suffix plus O_EXCL retry) rather than from the clock, and TempDir's own Drop handles cleanup, so all four hand-rolled Drop impls are removed. Net 34 lines deleted.

The fixture structs keep the directory alive via a _dir: TempDir field; dropping it early would delete the directory out from under the still-live path.

Verification

  • 12 consecutive cargo test --locked runs, 785 tests each, zero failures
  • One cargo test --locked --all-features run, adding the feature-gated binaries including esp_diagnostics_sources, zero failures
  • cargo clippy --all-targets -- -D warnings clean
  • 5 further full suites after a collateral revert (below): still zero failures

Note

cargo fmt reformatted 13 unrelated files on this branch that were already non-conformant (12 under src-tauri/src/, plus tests/esp_diagnostics_sources.rs). That collateral was reverted to keep this diff minimal. There is no cargo fmt --check gate in .github/workflows/, so the drift is pre-existing and unenforced; worth cleaning up separately if desired.

Found while working #395, but entirely unrelated to it, so it lands on its own.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Improved test isolation by using dedicated temporary directories.
    • Automated cleanup of temporary test data to reduce leftover files and improve reliability.

`TempLogFixture::new` (and the shared `TempBenchFile`) derived their temp
directory name from `SystemTime::now().as_nanos()`. Clock granularity is
coarser than a nanosecond, so two fixtures constructed in the same observed
tick got the same path. Because each impl'd `Drop` as `remove_dir_all(&dir)`,
whichever test finished first deleted the other's fixture file; the victim
then parsed zero entries and panicked indexing `entries[0]`.

The harness runs each test binary's tests on parallel threads, so this made
`cargo test` intermittently fail (roughly 1 run in 5 on an M-series Mac).

Switch all four fixtures to `tempfile::TempDir` (already a dev-dependency),
which creates the directory with a genuinely unique name and removes it on
drop, so the hand-rolled `Drop` impls go away too.

Verified with 12 consecutive clean `cargo test --locked` runs plus one
`--all-features` run; `cargo clippy --all-targets -- -D warnings` is clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 31, 2026 17:54
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a02dc6ee-6345-425a-88ed-0b46cfd4b532

📥 Commits

Reviewing files that changed from the base of the PR and between 03e55c3 and 5e4527c.

📒 Files selected for processing (4)
  • src-tauri/tests/cmtlog_parser.rs
  • src-tauri/tests/common/mod.rs
  • src-tauri/tests/parser_expanded_corpus.rs
  • src-tauri/tests/parser_regression_corpus.rs

📝 Walkthrough

Walkthrough

Test fixtures across the parser test suites now use tempfile::TempDir for isolated directory creation and automatic cleanup. Timestamp-based paths, manual directory removal, and custom Drop implementations were removed.

Changes

Temporary fixture cleanup

Layer / File(s) Summary
Migrate test fixtures to TempDir
src-tauri/tests/cmtlog_parser.rs, src-tauri/tests/common/mod.rs, src-tauri/tests/parser_expanded_corpus.rs, src-tauri/tests/parser_regression_corpus.rs
Fixtures create prefixed TempDir instances, retain their handles, and derive file paths from them.
Remove manual cleanup
src-tauri/tests/cmtlog_parser.rs, src-tauri/tests/parser_regression_corpus.rs
Custom Drop implementations and recursive directory removal were deleted.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the fix for temporary fixture directory collisions in parser test suites.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes intermittent, parallel-test fixture collisions in the src-tauri parser test suites by switching from time-derived temp directory names (which can collide on coarse-granularity clocks) to tempfile::TempDir-managed unique directories. This stabilizes integration tests that create and clean up temp fixtures while the Rust test harness runs tests concurrently.

Changes:

  • Replaced SystemTime::now().as_nanos()-derived temp directory naming with TempDir::with_prefix(...) across affected test/bench fixtures.
  • Removed custom Drop implementations that manually remove_dir_all’d shared temp paths, relying on TempDir’s cleanup instead.
  • Updated fixture structs to retain the TempDir via a _dir: TempDir field so the directory outlives any paths derived from it.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src-tauri/tests/cmtlog_parser.rs Uses TempDir to create per-test unique fixture directories; removes manual cleanup Drop.
src-tauri/tests/parser_regression_corpus.rs Uses TempDir for unique temp fixtures to avoid cross-test directory collisions.
src-tauri/tests/parser_expanded_corpus.rs Migrates temp fixture directory creation to TempDir and removes manual directory deletion.
src-tauri/tests/common/mod.rs Updates shared bench/test fixture helper to use TempDir for safe unique directories and cleanup.

@adamgell adamgell added the enhancement New feature or request label Jul 31, 2026
@adamgell
adamgell merged commit 29ca9d7 into main Aug 1, 2026
17 of 19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants