extern crate notify;
extern crate tempdir;
mod utils;
use notify::*;
use std::sync::mpsc;
use tempdir::TempDir;
use std::thread;
use std::env;
#[cfg(all(feature = "manual_tests", target_os="linux"))]
use std::time::{Duration, Instant};
#[cfg(all(feature = "manual_tests", target_os="linux"))]
use std::io::prelude::*;
#[cfg(all(feature = "manual_tests", target_os="linux"))]
use std::fs::File;
use utils::*;
const NETWORK_PATH: &'static str = "";
#[cfg(target_os="linux")]
#[test]
fn new_inotify() {
let (tx, _) = mpsc::channel();
let w: Result<INotifyWatcher> = Watcher::new_raw(tx);
assert!(w.is_ok());
}
#[cfg(target_os="macos")]
#[test]
fn new_fsevent() {
let (tx, _) = mpsc::channel();
let w: Result<FsEventWatcher> = Watcher::new_raw(tx);
assert!(w.is_ok());
}
#[test]
fn new_null() {
let (tx, _) = mpsc::channel();
let w: Result<NullWatcher> = Watcher::new_raw(tx);
assert!(w.is_ok());
}
#[test]
fn new_poll() {
let (tx, _) = mpsc::channel();
let w: Result<PollWatcher> = Watcher::new_raw(tx);
assert!(w.is_ok());
}
#[test]
fn new_recommended() {
let (tx, _) = mpsc::channel();
let w: Result<RecommendedWatcher> = Watcher::new_raw(tx);
assert!(w.is_ok());
}
#[test]
fn test_watcher_send() {
let (tx, _) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).unwrap();
thread::spawn(move || {
watcher.watch(".", RecursiveMode::Recursive).unwrap();
}).join().unwrap();
}
#[test]
fn test_watcher_sync() {
use std::sync::{ Arc, RwLock };
let (tx, _) = mpsc::channel();
let watcher: RecommendedWatcher = Watcher::new_raw(tx).unwrap();
let watcher = Arc::new(RwLock::new(watcher));
thread::spawn(move || {
let mut watcher = watcher.write().unwrap();
watcher.watch(".", RecursiveMode::Recursive).unwrap();
}).join().unwrap();
}
#[test]
fn watch_relative() {
{ let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create("dir1");
env::set_current_dir(tdir.path()).expect("failed to change working directory");
let (tx, _) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch("dir1", RecursiveMode::Recursive).expect("failed to watch directory");
watcher.unwatch("dir1").expect("failed to unwatch directory");
if cfg!(not(target_os="windows")) {
match watcher.unwatch("dir1") {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}
}
{ let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create("file1");
env::set_current_dir(tdir.path()).expect("failed to change working directory");
let (tx, _) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch("file1", RecursiveMode::Recursive).expect("failed to watch file");
watcher.unwatch("file1").expect("failed to unwatch file");
if cfg!(not(target_os="windows")) {
match watcher.unwatch("file1") {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}
}
if cfg!(target_os = "windows") && !NETWORK_PATH.is_empty()
{ let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir").expect("failed to create temporary directory");
tdir.create("dir1");
env::set_current_dir(tdir.path()).expect("failed to change working directory");
let (tx, _) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch("dir1", RecursiveMode::Recursive).expect("failed to watch directory");
watcher.unwatch("dir1").expect("failed to unwatch directory");
if cfg!(not(target_os="windows")) {
match watcher.unwatch("dir1") {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}
}
if cfg!(target_os = "windows") && !NETWORK_PATH.is_empty()
{ let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir").expect("failed to create temporary directory");
tdir.create("file1");
env::set_current_dir(tdir.path()).expect("failed to change working directory");
let (tx, _) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch("file1", RecursiveMode::Recursive).expect("failed to watch file");
watcher.unwatch("file1").expect("failed to unwatch file");
if cfg!(not(target_os="windows")) {
match watcher.unwatch("file1") {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}
}
}
#[test]
#[cfg(target_os = "windows")]
fn watch_absolute_network_directory() {
if NETWORK_PATH.is_empty() {
return
}
let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir").expect("failed to create temporary directory");
tdir.create("dir1");
let (tx, _) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(tdir.mkpath("dir1"), RecursiveMode::Recursive).expect("failed to watch directory");
watcher.unwatch(tdir.mkpath("dir1")).expect("failed to unwatch directory");
if cfg!(not(target_os="windows")) {
match watcher.unwatch(tdir.mkpath("dir1")) {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}
}
#[test]
#[cfg(target_os = "windows")]
fn watch_absolute_network_file() {
if NETWORK_PATH.is_empty() {
return
}
let tdir = TempDir::new_in(NETWORK_PATH, "temp_dir").expect("failed to create temporary directory");
tdir.create("file1");
env::set_current_dir(tdir.path()).expect("failed to change working directory");
let (tx, _) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(tdir.mkpath("file1"), RecursiveMode::Recursive).expect("failed to watch file");
watcher.unwatch(tdir.mkpath("file1")).expect("failed to unwatch file");
if cfg!(not(target_os="windows")) {
match watcher.unwatch(tdir.mkpath("file1")) {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}
}
#[test]
#[cfg(all(feature = "manual_tests", target_os="linux"))]
fn inotify_queue_overflow() {
let mut max_queued_events = String::new();
let mut f = File::open("/proc/sys/fs/inotify/max_queued_events").expect("failed to open max_queued_events");
f.read_to_string(&mut max_queued_events).expect("failed to read max_queued_events");
assert_eq!(max_queued_events.trim(), "10");
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory");
for i in 0..20 {
let filename = format!("file{}", i);
tdir.create(&filename);
tdir.remove(&filename);
}
sleep(100);
let start = Instant::now();
let mut rescan_found = false;
while !rescan_found && start.elapsed().as_secs() < 5 {
match rx.try_recv() {
Ok(RawEvent{op: Ok(op::Op::RESCAN), ..}) => rescan_found = true,
Ok(RawEvent{op: Err(e), ..}) => panic!("unexpected event err: {:?}", e),
Ok(e) => (),
Err(mpsc::TryRecvError::Empty) => (),
Err(e) => panic!("unexpected channel err: {:?}", e)
}
thread::sleep(Duration::from_millis(10));
}
assert!(rescan_found);
}
#[test]
fn watch_recursive_create_directory() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(&tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory");
sleep_windows(100);
tdir.create("dir1");
sleep(10);
tdir.create("dir1/file1");
sleep_macos(100);
watcher.unwatch(&tdir.mkpath(".")).expect("failed to unwatch directory");
sleep_windows(100);
tdir.create("dir1/file2");
let actual = if cfg!(target_os="windows") {
let mut events = recv_events(&rx);
events.retain(|&(_, op, _)| op != op::Op::WRITE);
events
} else if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="linux") {
assert_eq!(actual, vec![
(tdir.mkpath("dir1"), op::Op::CREATE, None),
(tdir.mkpath("dir1/file1"), op::Op::CREATE, None),
(tdir.mkpath("dir1/file1"), op::Op::CLOSE_WRITE, None)
]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("dir1"), op::Op::CREATE, None),
(tdir.mkpath("dir1/file1"), op::Op::CREATE, None)
]);
}
}
#[test]
fn watch_recursive_move() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"dir1a",
]);
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory");
sleep_windows(100);
tdir.create("dir1a/file1");
tdir.rename("dir1a", "dir1b");
sleep(10);
tdir.create("dir1b/file2");
let actual = if cfg!(target_os="windows") {
let mut events = recv_events(&rx);
events.retain(|&(_, op, _)| op != op::Op::WRITE);
events
} else if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="macos") {
let cookies = extract_cookies(&actual);
assert_eq!(cookies.len(), 1);
assert_eq!(actual, vec![
(tdir.mkpath("dir1a/file1"), op::Op::CREATE, None),
(tdir.mkpath("dir1a"), op::Op::CREATE | op::Op::RENAME, Some(cookies[0])), (tdir.mkpath("dir1b"), op::Op::RENAME, Some(cookies[0])),
(tdir.mkpath("dir1b/file2"), op::Op::CREATE, None)
]);
} else if cfg!(target_os="linux") {
let cookies = extract_cookies(&actual);
assert_eq!(cookies.len(), 1);
assert_eq!(actual, vec![
(tdir.mkpath("dir1a/file1"), op::Op::CREATE, None),
(tdir.mkpath("dir1a/file1"), op::Op::CLOSE_WRITE, None),
(tdir.mkpath("dir1a"), op::Op::RENAME, Some(cookies[0])),
(tdir.mkpath("dir1b"), op::Op::RENAME, Some(cookies[0])),
(tdir.mkpath("dir1b/file2"), op::Op::CREATE, None),
(tdir.mkpath("dir1b/file2"), op::Op::CLOSE_WRITE, None)
]);
} else {
let cookies = extract_cookies(&actual);
assert_eq!(cookies.len(), 1);
assert_eq!(actual, vec![
(tdir.mkpath("dir1a/file1"), op::Op::CREATE, None),
(tdir.mkpath("dir1a"), op::Op::RENAME, Some(cookies[0])),
(tdir.mkpath("dir1b"), op::Op::RENAME, Some(cookies[0])),
(tdir.mkpath("dir1b/file2"), op::Op::CREATE, None)
]);
}
}
#[test]
#[cfg(not(target_os="macos"))]
fn watch_recursive_move_in() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"watch_dir",
"dir1a/dir1",
]);
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(&tdir.mkpath("watch_dir"), RecursiveMode::Recursive).expect("failed to watch directory");
sleep_windows(100);
tdir.rename("dir1a", "watch_dir/dir1b");
sleep(10);
tdir.create("watch_dir/dir1b/dir1/file1");
let actual = if cfg!(target_os="windows") {
let mut events = recv_events(&rx);
events.retain(|&(_, op, _)| op != op::Op::WRITE);
events
} else if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="macos") {
assert_eq!(actual, vec![
(tdir.mkpath("watch_dir/dir1b"), op::Op::RENAME, None), (tdir.mkpath("watch_dir/dir1b/dir1/file1"), op::Op::CREATE, None)
]);
panic!("move event should be a create event");
} else if cfg!(target_os="linux") {
assert_eq!(actual, vec![
(tdir.mkpath("watch_dir/dir1b"), op::Op::CREATE, None),
(tdir.mkpath("watch_dir/dir1b/dir1/file1"), op::Op::CREATE, None),
(tdir.mkpath("watch_dir/dir1b/dir1/file1"), op::Op::CLOSE_WRITE, None),
]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("watch_dir/dir1b"), op::Op::CREATE, None),
(tdir.mkpath("watch_dir/dir1b/dir1/file1"), op::Op::CREATE, None),
]);
}
}
#[test]
#[cfg(not(target_os="macos"))]
fn watch_recursive_move_out() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"watch_dir/dir1a/dir1",
]);
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(tdir.mkpath("watch_dir"), RecursiveMode::Recursive).expect("failed to watch directory");
sleep_windows(100);
tdir.create("watch_dir/dir1a/dir1/file1");
tdir.rename("watch_dir/dir1a", "dir1b");
sleep(10);
tdir.create("dir1b/dir1/file2");
let actual = if cfg!(target_os="windows") {
let mut events = recv_events(&rx);
events.retain(|&(_, op, _)| op != op::Op::WRITE);
events
} else if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="macos") {
assert_eq!(actual, vec![
(tdir.mkpath("watch_dir/dir1a/dir1/file1"), op::Op::CREATE, None),
(tdir.mkpath("watch_dir/dir1a"), op::Op::CREATE | op::Op::RENAME, None) ]);
panic!("move event should be a remove event");
} else if cfg!(target_os="linux") {
assert_eq!(actual, vec![
(tdir.mkpath("watch_dir/dir1a/dir1/file1"), op::Op::CREATE, None),
(tdir.mkpath("watch_dir/dir1a/dir1/file1"), op::Op::CLOSE_WRITE, None),
(tdir.mkpath("watch_dir/dir1a"), op::Op::REMOVE, None),
]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("watch_dir/dir1a/dir1/file1"), op::Op::CREATE, None),
(tdir.mkpath("watch_dir/dir1a"), op::Op::REMOVE, None),
]);
}
}
#[test]
fn watch_nonrecursive() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"dir1",
]);
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(tdir.mkpath("."), RecursiveMode::NonRecursive).expect("failed to watch directory");
sleep_windows(100);
tdir.create("dir2");
sleep(10);
tdir.create_all(vec![
"file0",
"dir1/file1",
"dir2/file2",
]);
if cfg!(target_os="linux") {
assert_eq!(recv_events(&rx), vec![
(tdir.mkpath("dir2"), op::Op::CREATE, None),
(tdir.mkpath("file0"), op::Op::CREATE, None),
(tdir.mkpath("file0"), op::Op::CLOSE_WRITE, None)
]);
} else {
assert_eq!(recv_events(&rx), vec![
(tdir.mkpath("dir2"), op::Op::CREATE, None),
(tdir.mkpath("file0"), op::Op::CREATE, None)
]);
}
}
#[test]
fn watch_file() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"file1",
]);
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(tdir.mkpath("file1"), RecursiveMode::Recursive).expect("failed to watch directory");
sleep_windows(100);
tdir.write("file1");
tdir.create("file2");
if cfg!(target_os="macos") {
assert_eq!(recv_events(&rx), vec![
(tdir.mkpath("file1"), op::Op::CREATE | op::Op::WRITE, None) ]);
} else if cfg!(target_os="linux") {
assert_eq!(recv_events(&rx), vec![
(tdir.mkpath("file1"), op::Op::WRITE, None),
(tdir.mkpath("file1"), op::Op::CLOSE_WRITE, None)
]);
} else {
assert_eq!(recv_events(&rx), vec![
(tdir.mkpath("file1"), op::Op::WRITE, None)
]);
}
}
#[test]
fn poll_watch_recursive_create_directory() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
let (tx, rx) = mpsc::channel();
let mut watcher = PollWatcher::with_delay_ms(tx, 50).expect("failed to create poll watcher");
watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory");
sleep(1100);
tdir.create("dir1/file1");
sleep(1100);
watcher.unwatch(tdir.mkpath(".")).expect("failed to unwatch directory");
tdir.create("dir1/file2");
let mut actual = recv_events(&rx);
actual.sort_by(|a, b| a.0.cmp(&b.0));
assert_eq!(actual, vec![
(tdir.mkpath("."), op::Op::WRITE, None), (tdir.mkpath("dir1"), op::Op::CREATE, None),
(tdir.mkpath("dir1/file1"), op::Op::CREATE, None)
]);
}
#[test]
#[ignore] fn poll_watch_recursive_move() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"dir1a",
]);
let (tx, rx) = mpsc::channel();
let mut watcher = PollWatcher::with_delay_ms(tx, 50).expect("failed to create poll watcher");
watcher.watch(tdir.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory");
sleep(1100);
tdir.create("dir1a/file1");
let mut actual = recv_events(&rx);
actual.sort_by(|a, b| a.0.cmp(&b.0));
assert_eq!(actual, vec![
(tdir.mkpath("dir1a"), op::Op::WRITE, None), (tdir.mkpath("dir1a/file1"), op::Op::CREATE, None),
]);
sleep(1100);
tdir.rename("dir1a", "dir1b");
tdir.create("dir1b/file2");
actual = recv_events(&rx);
actual.sort_by(|a, b| a.0.cmp(&b.0));
if cfg!(target_os="windows") {
assert_eq!(actual, vec![
(tdir.mkpath("."), op::Op::WRITE, None), (tdir.mkpath("dir1a"), op::Op::REMOVE, None),
(tdir.mkpath("dir1a/file1"), op::Op::REMOVE, None),
(tdir.mkpath("dir1b"), op::Op::CREATE, None),
(tdir.mkpath("dir1b"), op::Op::WRITE, None), (tdir.mkpath("dir1b/file1"), op::Op::CREATE, None),
(tdir.mkpath("dir1b/file2"), op::Op::CREATE, None),
]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("."), op::Op::WRITE, None), (tdir.mkpath("dir1a"), op::Op::REMOVE, None),
(tdir.mkpath("dir1a/file1"), op::Op::REMOVE, None),
(tdir.mkpath("dir1b"), op::Op::CREATE, None),
(tdir.mkpath("dir1b/file1"), op::Op::CREATE, None),
(tdir.mkpath("dir1b/file2"), op::Op::CREATE, None),
]);
}
}
#[test]
#[ignore] fn poll_watch_recursive_move_in() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"watch_dir",
"dir1a/dir1",
]);
let (tx, rx) = mpsc::channel();
let mut watcher = PollWatcher::with_delay_ms(tx, 50).expect("failed to create poll watcher");
watcher.watch(tdir.mkpath("watch_dir"), RecursiveMode::Recursive).expect("failed to watch directory");
sleep(1100);
tdir.rename("dir1a", "watch_dir/dir1b");
tdir.create("watch_dir/dir1b/dir1/file1");
let mut actual = recv_events(&rx);
actual.sort_by(|a, b| a.0.cmp(&b.0));
if cfg!(target_os="windows") {
assert_eq!(actual, vec![
(tdir.mkpath("watch_dir"), op::Op::WRITE, None), (tdir.mkpath("watch_dir/dir1b"), op::Op::CREATE, None),
(tdir.mkpath("watch_dir/dir1b/dir1"), op::Op::CREATE, None),
(tdir.mkpath("watch_dir/dir1b/dir1"), op::Op::WRITE, None), (tdir.mkpath("watch_dir/dir1b/dir1/file1"), op::Op::CREATE, None),
]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("watch_dir"), op::Op::WRITE, None), (tdir.mkpath("watch_dir/dir1b"), op::Op::CREATE, None),
(tdir.mkpath("watch_dir/dir1b/dir1"), op::Op::CREATE, None),
(tdir.mkpath("watch_dir/dir1b/dir1/file1"), op::Op::CREATE, None),
]);
}
}
#[test]
#[ignore] fn poll_watch_recursive_move_out() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"watch_dir/dir1a/dir1",
]);
let (tx, rx) = mpsc::channel();
let mut watcher = PollWatcher::with_delay_ms(tx, 50).expect("failed to create poll watcher");
watcher.watch(tdir.mkpath("watch_dir"), RecursiveMode::Recursive).expect("failed to watch directory");
sleep(1100);
tdir.create("watch_dir/dir1a/dir1/file1");
let mut actual = recv_events(&rx);
actual.sort_by(|a, b| a.0.cmp(&b.0));
assert_eq!(actual, vec![
(tdir.mkpath("watch_dir/dir1a/dir1"), op::Op::WRITE, None), (tdir.mkpath("watch_dir/dir1a/dir1/file1"), op::Op::CREATE, None),
]);
sleep(1100);
tdir.rename("watch_dir/dir1a", "dir1b");
tdir.create("dir1b/dir1/file2");
actual = recv_events(&rx);
actual.sort_by(|a, b| a.0.cmp(&b.0));
assert_eq!(actual, vec![
(tdir.mkpath("watch_dir"), op::Op::WRITE, None), (tdir.mkpath("watch_dir/dir1a"), op::Op::REMOVE, None),
(tdir.mkpath("watch_dir/dir1a/dir1"), op::Op::REMOVE, None),
(tdir.mkpath("watch_dir/dir1a/dir1/file1"), op::Op::REMOVE, None),
]);
}
#[test]
fn poll_watch_nonrecursive() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"dir1",
]);
let (tx, rx) = mpsc::channel();
let mut watcher = PollWatcher::with_delay_ms(tx, 50).expect("failed to create poll watcher");
watcher.watch(tdir.mkpath("."), RecursiveMode::NonRecursive).expect("failed to watch directory");
sleep(1100);
tdir.create_all(vec![
"file1",
"dir1/file1",
"dir2/file1",
]);
let mut actual = recv_events(&rx);
actual.sort_by(|a, b| a.0.cmp(&b.0));
assert_eq!(actual, vec![
(tdir.mkpath("."), op::Op::WRITE, None), (tdir.mkpath("dir1"), op::Op::WRITE, None), (tdir.mkpath("dir2"), op::Op::CREATE, None),
(tdir.mkpath("file1"), op::Op::CREATE, None),
]);
}
#[test]
fn poll_watch_file() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"file1",
]);
let (tx, rx) = mpsc::channel();
let mut watcher = PollWatcher::with_delay_ms(tx, 50).expect("failed to create poll watcher");
watcher.watch(tdir.mkpath("file1"), RecursiveMode::Recursive).expect("failed to watch directory");
sleep(1100);
tdir.write("file1");
tdir.create("file2");
assert_eq!(recv_events(&rx), vec![
(tdir.mkpath("file1"), op::Op::WRITE, None)
]);
}
#[test]
fn watch_nonexisting() {
let tdir1 = TempDir::new("temp_dir1").expect("failed to create temporary directory");
let tdir2 = TempDir::new("temp_dir2").expect("failed to create temporary directory");
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(&tdir1.mkpath("."), RecursiveMode::Recursive).expect("failed to watch directory");
let result = watcher.watch(&tdir2.mkpath("non_existing"), RecursiveMode::Recursive);
assert!(result.is_err());
sleep_windows(100);
tdir1.create("file1");
if cfg!(target_os="macos") {
assert_eq!(inflate_events(recv_events(&rx)), vec![
(tdir1.mkpath("file1"), op::Op::CREATE, None),
]);
} else if cfg!(target_os="windows") {
assert_eq!(recv_events(&rx), vec![
(tdir1.mkpath("file1"), op::Op::CREATE, None)
]);
} else {
assert_eq!(recv_events(&rx), vec![
(tdir1.mkpath("file1"), op::Op::CREATE, None),
(tdir1.mkpath("file1"), op::Op::CLOSE_WRITE, None)
]);
}
}
#[test]
fn unwatch_file() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"file1",
]);
sleep_macos(10);
let (tx, _) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(&tdir.mkpath("file1"), RecursiveMode::Recursive).expect("failed to watch file");
match watcher.unwatch(&tdir.mkpath("file1")) {
Ok(_) => (),
Err(e) => panic!("{:?}", e),
}
}
#[test]
fn unwatch_directory() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"dir1",
]);
sleep_macos(10);
let (tx, _) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(&tdir.mkpath("dir1"), RecursiveMode::Recursive).expect("failed to watch directory");
match watcher.unwatch(&tdir.mkpath("dir1")) {
Ok(_) => (),
Err(e) => panic!("{:?}", e),
}
}
#[test]
#[cfg(not(target_os="windows"))]
fn unwatch_nonexisting() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
sleep_macos(10);
let (tx, _) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
match watcher.unwatch(&tdir.mkpath("file1")) {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}
#[test]
fn self_delete_file() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"file1",
]);
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(&tdir.mkpath("file1"), RecursiveMode::Recursive).expect("failed to watch file");
sleep_windows(100);
tdir.remove("file1");
let actual = if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="windows") {
assert_eq!(actual, vec![
(tdir.mkpath("file1"), op::Op::REMOVE, None),
]);
} else if cfg!(target_os="macos") {
assert_eq!(actual, vec![
(tdir.mkpath("file1"), op::Op::CREATE | op::Op::REMOVE, None),
]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("file1"), op::Op::CHMOD, None),
(tdir.mkpath("file1"), op::Op::REMOVE, None),
]);
}
if cfg!(not(any(target_os="windows", target_os="macos"))) {
tdir.create("file1");
assert_eq!(recv_events(&rx), vec![]);
match watcher.unwatch(&tdir.mkpath("file1")) {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}
}
#[test]
#[cfg(not(target_os="windows"))]
fn self_delete_directory() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"dir1",
]);
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(&tdir.mkpath("dir1"), RecursiveMode::Recursive).expect("failed to watch directory");
sleep_windows(100);
tdir.remove("dir1");
let actual = if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="windows") {
assert_eq!(actual, vec![
(tdir.mkpath("dir1"), Op::empty(), None),
]);
} else if cfg!(target_os="macos") {
assert_eq!(actual, vec![
(tdir.mkpath("dir1"), op::Op::CREATE | op::Op::REMOVE, None),
]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("dir1"), op::Op::REMOVE, None),
]);
}
tdir.create("dir1");
let actual = if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="macos") {
assert_eq!(actual, vec![
(tdir.mkpath("dir1"), op::Op::CREATE | op::Op::REMOVE, None), ]);
} else {
assert_eq!(actual, vec![]);
}
if cfg!(not(any(target_os="windows", target_os="macos"))) {
match watcher.unwatch(&tdir.mkpath("dir1")) {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}
}
#[test]
#[cfg(not(target_os="windows"))]
fn self_rename_file() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"file1",
]);
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(&tdir.mkpath("file1"), RecursiveMode::Recursive).expect("failed to watch file");
sleep_windows(100);
tdir.rename("file1", "file2");
let actual = if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="macos") {
assert_eq!(actual, vec![
(tdir.mkpath("file1"), op::Op::CREATE | op::Op::RENAME, None), ]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("file1"), op::Op::RENAME, None),
]);
}
tdir.write("file2");
let actual = if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="windows") {
assert_eq!(actual, vec![]);
panic!("windows back-end should update file watch path");
} else if cfg!(target_os="macos") {
assert_eq!(actual, vec![]);
} else if cfg!(target_os="linux") {
assert_eq!(actual, vec![
(tdir.mkpath("file1"), op::Op::WRITE, None), (tdir.mkpath("file1"), op::Op::CLOSE_WRITE, None), ]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("file1"), op::Op::WRITE, None), ]);
}
tdir.create("file1");
if cfg!(target_os="macos") {
assert_eq!(recv_events(&rx), vec![
(tdir.mkpath("file1"), op::Op::CREATE | op::Op::RENAME, None), ]);
} else {
assert_eq!(recv_events(&rx), vec![]);
}
watcher.unwatch(&tdir.mkpath("file1")).expect("failed to unwatch file");
let result = watcher.unwatch(&tdir.mkpath("file1"));
match result {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}
#[test]
fn self_rename_directory() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"dir1",
]);
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(&tdir.mkpath("dir1"), RecursiveMode::Recursive).expect("failed to watch directory");
sleep_windows(100);
tdir.rename("dir1", "dir2");
let actual = if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="windows") {
assert_eq!(actual, vec![]);
} else if cfg!(target_os="macos") {
assert_eq!(actual, vec![
(tdir.mkpath("dir1"), op::Op::CREATE | op::Op::RENAME, None), ]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("dir1"), op::Op::RENAME, None),
]);
}
tdir.create("dir2/file1");
let actual = if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="macos") {
assert_eq!(actual, vec![]);
} else if cfg!(target_os="linux") {
assert_eq!(actual, vec![
(tdir.mkpath("dir1/file1"), op::Op::CREATE, None), (tdir.mkpath("dir1/file1"), op::Op::CLOSE_WRITE, None)
]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("dir1/file1"), op::Op::CREATE, None) ]);
}
tdir.create("dir1");
let actual = if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="macos") {
assert_eq!(actual, vec![
(tdir.mkpath("dir1"), op::Op::CREATE | op::Op::RENAME, None), ]);
} else {
assert_eq!(actual, vec![]);
}
watcher.unwatch(&tdir.mkpath("dir1")).expect("failed to unwatch directory");
let result = watcher.unwatch(&tdir.mkpath("dir1"));
if cfg!(target_os="windows") {
match result {
Err(e) => panic!("{:?}", e),
Ok(()) => (),
}
} else {
match result {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}
}
#[test]
fn parent_rename_file() {
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"dir1/file1",
]);
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(&tdir.mkpath("dir1/file1"), RecursiveMode::Recursive).expect("failed to watch file");
sleep_windows(100);
tdir.rename("dir1", "dir2");
assert_eq!(recv_events(&rx), vec![]);
tdir.write("dir2/file1");
let actual = if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="macos") {
assert_eq!(actual, vec![]);
} else if cfg!(target_os="linux") {
assert_eq!(actual, vec![
(tdir.mkpath("dir1/file1"), op::Op::WRITE, None), (tdir.mkpath("dir1/file1"), op::Op::CLOSE_WRITE, None)
]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("dir1/file1"), op::Op::WRITE, None) ]);
}
tdir.create("dir1/file1");
if cfg!(target_os="macos") {
assert_eq!(recv_events(&rx), vec![
(tdir.mkpath("dir1/file1"), op::Op::CREATE, None),
]);
} else {
assert_eq!(recv_events(&rx), vec![]);
}
watcher.unwatch(&tdir.mkpath("dir1/file1")).expect("failed to unwatch file");
let result = watcher.unwatch(&tdir.mkpath("dir1/file1"));
if cfg!(target_os="windows") {
match result {
Err(e) => panic!("{:?}", e),
Ok(()) => (),
}
} else {
match result {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}
}
#[test]
#[cfg(not(target_os="windows"))]
fn parent_rename_directory() {
if cfg!(target_os="windows") {
panic!("cannot remove parent directory on windows");
}
let tdir = TempDir::new("temp_dir").expect("failed to create temporary directory");
tdir.create_all(vec![
"dir1/watch_dir",
]);
sleep_macos(10);
let (tx, rx) = mpsc::channel();
let mut watcher: RecommendedWatcher = Watcher::new_raw(tx).expect("failed to create recommended watcher");
watcher.watch(&tdir.mkpath("dir1/watch_dir"), RecursiveMode::Recursive).expect("failed to watch directory");
tdir.rename("dir1", "dir2");
assert_eq!(recv_events(&rx), vec![]);
tdir.create("dir2/watch_dir/file1");
let actual = if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="macos") {
assert_eq!(actual, vec![]);
} else if cfg!(target_os="linux") {
assert_eq!(actual, vec![
(tdir.mkpath("dir1/watch_dir/file1"), op::Op::CREATE, None), (tdir.mkpath("dir1/watch_dir/file1"), op::Op::CLOSE_WRITE, None), ]);
} else {
assert_eq!(actual, vec![
(tdir.mkpath("dir1/watch_dir/file1"), op::Op::CREATE, None), ]);
}
tdir.create("dir1/watch_dir");
let actual = if cfg!(target_os="macos") {
inflate_events(recv_events(&rx))
} else {
recv_events(&rx)
};
if cfg!(target_os="macos") {
assert_eq!(actual, vec![
(tdir.mkpath("dir1/watch_dir"), op::Op::CREATE, None),
]);
} else {
assert_eq!(actual, vec![]);
}
watcher.unwatch(&tdir.mkpath("dir1/watch_dir")).expect("failed to unwatch directory");
let result = watcher.unwatch(&tdir.mkpath("dir1/watch_dir"));
match result {
Err(Error::WatchNotFound) => (),
Err(e) => panic!("{:?}", e),
Ok(o) => panic!("{:?}", o),
}
}