Skip to content

Commit 80c7382

Browse files
author
Christopher Woolum
committed
test(windows): add process kill unit tests
1 parent 2779ab1 commit 80c7382

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

crates/chat-cli/src/util/process/unix.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,60 @@ pub fn terminate_process(pid: Pid) -> Result<(), String> {
55
let nix_pid = nix::unistd::Pid::from_raw(pid.as_u32() as i32);
66
nix::sys::signal::kill(nix_pid, Signal::SIGTERM).map_err(|e| format!("Failed to terminate process: {}", e))
77
}
8+
9+
#[cfg(test)]
10+
#[cfg(not(windows))]
11+
mod tests {
12+
use std::process::Command;
13+
use std::time::Duration;
14+
15+
use super::*;
16+
17+
// Helper to create a long-running process for testing
18+
fn spawn_test_process() -> std::process::Child {
19+
let mut command = Command::new("sleep");
20+
command.arg("30");
21+
command.spawn().expect("Failed to spawn test process")
22+
}
23+
24+
#[test]
25+
fn test_terminate_process() {
26+
// Spawn a test process
27+
let mut child = spawn_test_process();
28+
let pid = Pid::from_u32(child.id());
29+
30+
// Terminate the process
31+
let result = terminate_process(pid);
32+
33+
// Verify termination was successful
34+
assert!(result.is_ok(), "Process termination failed: {:?}", result.err());
35+
36+
// Give it a moment to terminate
37+
std::thread::sleep(Duration::from_millis(100));
38+
39+
// Verify the process is actually terminated
40+
match child.try_wait() {
41+
Ok(Some(_)) => {
42+
// Process exited, which is what we expect
43+
},
44+
Ok(None) => {
45+
panic!("Process is still running after termination");
46+
},
47+
Err(e) => {
48+
panic!("Error checking process status: {}", e);
49+
},
50+
}
51+
}
52+
53+
#[test]
54+
fn test_terminate_nonexistent_process() {
55+
// Use a likely invalid PID
56+
let invalid_pid = Pid::from_u32(u32::MAX - 1);
57+
58+
// Attempt to terminate a non-existent process
59+
let result = terminate_process(invalid_pid);
60+
61+
// Should return an error
62+
assert!(result.is_err(), "Terminating non-existent process should fail");
63+
}
64+
}

crates/chat-cli/src/util/process/windows.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,71 @@ impl Deref for SafeHandle {
5151
&self.0
5252
}
5353
}
54+
55+
#[cfg(test)]
56+
#[cfg(windows)]
57+
mod tests {
58+
use std::process::Command;
59+
use std::time::Duration;
60+
61+
use super::*;
62+
63+
// Helper to create a long-running process for testing
64+
fn spawn_test_process() -> std::process::Child {
65+
let mut command = Command::new("cmd");
66+
command.args(["/C", "ping 127.0.0.1 -n 30 > nul"]);
67+
command.spawn().expect("Failed to spawn test process")
68+
}
69+
70+
#[test]
71+
fn test_terminate_process() {
72+
// Spawn a test process
73+
let mut child = spawn_test_process();
74+
let pid = Pid::from_u32(child.id());
75+
76+
// Terminate the process
77+
let result = terminate_process(pid);
78+
79+
// Verify termination was successful
80+
assert!(result.is_ok(), "Process termination failed: {:?}", result.err());
81+
82+
// Give it a moment to terminate
83+
std::thread::sleep(Duration::from_millis(100));
84+
85+
// Verify the process is actually terminated
86+
match child.try_wait() {
87+
Ok(Some(_)) => {
88+
// Process exited, which is what we expect
89+
},
90+
Ok(None) => {
91+
panic!("Process is still running after termination");
92+
},
93+
Err(e) => {
94+
panic!("Error checking process status: {}", e);
95+
},
96+
}
97+
}
98+
99+
#[test]
100+
fn test_terminate_nonexistent_process() {
101+
// Use a likely invalid PID
102+
let invalid_pid = Pid::from_u32(u32::MAX - 1);
103+
104+
// Attempt to terminate a non-existent process
105+
let result = terminate_process(invalid_pid);
106+
107+
// Should return an error
108+
assert!(result.is_err(), "Terminating non-existent process should fail");
109+
}
110+
111+
#[test]
112+
fn test_safe_handle() {
113+
// Test creating a SafeHandle with an invalid handle
114+
let invalid_handle = HANDLE(0);
115+
let safe_handle = SafeHandle::new(invalid_handle);
116+
assert!(safe_handle.is_none(), "SafeHandle should be None for invalid handle");
117+
118+
// We can't easily test a valid handle without actually opening a process,
119+
// which would require additional setup and teardown
120+
}
121+
}

0 commit comments

Comments
 (0)