Skip to content

Commit 79210f9

Browse files
committed
Copy windows test from v4
1 parent 5687d54 commit 79210f9

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

tests/windows.rs

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#![cfg(target_os = "windows")]
2+
#![allow(dead_code)]
3+
4+
use std::{
5+
sync::{Arc, Mutex},
6+
thread,
7+
time::{Duration, Instant},
8+
};
9+
10+
use crossbeam_channel::unbounded;
11+
use notify::{
12+
windows::{MetaEvent, ReadDirectoryChangesWatcher},
13+
Event, RecursiveMode, Result, Watcher,
14+
};
15+
use tempfile::TempDir;
16+
17+
fn wait_for_disconnect(rx: &crossbeam_channel::Receiver<Event>) {
18+
loop {
19+
if let Err(crossbeam_channel::TryRecvError::Disconnected) = rx.try_recv() {
20+
break;
21+
}
22+
thread::sleep(Duration::from_millis(10));
23+
}
24+
}
25+
26+
#[test]
27+
fn shutdown() {
28+
// create a watcher for N directories. start the watcher, then shut it down.
29+
// inspect the watcher to make sure that it received final callbacks for all
30+
// N watchers.
31+
let dir_count = 100;
32+
33+
// to get meta events, we have to pass in the meta channel
34+
let (meta_tx, meta_rx) = unbounded();
35+
36+
// hook a channel to the watcher
37+
let (tx, rx) = unbounded();
38+
39+
{
40+
let mut dirs: Vec<TempDir> = Vec::new();
41+
let mut w = ReadDirectoryChangesWatcher::create(
42+
Arc::new(Mutex::new(move |er: Result<Event>| {
43+
tx.send(er.unwrap()).unwrap();
44+
})),
45+
meta_tx,
46+
)
47+
.unwrap();
48+
49+
for _ in 0..dir_count {
50+
let d = tempfile::Builder::new()
51+
.prefix("rsnotifytest")
52+
.tempdir()
53+
.expect("failed to create temporary directory");
54+
dirs.push(d);
55+
}
56+
57+
// need the ref, otherwise it's a move and the dir will be dropped!
58+
for d in &dirs {
59+
w.watch(d.path(), RecursiveMode::Recursive).unwrap();
60+
}
61+
62+
// unwatch half of the directories, let the others get stopped when we go out of scope
63+
for d in &dirs[0..dir_count / 2] {
64+
w.unwatch(d.path()).unwrap();
65+
}
66+
67+
thread::sleep(Duration::from_millis(2000)); // sleep to unhook the watches
68+
}
69+
70+
wait_for_disconnect(&rx);
71+
72+
const TIMEOUT_MS: u64 = 60000; // give it PLENTY of time before we declare failure
73+
let start = Instant::now();
74+
75+
let mut watchers_shutdown = 0;
76+
while watchers_shutdown != dir_count && start.elapsed() < Duration::from_millis(TIMEOUT_MS) {
77+
if let Ok(actual) = meta_rx.try_recv() {
78+
match actual {
79+
MetaEvent::SingleWatchComplete => watchers_shutdown += 1,
80+
_ => (),
81+
}
82+
}
83+
thread::sleep(Duration::from_millis(1)); // don't burn cpu, can take some time for completion events to fire
84+
}
85+
86+
assert_eq!(dir_count, watchers_shutdown);
87+
}
88+
89+
#[test]
90+
fn watch_server_can_be_awakened() {
91+
// hook a channel to the watcher
92+
let (tx, _) = unbounded();
93+
94+
let (meta_tx, meta_rx) = unbounded();
95+
let mut w = ReadDirectoryChangesWatcher::create(
96+
Arc::new(Mutex::new(move |er: Result<Event>| {
97+
tx.send(er.unwrap()).unwrap();
98+
})),
99+
meta_tx,
100+
)
101+
.unwrap();
102+
103+
let d = tempfile::Builder::new()
104+
.prefix("rsnotifytest")
105+
.tempdir()
106+
.expect("failed to create temporary directory");
107+
w.watch(d.path(), RecursiveMode::Recursive).unwrap();
108+
109+
// should be at least one awaken in there
110+
const TIMEOUT_MS: u64 = 5000;
111+
let start = Instant::now();
112+
113+
let mut awakened = false;
114+
while !awakened && start.elapsed() < Duration::from_millis(TIMEOUT_MS) {
115+
if let Ok(actual) = meta_rx.try_recv() {
116+
match actual {
117+
MetaEvent::WatcherAwakened => awakened = true,
118+
_ => (),
119+
}
120+
}
121+
thread::sleep(Duration::from_millis(50));
122+
}
123+
124+
assert!(awakened);
125+
}
126+
127+
#[test]
128+
#[ignore]
129+
#[cfg(feature = "manual_tests")]
130+
// repeatedly watch and unwatch a directory; make sure process memory does not increase.
131+
// you use task manager to watch the memory; it will fluctuate a bit, but should not leak overall
132+
fn memtest_manual() {
133+
let mut i = 0;
134+
loop {
135+
let (tx, rx) = unbounded();
136+
let d = tempfile::Builder::new()
137+
.prefix("rsnotifytest")
138+
.tempdir()
139+
.expect("failed to create temporary directory");
140+
{
141+
let (meta_tx, _) = unbounded();
142+
let mut w = ReadDirectoryChangesWatcher::create(
143+
Arc::new(Mutex::new(move |er: Result<Event>| {
144+
tx.send(er.unwrap()).unwrap();
145+
})),
146+
meta_tx,
147+
)
148+
.unwrap();
149+
w.watch(d.path(), RecursiveMode::Recursive).unwrap();
150+
thread::sleep(Duration::from_millis(1)); // this should make us run pretty hot but not insane
151+
}
152+
wait_for_disconnect(&rx);
153+
i += 1;
154+
println!("memtest {}", i);
155+
}
156+
}

0 commit comments

Comments
 (0)