From 24aaabca3a142aac5ebd416cbf4c2ea1c4a3af84 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 6 Apr 2024 21:20:22 +0200 Subject: [PATCH] Add regression test for `Process::parent` update --- test_bin/main.rs | 22 +++++++++++++++++++++- tests/process.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/test_bin/main.rs b/test_bin/main.rs index d15425064..8957b0037 100644 --- a/test_bin/main.rs +++ b/test_bin/main.rs @@ -1,5 +1,25 @@ // Does nothing and just exits after waiting for 30 seconds. +use std::process::{Child, Command}; + +fn maybe_start_child(last: String, args: &[String]) -> Option { + if last == "1" { + let mut cmd = Command::new(&args[0]); + for arg in &args[1..] { + cmd.arg(arg); + } + Some(cmd.spawn().expect("failed to run command")) + } else { + None + } +} + fn main() { - std::thread::sleep(std::time::Duration::from_secs(30)); + let mut args: Vec = std::env::args().collect(); + let child = args.pop().and_then(|last| maybe_start_child(last, &args)); + if child.is_some() { + std::thread::sleep(std::time::Duration::from_secs(3)); + } else { + std::thread::sleep(std::time::Duration::from_secs(30)); + } } diff --git a/tests/process.rs b/tests/process.rs index 8f04a17f9..459dfb149 100644 --- a/tests/process.rs +++ b/tests/process.rs @@ -794,3 +794,50 @@ fn test_process_run_time() { run_time ); } + +// Test that if the parent of a process is removed, then the child PID will be +// updated as well. +#[test] +fn test_parent_change() { + if !sysinfo::IS_SUPPORTED_SYSTEM || cfg!(feature = "apple-sandbox") { + return; + } + + build_test_binary(); + let mut p = std::process::Command::new("./target/test_binary") + .arg("1") + .spawn() + .unwrap(); + + std::thread::sleep(std::time::Duration::from_secs(1)); + + let pid = Pid::from_u32(p.id() as _); + let mut s = System::new(); + s.refresh_processes(); + + assert_eq!( + s.process(pid).expect("process was not created").parent(), + sysinfo::get_current_pid().ok(), + ); + + let child_pid = s + .processes() + .iter() + .find(|(_, proc_)| proc_.parent() == Some(pid)) + .map(|(pid, _)| *pid) + .expect("failed to get child process"); + + // Waiting for the parent process to stop. + p.wait().expect("wait failed"); + + s.refresh_processes(); + // Parent should not be around anymore. + assert!(s.process(pid).is_none()); + + let child = s.process(child_pid).expect("child is dead"); + // Child should have a different parent now. + assert_ne!(child.parent(), Some(pid)); + + // We kill the child to clean up. + child.kill(); +}