From 4b6a181aa2f8f5a618adba813408dd5456367629 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Oct 2026 06:53:35 +0000 Subject: [PATCH] Fix Windows flake in read-set replacement test a_read_set_notices_a_changed_file asserted that renaming a file with the same bytes over a.lock breaks the read set. On Windows the stat identity is the creation time, which NTFS tunnelling carries over to a file renamed onto a just-removed name, and mtime only moves every ~16 ms tick. A replacement inside the same tick keeps every stat, and the racy content compare finds the bytes the view read, so the set correctly holds and the assert fails intermittently. That evicted #1215 from the merge queue and failed a #1187 head. Assert the replacement with other same-length bytes on every platform (caught by mtime or by the content compare) and keep the same-bytes case on Unix, where (dev, ino, ctime) sees it. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../src/vendor/lock_inventory/view.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/crates/socket-patch-core/src/vendor/lock_inventory/view.rs b/crates/socket-patch-core/src/vendor/lock_inventory/view.rs index 5d150ebdb..44addc7a4 100644 --- a/crates/socket-patch-core/src/vendor/lock_inventory/view.rs +++ b/crates/socket-patch-core/src/vendor/lock_inventory/view.rs @@ -1175,11 +1175,23 @@ mod tests { // Rewritten in place with the same length. std::fs::write(root.join("a.lock"), "two").unwrap(); assert!(!set.unchanged(), "an in-place rewrite"); - // Replaced (rename over) with the same bytes. + // Replaced (rename over) with other bytes of the same length. let set = recorded(root, read).await.unwrap(); - std::fs::write(root.join("a.tmp"), "two").unwrap(); + std::fs::write(root.join("a.tmp"), "six").unwrap(); std::fs::rename(root.join("a.tmp"), root.join("a.lock")).unwrap(); assert!(!set.unchanged(), "a replacement"); + // Replaced with the same bytes: only Unix's (dev, ino, ctime) sees + // it. On Windows NTFS tunnelling gives the new file the old one's + // creation time and a write in the same ~16 ms tick keeps mtime, so + // every stat survives and the racy content compare finds the bytes + // the view read: the set rightly holds. + #[cfg(unix)] + { + let set = recorded(root, read).await.unwrap(); + std::fs::write(root.join("a.tmp"), "six").unwrap(); + std::fs::rename(root.join("a.tmp"), root.join("a.lock")).unwrap(); + assert!(!set.unchanged(), "a same-bytes replacement"); + } // A file that was missing appears. let set = recorded(root, read).await.unwrap(); std::fs::write(root.join("b.lock"), "late").unwrap();