From daeec03a60a83f2b24fbc2738835d3c22603eb72 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Tue, 20 May 2025 15:18:49 -0400 Subject: [PATCH] Add watch run unit test --- Cargo.lock | 2 ++ cli-bin/Cargo.toml | 3 +++ cli-bin/src/cli/watch.rs | 17 ++++++++++++++++- cli-bin/src/lib.rs | 1 + cli-bin/tests/watch_unit.rs | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 cli-bin/src/lib.rs create mode 100644 cli-bin/tests/watch_unit.rs diff --git a/Cargo.lock b/Cargo.lock index ee9f8cc..4052d2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -691,7 +691,9 @@ dependencies = [ "ctrlc", "dirs 5.0.1", "glob", + "libc", "libmarlin", + "once_cell", "predicates", "rusqlite", "serde", diff --git a/cli-bin/Cargo.toml b/cli-bin/Cargo.toml index 68eae29..916e650 100644 --- a/cli-bin/Cargo.toml +++ b/cli-bin/Cargo.toml @@ -22,12 +22,15 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] } walkdir = "2.5" serde_json = { version = "1", optional = true } +once_cell = "1" [dev-dependencies] assert_cmd = "2" predicates = "3" tempfile = "3" dirs = "5" +once_cell = "1" +libc = "0.2" [features] # Enable JSON output with `--features json` diff --git a/cli-bin/src/cli/watch.rs b/cli-bin/src/cli/watch.rs index da81c64..4c3cc9f 100644 --- a/cli-bin/src/cli/watch.rs +++ b/cli-bin/src/cli/watch.rs @@ -11,6 +11,17 @@ use std::thread; use std::time::{Duration, Instant}; use tracing::info; +use once_cell::sync::Lazy; +use std::sync::Mutex; + +#[allow(dead_code)] +static LAST_WATCHER_STATE: Lazy>> = Lazy::new(|| Mutex::new(None)); + +#[allow(dead_code)] +pub fn last_watcher_state() -> Option { + LAST_WATCHER_STATE.lock().unwrap().clone() +} + /// Commands related to file watching functionality #[derive(Subcommand, Debug)] pub enum WatchCmd { @@ -84,7 +95,11 @@ pub fn run(cmd: &WatchCmd, _conn: &mut Connection, _format: super::Format) -> Re } info!("Watcher run loop ended. Explicitly stopping watcher instance..."); - watcher.stop()?; + watcher.stop()?; + { + let mut guard = LAST_WATCHER_STATE.lock().unwrap(); + *guard = Some(watcher.status().state); + } info!("Watcher instance fully stopped."); Ok(()) } diff --git a/cli-bin/src/lib.rs b/cli-bin/src/lib.rs new file mode 100644 index 0000000..4f77372 --- /dev/null +++ b/cli-bin/src/lib.rs @@ -0,0 +1 @@ +pub mod cli; diff --git a/cli-bin/tests/watch_unit.rs b/cli-bin/tests/watch_unit.rs new file mode 100644 index 0000000..574f714 --- /dev/null +++ b/cli-bin/tests/watch_unit.rs @@ -0,0 +1,35 @@ +use std::thread; +use std::time::Duration; +use tempfile::tempdir; + +use marlin_cli::cli::{watch, Format}; +use marlin_cli::cli::watch::WatchCmd; +use libmarlin::watcher::WatcherState; +use libmarlin::{self as marlin, db}; +use libc; + +#[test] +fn watch_start_and_stop_quickly() { + let tmp = tempdir().unwrap(); + let db_path = tmp.path().join("index.db"); + std::env::set_var("MARLIN_DB_PATH", &db_path); + + // create database + let _m = marlin::Marlin::open_default().unwrap(); + + let mut conn = db::open(&db_path).unwrap(); + + let path = tmp.path().to_path_buf(); + let cmd = WatchCmd::Start { path: path.clone(), debounce_ms: 50 }; + + // send SIGINT shortly after watcher starts + let t = thread::spawn(|| { + thread::sleep(Duration::from_millis(200)); + unsafe { libc::raise(libc::SIGINT) }; + }); + + watch::run(&cmd, &mut conn, Format::Text).unwrap(); + t.join().unwrap(); + + assert_eq!(watch::last_watcher_state(), Some(WatcherState::Stopped)); +}