mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-26 11:09:23 -06:00
Tests: the launch-list read-only test compares a held lock file without reading it
On Windows, tests_launch_library::listing_the_libraries_leaves_every_folder_byte_identical failed every time with os error 33. Its snapshot read every file in the folder, including the lock file of the library the test holds with LibraryLock::acquire. On Windows that lock is LockFileEx, and reading the locked bytes through another handle fails with ERROR_LOCK_VIOLATION. The snapshot now records each file's length as well as its contents and modification time. When the read of a catalog.lock fails with os error 33 on Windows, its contents are left out and the file is compared by its length and modification time. Every other file is still compared byte for byte, and on other platforms the held lock file is too. The app does not read a held lock file anywhere, so only the test changes.
This commit is contained in:
@@ -129,8 +129,8 @@ fn the_list_checks_each_library_and_selects_the_last_one() {
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
/// Every file under `dir`: relative path → (contents, modification time).
|
||||
fn snapshot(dir: &Path) -> std::collections::BTreeMap<PathBuf, (Vec<u8>, std::time::SystemTime)> {
|
||||
/// Every file under `dir`: relative path → (contents, length, modification time).
|
||||
fn snapshot(dir: &Path) -> std::collections::BTreeMap<PathBuf, (Option<Vec<u8>>, u64, std::time::SystemTime)> {
|
||||
let mut out = std::collections::BTreeMap::new();
|
||||
let mut todo = vec![dir.to_path_buf()];
|
||||
while let Some(d) = todo.pop() {
|
||||
@@ -140,13 +140,25 @@ fn snapshot(dir: &Path) -> std::collections::BTreeMap<PathBuf, (Vec<u8>, std::ti
|
||||
if m.is_dir() {
|
||||
todo.push(p.clone());
|
||||
}
|
||||
let bytes = if m.is_file() { std::fs::read(&p).unwrap() } else { Vec::new() };
|
||||
out.insert(p.strip_prefix(dir).unwrap().to_path_buf(), (bytes, m.modified().unwrap()));
|
||||
let (bytes, len) = if m.is_file() { (contents(&p), m.len()) } else { (Some(Vec::new()), 0) };
|
||||
out.insert(p.strip_prefix(dir).unwrap().to_path_buf(), (bytes, len, m.modified().unwrap()));
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// The bytes of the file `p`, or `None` for a lock file that a [`lightcraft_catalog::LibraryLock`]
|
||||
/// holds on Windows: there `LockFileEx` locks the file's bytes, and reading them through another
|
||||
/// handle fails with os error 33 (`ERROR_LOCK_VIOLATION`). Such a file is compared by its length
|
||||
/// and modification time only.
|
||||
fn contents(p: &Path) -> Option<Vec<u8>> {
|
||||
match std::fs::read(p) {
|
||||
Ok(bytes) => Some(bytes),
|
||||
Err(e) if cfg!(windows) && e.raw_os_error() == Some(33) && p.file_name().is_some_and(|n| n == lightcraft_catalog::lock::LOCK) => None,
|
||||
Err(e) => panic!("{}: {e}", p.display()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Listing the recent libraries (and drawing the window) writes nothing into any of them: no
|
||||
/// lock file, no owner file, nothing modified — free, held by another program or not a library.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user