Skip to content

test: use filesystem-safe temp dir names in sync runner tests - #468

Merged
dubadub merged 1 commit into
mainfrom
fix/windows-temp-dir-test-paths
Aug 30, 2026
Merged

test: use filesystem-safe temp dir names in sync runner tests#468
dubadub merged 1 commit into
mainfrom
fix/windows-temp-dir-test-paths

Conversation

@dubadub

@dubadub dubadub commented Aug 30, 2026

Copy link
Copy Markdown
Member

Problem

Four sync::runner tests fail on windows-latest only, blocking CI on main (run 33329650752):

thread 'sync::runner::tests::auth_rejected_clears_the_session_and_deletes_the_file' panicked at src\sync\runner.rs:559:39:
called `Result::unwrap()` on an `Err` value: Os { code: 267, kind: NotADirectory, message: "The directory name is invalid." }
  • auth_rejected_clears_the_session_and_deletes_the_file
  • file_age_secs_reports_recent_write_as_near_zero
  • successful_renewal_replaces_the_session_and_records_the_time
  • transient_failure_keeps_the_session_and_the_file

Cause

Both test helpers named their temp directory with {:?} of an Instant:

cookcli-runner-test-15720-Instant { tv_sec: 131419, tv_nsec: 294253417 }

That path component contains :, spaces and braces. Legal on Unix, illegal on Windows — so create_dir_all could never succeed there. Test fixtures only; nothing in the production code path was wrong.

Fix

Build the unique suffix from the pid plus a per-process AtomicUsize counter — filesystem-safe everywhere, and still collision-free across parallel test threads and concurrent test binaries.

file_age_secs_reports_recent_write_as_near_zero had duplicated the same bad snippet inline, so it now shares the temp_session_path helper instead of carrying its own copy.

Verification

cargo fmt, cargo clippy --all-targets clean, full cargo test suite green locally. Local runs are macOS, where these tests already passed — the Windows job on this PR is the real confirmation.

https://claude.ai/code/session_01V5XkBXdf8QdEho9QWQdFC8

The sync runner tests named their temp directory with `{:?}` of an
`Instant`, which renders as `Instant { tv_sec: 131419, tv_nsec: ... }`.
That component contains `:`, spaces and braces - legal in a Unix path,
illegal on Windows - so `create_dir_all` failed there with OS error 267
(NotADirectory) and four tests failed on windows-latest only.

Use a pid plus a per-process atomic counter for the unique suffix
instead: safe on every filesystem, still collision-free across parallel
test threads and concurrent test binaries.

`file_age_secs_reports_recent_write_as_near_zero` had its own inline
copy of the same snippet, so it now shares the `temp_session_path`
helper rather than carrying a second one.

Claude-Session: https://claude.ai/code/session_01V5XkBXdf8QdEho9QWQdFC8
@claude

claude Bot commented Aug 30, 2026

Copy link
Copy Markdown

Review

Small, well-scoped fix — replacing {:?} formatting of an Instant (which renders :, spaces, and braces — illegal in Windows path components) with a pid + per-process AtomicUsize counter for the temp-dir suffix. This directly matches the CI failure (Os { code: 267, kind: NotADirectory }) described in the PR body.

Code quality

  • The Instant-based approach was fragile from the start (its Debug output isn't documented/stable and was never meant for path components); the counter-based replacement is a clear improvement and the added doc comment on temp_session_path explains why, which is appropriate per the project's "only comment on non-obvious WHY" convention.
  • Good catch consolidating file_age_secs_reports_recent_write_as_near_zero's inline duplicate into the shared temp_session_path helper — reduces duplication without over-abstracting.
  • Instant import is still used elsewhere in the file (last_renewed_at: Option<Instant> etc.), so no dead-import risk from removing its use here.

Bugs / correctness

  • Uniqueness: the static AtomicUsize is scoped to the test binary, so within one process, concurrent test threads calling temp_session_path get distinct counter values (no TOCTOU between check and create_dir_all needed since names never collide). Across separate test binaries/processes, std::process::id() still differentiates them. This looks correct.
  • Each test still does let _ = std::fs::remove_dir_all(...) at the end for cleanup, consistent with prior behavior — no leaked temp dirs introduced.

Potential nit (non-blocking)

  • The counter resets to 0 on every test-binary invocation, so directory names are deterministic per run (cookcli-runner-test-<label>-<pid>-<n>). That's fine for uniqueness within/across a single run, but if two independent cargo test invocations somehow overlapped with the same pid (unlikely in practice) there'd be no cross-run entropy. Given std::process::id() is already part of the name and the old code had the same class of assumption, this isn't a regression — just noting it's not fully collision-proof in a pathological case.

Test coverage

  • No new tests added, which is appropriate here — this is a fix to test infrastructure itself, not product code. The PR body notes local runs are on macOS where these already passed, and the Windows CI run on this PR is the real verification; that seems like the right validation approach for a Windows-only path-handling bug.

Security / performance

  • No concerns — purely test-only code operating on OS temp directories with per-process/counter-based unique names.

Overall: a minimal, correct, well-justified fix. LGTM.

@dubadub
dubadub merged commit adb7ecd into main Aug 30, 2026
6 checks passed
@dubadub
dubadub deleted the fix/windows-temp-dir-test-paths branch August 30, 2026 20:43
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