Skip to content

Commit 9f67e24

Browse files
committed
test: integrated test
1 parent ef40f7e commit 9f67e24

File tree

1 file changed

+225
-0
lines changed

1 file changed

+225
-0
lines changed

crates/libs/kill_tree/tests/test.rs

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
use kill_tree;
2+
use std::{process::Command, sync::mpsc, thread, time::Duration};
3+
4+
fn get_node_script_infinite() -> String {
5+
r#"
6+
console.log('infinite. pid:', process.pid);
7+
setInterval(() => {}, 1000);
8+
"#
9+
.to_string()
10+
}
11+
12+
fn get_node_script_spawn_infinite_child() -> String {
13+
r#"
14+
console.log('spawn child. pid:', process.pid);
15+
const { spawn } = require('child_process');
16+
const child = spawn('node', ['-e', 'console.log("infinite. pid:", process.pid);setInterval(() => {}, 1000);'], {
17+
stdio: 'inherit',
18+
});
19+
child.on('exit', (code, signal) => {
20+
console.log('child process exited with ' +
21+
`code ${code} and signal ${signal}`);
22+
});
23+
setInterval(() => {}, 1000);
24+
"#
25+
.to_string()
26+
}
27+
28+
#[test]
29+
fn kill_tree_default() {
30+
let (tx, rx) = mpsc::channel();
31+
let thread = thread::spawn(move || {
32+
let mut child = Command::new("node")
33+
.arg("-e")
34+
.arg(get_node_script_infinite())
35+
.spawn()
36+
.unwrap();
37+
let target_process_id = child.id();
38+
tx.send(target_process_id).unwrap();
39+
let _ = child.wait();
40+
});
41+
let target_process_id = rx.recv().unwrap();
42+
let outputs = kill_tree::blocking::kill_tree(target_process_id).expect("Failed to kill");
43+
assert_eq!(outputs.len(), 1);
44+
let output = &outputs[0];
45+
match output {
46+
kill_tree::Output::Killed {
47+
process_id,
48+
parent_process_id,
49+
name,
50+
} => {
51+
assert_eq!(*process_id, target_process_id);
52+
assert_eq!(*parent_process_id, std::process::id());
53+
assert!(name.starts_with("node"));
54+
}
55+
kill_tree::Output::MaybeAlreadyTerminated { .. } => {
56+
panic!("This should not happen");
57+
}
58+
}
59+
thread.join().unwrap();
60+
}
61+
62+
#[test]
63+
fn kill_tree_with_config_sigkill() {
64+
let (tx, rx) = mpsc::channel();
65+
let thread = thread::spawn(move || {
66+
let mut child = Command::new("node")
67+
.arg("-e")
68+
.arg(get_node_script_infinite())
69+
.spawn()
70+
.unwrap();
71+
let target_process_id = child.id();
72+
tx.send(target_process_id).unwrap();
73+
let _ = child.wait();
74+
});
75+
let target_process_id = rx.recv().unwrap();
76+
let config = kill_tree::Config {
77+
signal: String::from("SIGKILL"),
78+
..Default::default()
79+
};
80+
let outputs = kill_tree::blocking::kill_tree_with_config(target_process_id, &config)
81+
.expect("Failed to kill");
82+
assert_eq!(outputs.len(), 1);
83+
let output = &outputs[0];
84+
match output {
85+
kill_tree::Output::Killed {
86+
process_id,
87+
parent_process_id,
88+
name,
89+
} => {
90+
assert_eq!(*process_id, target_process_id);
91+
assert_eq!(*parent_process_id, std::process::id());
92+
assert!(name.starts_with("node"));
93+
}
94+
kill_tree::Output::MaybeAlreadyTerminated { .. } => {
95+
panic!("This should not happen");
96+
}
97+
}
98+
thread.join().unwrap();
99+
}
100+
101+
#[test]
102+
fn kill_tree_with_config_include_target_false() {
103+
let (tx, rx) = mpsc::channel();
104+
let thread = thread::spawn(move || {
105+
let mut child = Command::new("node")
106+
.arg("-e")
107+
.arg(get_node_script_spawn_infinite_child())
108+
.spawn()
109+
.unwrap();
110+
thread::sleep(Duration::from_secs(1));
111+
let target_process_id = child.id();
112+
tx.send(target_process_id).unwrap();
113+
let _ = child.wait();
114+
});
115+
let target_process_id = rx.recv().unwrap();
116+
let config = kill_tree::Config {
117+
include_target: false,
118+
..Default::default()
119+
};
120+
let outputs = kill_tree::blocking::kill_tree_with_config(target_process_id, &config)
121+
.expect("Failed to kill");
122+
assert!(!outputs.is_empty());
123+
let output = &outputs[0];
124+
match output {
125+
kill_tree::Output::Killed {
126+
process_id: _,
127+
parent_process_id,
128+
name,
129+
} => {
130+
assert_eq!(*parent_process_id, target_process_id);
131+
assert!(name.starts_with("node"));
132+
}
133+
kill_tree::Output::MaybeAlreadyTerminated { .. } => {
134+
panic!("This should not happen");
135+
}
136+
}
137+
thread::sleep(Duration::from_secs(1));
138+
let outputs = kill_tree::blocking::kill_tree(target_process_id).expect("Failed to kill");
139+
assert_eq!(outputs.len(), 1);
140+
let output = &outputs[0];
141+
match output {
142+
kill_tree::Output::Killed {
143+
process_id,
144+
parent_process_id,
145+
name,
146+
} => {
147+
assert_eq!(*process_id, target_process_id);
148+
assert_eq!(*parent_process_id, std::process::id());
149+
assert!(name.starts_with("node"));
150+
}
151+
kill_tree::Output::MaybeAlreadyTerminated { .. } => {
152+
panic!("This should not happen");
153+
}
154+
}
155+
thread.join().unwrap();
156+
}
157+
158+
#[test]
159+
fn kill_tree_child_tree() {
160+
let (tx, rx) = mpsc::channel();
161+
let thread = thread::spawn(move || {
162+
let mut child = Command::new("node")
163+
.arg("-e")
164+
.arg(get_node_script_spawn_infinite_child())
165+
.spawn()
166+
.unwrap();
167+
thread::sleep(Duration::from_secs(1));
168+
let target_process_id = child.id();
169+
tx.send(target_process_id).unwrap();
170+
let _ = child.wait();
171+
});
172+
let target_process_id = rx.recv().unwrap();
173+
let outputs = kill_tree::blocking::kill_tree(target_process_id).expect("Failed to kill");
174+
assert_eq!(outputs.len(), 2);
175+
let target_output = outputs
176+
.iter()
177+
.find(|output| match output {
178+
kill_tree::Output::Killed {
179+
process_id: _,
180+
parent_process_id,
181+
name: _,
182+
} => *parent_process_id == std::process::id(),
183+
kill_tree::Output::MaybeAlreadyTerminated { .. } => false,
184+
})
185+
.unwrap();
186+
match target_output {
187+
kill_tree::Output::Killed {
188+
process_id,
189+
parent_process_id,
190+
name,
191+
} => {
192+
assert_eq!(*process_id, target_process_id);
193+
assert_eq!(*parent_process_id, std::process::id());
194+
assert!(name.starts_with("node"));
195+
}
196+
kill_tree::Output::MaybeAlreadyTerminated { .. } => {
197+
panic!("This should not happen");
198+
}
199+
}
200+
let child_output = outputs
201+
.iter()
202+
.find(|output| match output {
203+
kill_tree::Output::Killed {
204+
process_id: _,
205+
parent_process_id,
206+
name: _,
207+
} => *parent_process_id == target_process_id,
208+
kill_tree::Output::MaybeAlreadyTerminated { .. } => false,
209+
})
210+
.unwrap();
211+
match child_output {
212+
kill_tree::Output::Killed {
213+
process_id: _,
214+
parent_process_id,
215+
name,
216+
} => {
217+
assert_eq!(*parent_process_id, target_process_id);
218+
assert!(name.starts_with("node"));
219+
}
220+
kill_tree::Output::MaybeAlreadyTerminated { .. } => {
221+
panic!("This should not happen");
222+
}
223+
}
224+
thread.join().unwrap();
225+
}

0 commit comments

Comments
 (0)