diff --git a/Cargo.toml b/Cargo.toml index b5c1376..7c4b1c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,8 +45,8 @@ winapi = "^0.2.5" kernel32-sys = "^0.2.1" [dev-dependencies] -tempfile = "^2.0.1" tempdir = "^0.3.4" [features] timing_tests = [] +manual_tests = [] diff --git a/tests/fsevents.rs b/tests/fsevents.rs index ce35a35..b337def 100644 --- a/tests/fsevents.rs +++ b/tests/fsevents.rs @@ -1,445 +1,436 @@ +#![allow(dead_code)] + extern crate notify; extern crate tempdir; +extern crate time; mod utils; -use notify::*; -use std::sync::mpsc; -use tempdir::TempDir; +#[cfg(all(target_os = "macos", feature = "timing_tests"))] +mod timing_tests { + use notify::*; + use std::sync::mpsc; + use tempdir::TempDir; -use utils::*; + use utils::*; -const TIMEOUT_S: f64 = 5.0; + const TIMEOUT_S: f64 = 5.0; -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_create_delete_file_0() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + #[test] + fn fsevents_create_delete_file_0() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - sleep(10); + sleep(10); - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - tdir.create("file1"); - tdir.remove("file1"); + tdir.create("file1"); + tdir.remove("file1"); - let actual = recv_events_with_timeout(&rx, TIMEOUT_S); - if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { - panic!("single CREATE | REMOVE event"); - } else { - assert_eq!(actual, vec![ + let actual = recv_events_with_timeout(&rx, TIMEOUT_S); + if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { + panic!("single CREATE | REMOVE event"); + } else { + assert_eq!(actual, vec![ + (tdir.mkpath("file1"), op::CREATE, None), + (tdir.mkpath("file1"), op::CREATE | op::REMOVE, None), + ]); + } + } + + #[test] + fn fsevents_create_delete_file_1() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + + sleep(10); + + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + + tdir.create("file1"); + + assert_eq!(recv_events_with_timeout(&rx, 1.0), vec![ (tdir.mkpath("file1"), op::CREATE, None), - (tdir.mkpath("file1"), op::CREATE | op::REMOVE, None), ]); + + tdir.remove("file1"); + + let actual = recv_events_with_timeout(&rx, TIMEOUT_S); + if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { + panic!("excessive CREATE event"); + } else { + assert_eq!(actual, vec![ + (tdir.mkpath("file1"), op::REMOVE, None), + ]); + } } -} -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_create_delete_file_1() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + #[test] + fn fsevents_create_delete_file_2() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - sleep(10); + sleep(10); - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - tdir.create("file1"); + tdir.create("file1"); - assert_eq!(recv_events_with_timeout(&rx, 1.0), vec![ - (tdir.mkpath("file1"), op::CREATE, None), - ]); + assert_eq!(recv_events_with_timeout(&rx, 2.0), vec![ + (tdir.mkpath("file1"), op::CREATE, None), + ]); - tdir.remove("file1"); + tdir.remove("file1"); - let actual = recv_events_with_timeout(&rx, TIMEOUT_S); - if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { - panic!("excessive CREATE event"); - } else { + let actual = recv_events_with_timeout(&rx, TIMEOUT_S); + if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { + panic!("excessive CREATE event"); + } else { + assert_eq!(actual, vec![ + (tdir.mkpath("file1"), op::REMOVE, None), + ]); + } + } + + #[test] + fn fsevents_create_delete_file_4() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + + sleep(10); + + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + + tdir.create("file1"); + + assert_eq!(recv_events_with_timeout(&rx, 4.0), vec![ + (tdir.mkpath("file1"), op::CREATE, None), + ]); + + tdir.remove("file1"); + + let actual = recv_events_with_timeout(&rx, TIMEOUT_S); + if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { + panic!("excessive CREATE event"); + } else { + assert_eq!(actual, vec![ + (tdir.mkpath("file1"), op::REMOVE, None), + ]); + } + } + + #[test] + fn fsevents_create_delete_file_8() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + + sleep(10); + + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + + tdir.create("file1"); + + assert_eq!(recv_events_with_timeout(&rx, 8.0), vec![ + (tdir.mkpath("file1"), op::CREATE, None), + ]); + + tdir.remove("file1"); + + let actual = recv_events_with_timeout(&rx, TIMEOUT_S); + if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { + panic!("excessive CREATE event"); + } else { + assert_eq!(actual, vec![ + (tdir.mkpath("file1"), op::REMOVE, None), + ]); + } + } + + #[test] + fn fsevents_create_delete_file_16() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + + sleep(10); + + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + + tdir.create("file1"); + + assert_eq!(recv_events_with_timeout(&rx, 16.0), vec![ + (tdir.mkpath("file1"), op::CREATE, None), + ]); + + tdir.remove("file1"); + + let actual = recv_events_with_timeout(&rx, TIMEOUT_S); + if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { + panic!("excessive CREATE event"); + } else { + assert_eq!(actual, vec![ + (tdir.mkpath("file1"), op::REMOVE, None), + ]); + } + } + + #[test] + fn fsevents_create_delete_file_32() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + + sleep(10); + + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + + tdir.create("file1"); + + assert_eq!(recv_events_with_timeout(&rx, 32.0), vec![ + (tdir.mkpath("file1"), op::CREATE, None), + ]); + + tdir.remove("file1"); + + let actual = recv_events_with_timeout(&rx, TIMEOUT_S); + if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { + panic!("excessive CREATE event"); + } else { + assert_eq!(actual, vec![ + (tdir.mkpath("file1"), op::REMOVE, None), + ]); + } + } + + #[test] + fn fsevents_create_delete_file_64() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + + sleep(10); + + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + + tdir.create("file1"); + + assert_eq!(recv_events_with_timeout(&rx, 64.0), vec![ + (tdir.mkpath("file1"), op::CREATE, None), + ]); + + tdir.remove("file1"); + + let actual = recv_events_with_timeout(&rx, TIMEOUT_S); + if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { + panic!("excessive CREATE event"); + } else { + assert_eq!(actual, vec![ + (tdir.mkpath("file1"), op::REMOVE, None), + ]); + } + } + + #[test] + fn fsevents_rename_rename_file_0() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + + tdir.create_all(vec![ + "file1a", + ]); + + sleep(10); + + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + + tdir.rename("file1a", "file1b"); + tdir.rename("file1b", "file1c"); + + let actual = recv_events(&rx); + let cookies = extract_cookies(&actual); + assert_eq!(cookies.len(), 1); assert_eq!(actual, vec![ - (tdir.mkpath("file1"), op::REMOVE, None), + (tdir.mkpath("file1a"), op::CREATE | op::RENAME, None), + (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), + (tdir.mkpath("file1c"), op::RENAME, Some(cookies[0])), ]); } -} -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_create_delete_file_2() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + #[test] + fn fsevents_rename_rename_file_10() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - sleep(10); + tdir.create_all(vec![ + "file1a", + ]); - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + sleep(10); - tdir.create("file1"); + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - assert_eq!(recv_events_with_timeout(&rx, 2.0), vec![ - (tdir.mkpath("file1"), op::CREATE, None), - ]); + tdir.rename("file1a", "file1b"); + sleep(10); + tdir.rename("file1b", "file1c"); - tdir.remove("file1"); - - let actual = recv_events_with_timeout(&rx, TIMEOUT_S); - if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { - panic!("excessive CREATE event"); - } else { + let actual = recv_events(&rx); + let cookies = extract_cookies(&actual); + assert_eq!(cookies.len(), 2); assert_eq!(actual, vec![ - (tdir.mkpath("file1"), op::REMOVE, None), + (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[0])), + (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), + (tdir.mkpath("file1b"), op::RENAME, Some(cookies[1])), + (tdir.mkpath("file1c"), op::RENAME, Some(cookies[1])), ]); } -} -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_create_delete_file_4() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + #[test] + fn fsevents_rename_rename_file_20() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - sleep(10); + tdir.create_all(vec![ + "file1a", + ]); - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + sleep(10); - tdir.create("file1"); + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - assert_eq!(recv_events_with_timeout(&rx, 4.0), vec![ - (tdir.mkpath("file1"), op::CREATE, None), - ]); + tdir.rename("file1a", "file1b"); + sleep(20); + tdir.rename("file1b", "file1c"); - tdir.remove("file1"); - - let actual = recv_events_with_timeout(&rx, TIMEOUT_S); - if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { - panic!("excessive CREATE event"); - } else { + let actual = recv_events(&rx); + let cookies = extract_cookies(&actual); + assert_eq!(cookies.len(), 2); assert_eq!(actual, vec![ - (tdir.mkpath("file1"), op::REMOVE, None), + (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[0])), + (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), + (tdir.mkpath("file1b"), op::RENAME, Some(cookies[1])), + (tdir.mkpath("file1c"), op::RENAME, Some(cookies[1])), ]); } -} -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_create_delete_file_8() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + #[test] + fn fsevents_rename_rename_back_file_0() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - sleep(10); + tdir.create_all(vec![ + "file1a", + ]); - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + sleep(10); - tdir.create("file1"); + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - assert_eq!(recv_events_with_timeout(&rx, 8.0), vec![ - (tdir.mkpath("file1"), op::CREATE, None), - ]); + tdir.rename("file1a", "file1b"); + tdir.rename("file1b", "file1a"); - tdir.remove("file1"); - - let actual = recv_events_with_timeout(&rx, TIMEOUT_S); - if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { - panic!("excessive CREATE event"); - } else { + let actual = recv_events(&rx); + let cookies = extract_cookies(&actual); + assert_eq!(cookies.len(), 1); assert_eq!(actual, vec![ - (tdir.mkpath("file1"), op::REMOVE, None), + (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), + (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[0])), ]); } -} -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_create_delete_file_16() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + #[test] + fn fsevents_rename_rename_back_file_10() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - sleep(10); + tdir.create_all(vec![ + "file1a", + ]); - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + sleep(10); - tdir.create("file1"); + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - assert_eq!(recv_events_with_timeout(&rx, 16.0), vec![ - (tdir.mkpath("file1"), op::CREATE, None), - ]); + tdir.rename("file1a", "file1b"); + sleep(10); + tdir.rename("file1b", "file1a"); - tdir.remove("file1"); - - let actual = recv_events_with_timeout(&rx, TIMEOUT_S); - if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { - panic!("excessive CREATE event"); - } else { + let actual = recv_events(&rx); + let cookies = extract_cookies(&actual); + assert_eq!(cookies.len(), 2); assert_eq!(actual, vec![ - (tdir.mkpath("file1"), op::REMOVE, None), + (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[0])), + (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), + (tdir.mkpath("file1b"), op::RENAME, Some(cookies[1])), + (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[1])), ]); } -} -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_create_delete_file_32() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + #[test] + fn fsevents_rename_rename_back_file_20() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - sleep(10); + tdir.create_all(vec![ + "file1a", + ]); - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + sleep(10); - tdir.create("file1"); + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - assert_eq!(recv_events_with_timeout(&rx, 32.0), vec![ - (tdir.mkpath("file1"), op::CREATE, None), - ]); + tdir.rename("file1a", "file1b"); + sleep(20); + tdir.rename("file1b", "file1a"); - tdir.remove("file1"); - - let actual = recv_events_with_timeout(&rx, TIMEOUT_S); - if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { - panic!("excessive CREATE event"); - } else { + let actual = recv_events(&rx); + let cookies = extract_cookies(&actual); + assert_eq!(cookies.len(), 2); assert_eq!(actual, vec![ - (tdir.mkpath("file1"), op::REMOVE, None), + (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[0])), + (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), + (tdir.mkpath("file1b"), op::RENAME, Some(cookies[1])), + (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[1])), ]); } -} -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_create_delete_file_64() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); + #[test] + fn fsevents_rename_rename_back_file_sleep() { + let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - sleep(10); + tdir.create_all(vec![ + "file1a", + ]); - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); + sleep(40_000); - tdir.create("file1"); + let (tx, rx) = mpsc::channel(); + let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); + watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - assert_eq!(recv_events_with_timeout(&rx, 64.0), vec![ - (tdir.mkpath("file1"), op::CREATE, None), - ]); + tdir.rename("file1a", "file1b"); + sleep(10); + tdir.rename("file1b", "file1a"); - tdir.remove("file1"); - - let actual = recv_events_with_timeout(&rx, TIMEOUT_S); - if actual == vec![(tdir.mkpath("file1"), op::CREATE | op::REMOVE, None)] { - panic!("excessive CREATE event"); - } else { + let actual = recv_events(&rx); + let cookies = extract_cookies(&actual); + assert_eq!(cookies.len(), 2); assert_eq!(actual, vec![ - (tdir.mkpath("file1"), op::REMOVE, None), + (tdir.mkpath("file1a"), op::RENAME, Some(cookies[0])), + (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), + (tdir.mkpath("file1b"), op::RENAME, Some(cookies[1])), + (tdir.mkpath("file1a"), op::RENAME, Some(cookies[1])), ]); } } - -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_rename_rename_file_0() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - - tdir.create_all(vec![ - "file1a", - ]); - - sleep(10); - - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - - tdir.rename("file1a", "file1b"); - tdir.rename("file1b", "file1c"); - - let actual = recv_events(&rx); - let cookies = extract_cookies(&actual); - assert_eq!(cookies.len(), 1); - assert_eq!(actual, vec![ - (tdir.mkpath("file1a"), op::CREATE | op::RENAME, None), - (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), - (tdir.mkpath("file1c"), op::RENAME, Some(cookies[0])), - ]); -} - -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_rename_rename_file_10() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - - tdir.create_all(vec![ - "file1a", - ]); - - sleep(10); - - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - - tdir.rename("file1a", "file1b"); - sleep(10); - tdir.rename("file1b", "file1c"); - - let actual = recv_events(&rx); - let cookies = extract_cookies(&actual); - assert_eq!(cookies.len(), 2); - assert_eq!(actual, vec![ - (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[0])), - (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), - (tdir.mkpath("file1b"), op::RENAME, Some(cookies[1])), - (tdir.mkpath("file1c"), op::RENAME, Some(cookies[1])), - ]); -} - -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_rename_rename_file_20() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - - tdir.create_all(vec![ - "file1a", - ]); - - sleep(10); - - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - - tdir.rename("file1a", "file1b"); - sleep(20); - tdir.rename("file1b", "file1c"); - - let actual = recv_events(&rx); - let cookies = extract_cookies(&actual); - assert_eq!(cookies.len(), 2); - assert_eq!(actual, vec![ - (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[0])), - (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), - (tdir.mkpath("file1b"), op::RENAME, Some(cookies[1])), - (tdir.mkpath("file1c"), op::RENAME, Some(cookies[1])), - ]); -} - -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_rename_rename_back_file_0() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - - tdir.create_all(vec![ - "file1a", - ]); - - sleep(10); - - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - - tdir.rename("file1a", "file1b"); - tdir.rename("file1b", "file1a"); - - let actual = recv_events(&rx); - let cookies = extract_cookies(&actual); - assert_eq!(cookies.len(), 1); - assert_eq!(actual, vec![ - (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), - (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[0])), - ]); -} - -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_rename_rename_back_file_10() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - - tdir.create_all(vec![ - "file1a", - ]); - - sleep(10); - - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - - tdir.rename("file1a", "file1b"); - sleep(10); - tdir.rename("file1b", "file1a"); - - let actual = recv_events(&rx); - let cookies = extract_cookies(&actual); - assert_eq!(cookies.len(), 2); - assert_eq!(actual, vec![ - (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[0])), - (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), - (tdir.mkpath("file1b"), op::RENAME, Some(cookies[1])), - (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[1])), - ]); -} - -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_rename_rename_back_file_20() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - - tdir.create_all(vec![ - "file1a", - ]); - - sleep(10); - - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - - tdir.rename("file1a", "file1b"); - sleep(20); - tdir.rename("file1b", "file1a"); - - let actual = recv_events(&rx); - let cookies = extract_cookies(&actual); - assert_eq!(cookies.len(), 2); - assert_eq!(actual, vec![ - (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[0])), - (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), - (tdir.mkpath("file1b"), op::RENAME, Some(cookies[1])), - (tdir.mkpath("file1a"), op::CREATE | op::RENAME, Some(cookies[1])), - ]); -} - -#[test] -#[cfg(feature = "timing_tests")] -fn fsevents_rename_rename_back_file_sleep() { - let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory"); - - tdir.create_all(vec![ - "file1a", - ]); - - sleep(40_000); - - let (tx, rx) = mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(tx).expect("failed to create recommended watcher"); - watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory"); - - tdir.rename("file1a", "file1b"); - sleep(10); - tdir.rename("file1b", "file1a"); - - let actual = recv_events(&rx); - let cookies = extract_cookies(&actual); - assert_eq!(cookies.len(), 2); - assert_eq!(actual, vec![ - (tdir.mkpath("file1a"), op::RENAME, Some(cookies[0])), - (tdir.mkpath("file1b"), op::RENAME, Some(cookies[0])), - (tdir.mkpath("file1b"), op::RENAME, Some(cookies[1])), - (tdir.mkpath("file1a"), op::RENAME, Some(cookies[1])), - ]); -} diff --git a/tests/utils.rs b/tests/utils/mod.rs similarity index 98% rename from tests/utils.rs rename to tests/utils/mod.rs index c2912b6..5fc28bc 100644 --- a/tests/utils.rs +++ b/tests/utils/mod.rs @@ -1,10 +1,7 @@ -extern crate notify; -extern crate time; -extern crate tempdir; - +use time; use tempdir::TempDir; - use notify::*; + use std::fs; use std::io::Write; use std::path::PathBuf; diff --git a/tests/watcher.rs b/tests/watcher.rs index c7906f0..b0767b0 100644 --- a/tests/watcher.rs +++ b/tests/watcher.rs @@ -1,6 +1,5 @@ extern crate notify; extern crate tempdir; -extern crate tempfile; extern crate time; mod utils; diff --git a/tests/windows.rs b/tests/windows.rs index 4acd2d3..55df165 100644 --- a/tests/windows.rs +++ b/tests/windows.rs @@ -1,139 +1,144 @@ +#![allow(dead_code)] + extern crate notify; extern crate tempdir; -extern crate tempfile; extern crate time; -use notify::*; -use std::thread; -use std::time::Duration; -use std::sync::mpsc::{channel, Receiver}; -use tempdir::TempDir; +#[cfg(target_os = "windows")] +mod windows_tests { + use super::notify::*; + use super::tempdir::TempDir; + use super::time; + use std::thread; + use std::time::Duration; + use std::sync::mpsc; -fn check_for_error(rx:&Receiver) { - while let Ok(res) = rx.try_recv() { - match res.op { - Err(e) => panic!("unexpected err: {:?}: {:?}", e, res.path), - _ => () - } - }; -} -#[cfg(target_os="windows")] -#[test] -fn shutdown() { - // create a watcher for n directories. start the watcher, then shut it down. inspect - // the watcher to make sure that it received final callbacks for all n watchers. - let dir_count = 100; - - // to get meta events, we have to pass in the meta channel - let (meta_tx,meta_rx) = channel(); - let (tx, rx) = channel(); - { - let mut dirs:Vec = Vec::new(); - let mut w = ReadDirectoryChangesWatcher::create(tx,meta_tx).unwrap(); - - for _ in 0..dir_count { - let d = TempDir::new("rsnotifytest").unwrap(); - dirs.push(d); - } - - for d in &dirs { // need the ref, otherwise its a move and the dir will be dropped! - //println!("{:?}", d.path()); - w.watch(d.path(), RecursiveMode::Recursive).unwrap(); - } - - // unwatch half of the directories, let the others get stopped when we go out of scope - for d in &dirs[0..dir_count/2] { - w.unwatch(d.path()).unwrap(); - } - - thread::sleep(Duration::from_millis(2000)); // sleep to unhook the watches - } - - check_for_error(&rx); - - const TIMEOUT_S: f64 = 60.0; // give it PLENTY of time before we declare failure - let deadline = time::precise_time_s() + TIMEOUT_S; - let mut watchers_shutdown = 0; - while watchers_shutdown != dir_count && time::precise_time_s() < deadline { - if let Ok(actual) = meta_rx.try_recv() { - match actual { - notify::windows::MetaEvent::SingleWatchComplete => watchers_shutdown += 1, - _ => () + fn wait_for_disconnect(rx: &mpsc::Receiver) { + loop { + match rx.try_recv() { + Err(mpsc::TryRecvError::Disconnected) => break, + Err(mpsc::TryRecvError::Empty) => (), + Ok(res) => { + match res.op { + Err(e) => panic!("unexpected err: {:?}: {:?}", e, res.path), + _ => (), + } + } } + thread::sleep(Duration::from_millis(10)); } - thread::sleep(Duration::from_millis(50)); // don't burn cpu, can take some time for completion events to fire } - assert_eq!(watchers_shutdown,dir_count); -} + #[test] + fn shutdown() { + // create a watcher for n directories. start the watcher, then shut it down. inspect + // the watcher to make sure that it received final callbacks for all n watchers. + let dir_count = 100; -#[cfg(target_os="windows")] -#[test] -fn watch_deleted_fails() { - let pb = { - let d = TempDir::new("rsnotifytest").unwrap(); - d.path().to_path_buf() - }; - - let (tx, _) = channel(); - let mut w = ReadDirectoryChangesWatcher::new(tx).unwrap(); - match w.watch(pb.as_path(), RecursiveMode::Recursive) { - Ok(x) => panic!("Should have failed, but got: {:?}", x), - Err(_) => () - } -} - -#[cfg(target_os="windows")] -#[test] -fn watch_server_can_be_awakened() { - let (tx, _) = channel(); - let (meta_tx,meta_rx) = channel(); - let mut w = ReadDirectoryChangesWatcher::create(tx,meta_tx).unwrap(); - let d = TempDir::new("rsnotifytest").unwrap(); - let d2 = TempDir::new("rsnotifytest").unwrap(); - - match w.watch(d.path(), RecursiveMode::Recursive) { - Ok(_) => (), - Err(e) => panic!("Oops: {:?}", e) - } - match w.watch(d2.path(), RecursiveMode::Recursive) { - Ok(_) => (), - Err(e) => panic!("Oops: {:?}", e) - } - // should be at least one awaken in there - const TIMEOUT_S: f64 = 5.0; - let deadline = time::precise_time_s() + TIMEOUT_S; - let mut awakened = false; - while time::precise_time_s() < deadline { - if let Ok(actual) = meta_rx.try_recv() { - match actual { - notify::windows::MetaEvent::WatcherAwakened => awakened = true, - _ => () - } - } - thread::sleep(Duration::from_millis(50)); - } - - if !awakened { - panic!("Failed to awaken"); - } -} - -#[cfg(target_os="windows")] -#[test] -#[ignore] -// repeatedly watch and unwatch a directory; make sure process memory does not increase. -// you use task manager to watch the memory; it will fluctuate a bit, but should not leak overall -fn memtest_manual() { - loop { - let (tx, rx) = channel(); - let d = TempDir::new("rsnotifytest").unwrap(); + // to get meta events, we have to pass in the meta channel + let (meta_tx, meta_rx) = mpsc::channel(); + let (tx, rx) = mpsc::channel(); { - let (meta_tx,_) = channel(); - let mut w = ReadDirectoryChangesWatcher::create(tx,meta_tx).unwrap(); - w.watch(d.path(), RecursiveMode::Recursive).unwrap(); - thread::sleep(Duration::from_millis(1)); // this should make us run pretty hot but not insane + let mut dirs: Vec = Vec::new(); + let mut w = ReadDirectoryChangesWatcher::create(tx, meta_tx).unwrap(); + + for _ in 0..dir_count { + let d = TempDir::new("rsnotifytest").unwrap(); + dirs.push(d); + } + + // need the ref, otherwise it's a move and the dir will be dropped! + for d in &dirs { + w.watch(d.path(), RecursiveMode::Recursive).unwrap(); + } + + // unwatch half of the directories, let the others get stopped when we go out of scope + for d in &dirs[0..dir_count / 2] { + w.unwatch(d.path()).unwrap(); + } + + thread::sleep(Duration::from_millis(2000)); // sleep to unhook the watches + } + + wait_for_disconnect(&rx); + + const TIMEOUT_S: f64 = 60.0; // give it PLENTY of time before we declare failure + let deadline = time::precise_time_s() + TIMEOUT_S; + + let mut watchers_shutdown = 0; + while watchers_shutdown != dir_count && time::precise_time_s() < deadline { + if let Ok(actual) = meta_rx.try_recv() { + match actual { + windows::MetaEvent::SingleWatchComplete => watchers_shutdown += 1, + _ => (), + } + } + thread::sleep(Duration::from_millis(1)); // don't burn cpu, can take some time for completion events to fire + } + + assert_eq!(dir_count, watchers_shutdown); + } + + #[test] + fn watch_deleted_fails() { + let pb = { + let d = TempDir::new("rsnotifytest").unwrap(); + d.path().to_path_buf() + }; + + let (tx, _) = mpsc::channel(); + let mut w = ReadDirectoryChangesWatcher::new(tx).unwrap(); + match w.watch(pb.as_path(), RecursiveMode::Recursive) { + Ok(x) => panic!("Should have failed, but got: {:?}", x), + Err(_) => (), + } + } + + #[test] + fn watch_server_can_be_awakened() { + let (tx, _) = mpsc::channel(); + let (meta_tx, meta_rx) = mpsc::channel(); + let mut w = ReadDirectoryChangesWatcher::create(tx, meta_tx).unwrap(); + + let d = TempDir::new("rsnotifytest").unwrap(); + w.watch(d.path(), RecursiveMode::Recursive).unwrap(); + + // should be at least one awaken in there + const TIMEOUT_S: f64 = 5.0; + let deadline = time::precise_time_s() + TIMEOUT_S; + + let mut awakened = false; + while !awakened && time::precise_time_s() < deadline { + if let Ok(actual) = meta_rx.try_recv() { + match actual { + windows::MetaEvent::WatcherAwakened => awakened = true, + _ => (), + } + } + thread::sleep(Duration::from_millis(50)); + } + + assert!(awakened); + } + + #[test] + #[cfg(feature = "manual_tests")] + // repeatedly watch and unwatch a directory; make sure process memory does not increase. + // you use task manager to watch the memory; it will fluctuate a bit, but should not leak overall + fn memtest_manual() { + let mut i = 0; + loop { + let (tx, rx) = mpsc::channel(); + let d = TempDir::new("rsnotifytest").unwrap(); + { + let (meta_tx, _) = mpsc::channel(); + let mut w = ReadDirectoryChangesWatcher::create(tx, meta_tx).unwrap(); + w.watch(d.path(), RecursiveMode::Recursive).unwrap(); + thread::sleep(Duration::from_millis(1)); // this should make us run pretty hot but not insane + } + wait_for_disconnect(&rx); + i += 1; + println!("memtest {}", i); } - check_for_error(&rx); } }