Canonicalize test paths

This commit is contained in:
thePR0M3TH3AN
2025-05-26 16:51:39 -04:00
parent 4191b2d3ff
commit 892a444b32
3 changed files with 23 additions and 7 deletions

View File

@@ -45,12 +45,18 @@ pub fn determine_scan_root(pattern: &str) -> PathBuf {
} }
} }
/// Canonicalize a path, falling back to the original on error.
pub fn canonicalize_lossy<P: AsRef<Path>>(p: P) -> PathBuf {
std::fs::canonicalize(&p).unwrap_or_else(|_| p.as_ref().to_path_buf())
}
/// Convert a filesystem path to a normalized database path. /// Convert a filesystem path to a normalized database path.
/// ///
/// On Windows this replaces backslashes with forward slashes so that paths /// On Windows this replaces backslashes with forward slashes so that paths
/// stored in the database are consistent across platforms. /// stored in the database are consistent across platforms.
pub fn to_db_path<P: AsRef<Path>>(p: P) -> String { pub fn to_db_path<P: AsRef<Path>>(p: P) -> String {
let s = p.as_ref().to_string_lossy(); let canonical = canonicalize_lossy(p);
let s = canonical.to_string_lossy();
#[cfg(windows)] #[cfg(windows)]
{ {
s.replace('\\', "/") s.replace('\\', "/")

View File

@@ -6,7 +6,7 @@
//! watcher can be paused, resumed and shut down cleanly. //! watcher can be paused, resumed and shut down cleanly.
use crate::db::{self, Database}; use crate::db::{self, Database};
use crate::utils::to_db_path; use crate::utils::{canonicalize_lossy, to_db_path};
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use crossbeam_channel::{bounded, Receiver}; use crossbeam_channel::{bounded, Receiver};
use notify::{ use notify::{
@@ -256,13 +256,20 @@ impl FileWatcher {
// ── start actual OS watcher ─────────────────────────────────────────── // ── start actual OS watcher ───────────────────────────────────────────
let event_tx = tx.clone(); let event_tx = tx.clone();
let mut actual_watcher = RecommendedWatcher::new( let mut actual_watcher = RecommendedWatcher::new(
move |ev| { move |ev: Result<Event, notify::Error>| {
let ev = ev.map(|mut e| {
for p in &mut e.paths {
*p = canonicalize_lossy(&*p);
}
e
});
let _ = event_tx.send(ev); let _ = event_tx.send(ev);
}, },
notify::Config::default(), notify::Config::default(),
)?; )?;
for p in &paths { let canonical_paths: Vec<PathBuf> = paths.iter().map(canonicalize_lossy).collect();
for p in &canonical_paths {
actual_watcher actual_watcher
.watch(p, RecursiveMode::Recursive) .watch(p, RecursiveMode::Recursive)
.with_context(|| format!("Failed to watch path {}", p.display()))?; .with_context(|| format!("Failed to watch path {}", p.display()))?;
@@ -532,7 +539,7 @@ impl FileWatcher {
Ok(Self { Ok(Self {
state, state,
_config: config, _config: config,
watched_paths: paths, watched_paths: canonical_paths,
_event_receiver: rx, _event_receiver: rx,
_watcher: actual_watcher, _watcher: actual_watcher,
processor_thread: Some(processor_thread), processor_thread: Some(processor_thread),

View File

@@ -6,7 +6,7 @@ mod tests {
use crate::backup::BackupManager; use crate::backup::BackupManager;
// These are still from the watcher module // These are still from the watcher module
use crate::db::open as open_marlin_db; use crate::db::open as open_marlin_db;
use crate::utils::to_db_path; use crate::utils::{canonicalize_lossy, to_db_path};
use crate::watcher::{FileWatcher, WatcherConfig, WatcherState}; // Use your project's DB open function use crate::watcher::{FileWatcher, WatcherConfig, WatcherState}; // Use your project's DB open function
use crate::Marlin; use crate::Marlin;
@@ -24,13 +24,14 @@ mod tests {
expected: i64, expected: i64,
timeout: Duration, timeout: Duration,
) { ) {
let target = canonicalize_lossy(path);
let start = Instant::now(); let start = Instant::now();
loop { loop {
let count: i64 = marlin let count: i64 = marlin
.conn() .conn()
.query_row( .query_row(
"SELECT COUNT(*) FROM files WHERE path = ?1", "SELECT COUNT(*) FROM files WHERE path = ?1",
[to_db_path(path)], [to_db_path(&target)],
|r| r.get(0), |r| r.get(0),
) )
.unwrap(); .unwrap();
@@ -201,6 +202,7 @@ mod tests {
thread::sleep(Duration::from_millis(100)); thread::sleep(Duration::from_millis(100));
let new_file = dir.join("b.txt"); let new_file = dir.join("b.txt");
fs::rename(&file, &new_file).unwrap(); fs::rename(&file, &new_file).unwrap();
let new_file = canonicalize_lossy(&new_file);
wait_for_row_count(&marlin, &new_file, 1, Duration::from_secs(10)); wait_for_row_count(&marlin, &new_file, 1, Duration::from_secs(10));
watcher.stop().unwrap(); watcher.stop().unwrap();
assert!( assert!(
@@ -247,6 +249,7 @@ mod tests {
thread::sleep(Duration::from_millis(100)); thread::sleep(Duration::from_millis(100));
let new = dir.join("newdir"); let new = dir.join("newdir");
fs::rename(&sub, &new).unwrap(); fs::rename(&sub, &new).unwrap();
let new = canonicalize_lossy(&new);
for fname in ["one.txt", "two.txt"] { for fname in ["one.txt", "two.txt"] {
let p = new.join(fname); let p = new.join(fname);
wait_for_row_count(&marlin, &p, 1, Duration::from_secs(10)); wait_for_row_count(&marlin, &p, 1, Duration::from_secs(10));