From 8ac4e5438d6636266993fe63d043d7fb0c99c3b0 Mon Sep 17 00:00:00 2001 From: Stephen Waits Date: Wed, 14 Oct 2026 14:46:01 -0600 Subject: [PATCH] mutants-gui timeout 300 s (tests compete with other mutants' builds); read_only test restores permissions on failure and sweeps leftovers from killed runs Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01GWVo7x3UHw5kwCUaWxiejX --- crates/ledger-gui/tests/read_only.rs | 32 ++++++++++++++++++++++++++++ justfile | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/crates/ledger-gui/tests/read_only.rs b/crates/ledger-gui/tests/read_only.rs index ce31337..513b919 100644 --- a/crates/ledger-gui/tests/read_only.rs +++ b/crates/ledger-gui/tests/read_only.rs @@ -67,8 +67,39 @@ fn set_read_only(root: &Path, read_only: bool) { walk(root, read_only); } +/// Makes the books writable again when dropped, so a failing or +/// interrupted run never leaves a folder no one can delete. +struct Writable(PathBuf); +impl Drop for Writable { + fn drop(&mut self) { + if self.0.exists() { + set_read_only(&self.0, false); + } + } +} + +/// Folders left read-only by a killed run (no destructor ran): made +/// writable and removed once their process is gone. +fn sweep_leftovers() { + let Ok(entries) = std::fs::read_dir(std::env::temp_dir()) else { + return; + }; + for e in entries.flatten() { + let name = e.file_name().to_string_lossy().to_string(); + let Some(pid) = name.strip_prefix("ledger-gui-ro-") else { + continue; + }; + if Path::new("/proc").join(pid).exists() { + continue; // still running (or the pid was reused): leave it + } + set_read_only(&e.path(), false); + let _ = std::fs::remove_dir_all(e.path()); + } +} + #[test] fn the_viewer_never_writes_into_the_books() { + sweep_leftovers(); let dir = std::env::temp_dir().join(format!("ledger-gui-ro-{}", std::process::id())); if dir.exists() { set_read_only(&dir, false); @@ -81,6 +112,7 @@ fn the_viewer_never_writes_into_the_books() { books_toml: Some(dir.join("wanderbooks.toml")), today: Some(today), }; + let _restore = Writable(dir.clone()); set_read_only(&dir, true); let before = tree(&dir); diff --git a/justfile b/justfile index 81d406e..3eb7853 100644 --- a/justfile +++ b/justfile @@ -102,7 +102,7 @@ mutants-mcp: # spec-tested, not swept. mutants-gui: mkdir -p {{mutants_tmp}} - PROPTEST_MAX_SHRINK_ITERS=0 TMPDIR={{mutants_tmp}} cargo mutants -p ledger-gui --test-package ledger-gui -j 4 --timeout 60 -o mutants-gui -f crates/ledger-gui/src/books.rs -f crates/ledger-gui/src/fmt.rs -- --lib --test spec_gui + PROPTEST_MAX_SHRINK_ITERS=0 TMPDIR={{mutants_tmp}} cargo mutants -p ledger-gui --test-package ledger-gui -j 4 --timeout 300 -o mutants-gui -f crates/ledger-gui/src/books.rs -f crates/ledger-gui/src/fmt.rs -- --lib --test spec_gui # Benchmarks of the core's hot paths (no budget gates them yet) bench: