From 4a1bd05b7c8758790385b6ca5cff3995e7ee6696 Mon Sep 17 00:00:00 2001 From: Stephen Waits Date: Fri, 30 Oct 2026 13:58:55 -0600 Subject: [PATCH] test(store): tree() leaves out the lock files too (P11c) Run 13 failed at the same helper: the store holds LockFileEx locks on wanderbooks.lock and books.lock, which are mandatory on Windows, so reading them is refused. tree() skips any *.lock and the live SQLite files at any depth. The other read_dir walkers in the store, cli and gui tests either read only metadata or copy closed books; the cli harness's book_files already tolerates a refused read. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp --- crates/ledger-store/tests/spec_store.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/crates/ledger-store/tests/spec_store.rs b/crates/ledger-store/tests/spec_store.rs index 5f13dca..6c6a38b 100644 --- a/crates/ledger-store/tests/spec_store.rs +++ b/crates/ledger-store/tests/spec_store.rs @@ -125,6 +125,12 @@ fn line_types(dir: &Path) -> Vec { .collect() } +/// Whether `p` is a lock file (`wanderbooks.lock`, `books.lock`, and any +/// other `*.lock`): it holds no data. +fn is_lock_file(p: &Path) -> bool { + p.extension().is_some_and(|x| x == "lock") +} + /// Whether `p` is the live SQLite database or one of its companions. fn is_live_database(p: &Path) -> bool { let name = p.file_name().unwrap().to_string_lossy().into_owned(); @@ -135,18 +141,20 @@ fn is_live_database(p: &Path) -> bool { .any(|x| name == format!("{db}{x}")) } -/// Every file under `dir` (relative path → bytes), the live database and -/// its companions left out. +/// Every file under `dir` (relative path → bytes), the live database, its +/// companions and the lock files left out. fn tree(dir: &Path) -> BTreeMap> { fn walk(root: &Path, d: &Path, out: &mut BTreeMap>) { for e in std::fs::read_dir(d).unwrap() { let p = e.unwrap().path(); if p.is_dir() { walk(root, &p, out); - } else if p.parent() == Some(root) && is_live_database(&p) { + } else if is_live_database(&p) || is_lock_file(&p) { // An open SQLite connection holds byte-range locks on its - // database file on Windows: a plain read is refused. The - // tests compare the journal, blobs and kept-aside files. + // database file on Windows, and so does the store on its + // lock files (LockFileEx is mandatory there): a plain read + // is refused. The tests compare the journal, blobs and + // kept-aside files. } else { out.insert( p.strip_prefix(root).unwrap().to_path_buf(),