From c6e49b177cd6bc103a0042eadfa5dee96a59aed1 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Sat, 31 Oct 2026 00:44:27 -0400 Subject: [PATCH] test(autosave): fix a flake: wait for the background write to finish, not just for its file Since #2518 the write syncs the folder after the rename, so the autosave file exists while the write is still running. Until it finishes the drawing is busy and the next change isn't planned, so the test's tick() returned None. Autosaver::writing() says whether a write is still running. Co-Authored-By: Claude Opus 5.5 --- crates/engine/src/autosave.rs | 7 +++++++ crates/engine/tests/autosave.rs | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/crates/engine/src/autosave.rs b/crates/engine/src/autosave.rs index c6b41cce4..9ff7eab0b 100644 --- a/crates/engine/src/autosave.rs +++ b/crates/engine/src/autosave.rs @@ -416,6 +416,13 @@ mod native { writes } + /// Whether a background write hasn't finished yet. Its file can exist before it finishes + /// (the folder is synced after the rename), and until [`Autosaver::reap`] takes it in, the + /// drawing is left out of planning. + pub fn writing(&self) -> bool { + self.running.iter().any(|(_, h)| !h.is_finished()) + } + /// Take in the writes that have finished ([`Autosaver::tick`] does this first). A drawing /// whose write failed is no longer counted as autosaved: the next plan restarts its clock, /// so it is tried again SAVETIME later even if it doesn't change. diff --git a/crates/engine/tests/autosave.rs b/crates/engine/tests/autosave.rs index da03c0d7d..f44be5231 100644 --- a/crates/engine/tests/autosave.rs +++ b/crates/engine/tests/autosave.rs @@ -185,6 +185,14 @@ fn autosave_files_are_written_in_the_background_and_removed_on_exit() { std::thread::sleep(Duration::from_millis(10)); } assert!(std::fs::read(&path).unwrap().ends_with(b"EOF\n")); + // The file exists before the write finishes (the folder sync comes after the rename); until + // it has, the drawing is busy and the change drawn below would not be planned. + for _ in 0..500 { + if !a.writing() { + break; + } + std::thread::sleep(Duration::from_millis(10)); + } // While the app runs, its lock keeps its files out of recovery. SAVETIME and SAVEFILEPATH // are system variables (process-wide, so set in this test only). assert_eq!(cadcraft_engine::sysvars::get(&s, "SAVETIME"), Some(json!(10)));