#![cfg(target_os = "linux")] use super::prelude::*; #[test] fn process_group_kill_leader() -> Result<()> { let mut leader = StdCommandWrap::with_new("tests/multiproc_helper.rs", |command| { command .arg("1") .arg("10") .stdout(Stdio::piped()) .stderr(Stdio::null()); }) .wrap(ProcessGroup::leader()) .spawn()?; assert!(leader.try_wait()?.is_none(), "leader: pre kill"); sleep(DIE_TIME); let stdout = leader .stdout() .take() .expect("Option.unwrap(): get leader stdout"); let mut lines = BufReader::new(stdout).lines(); let Some(Ok(line)) = lines.next() else { panic!("expected line with child pid"); }; let Some((parent, child)) = line.split_once(':') else { panic!("expected line with parent and child pids"); }; let parent = parent.parse::().unwrap(); let child = child.parse::().unwrap(); assert_eq!(parent, leader.id() as _); assert!(pid_alive(parent), "parent process should be alive"); assert!(pid_alive(child), "child process should be alive"); leader.kill().unwrap(); sleep(DIE_TIME); assert!(!pid_alive(parent), "parent process should be dead"); assert!(!pid_alive(child), "child process should be dead"); Ok(()) } #[test] fn process_group_kill_group() -> Result<()> { let mut leader = StdCommandWrap::with_new("tests/multiproc_helper.rs", |command| { command .arg("1") .arg("10") .stdout(Stdio::piped()) .stderr(Stdio::null()); }) .wrap(ProcessGroup::leader()) .spawn()?; assert!(leader.try_wait()?.is_none(), "leader: pre kill"); sleep(DIE_TIME); let stdout = leader .stdout() .take() .expect("Option.unwrap(): get leader stdout"); let mut lines = BufReader::new(stdout).lines(); let Some(Ok(line)) = lines.next() else { panic!("expected line with child pid"); }; let Some((parent, child)) = line.split_once(':') else { panic!("expected line with parent and child pids"); }; let parent = parent.parse::().unwrap(); let child = child.parse::().unwrap(); assert_eq!(parent, leader.id() as _); assert!(pid_alive(parent), "parent process should be alive"); assert!(pid_alive(child), "child process should be alive"); nix::sys::signal::killpg(nix::unistd::Pid::from_raw(parent), Signal::SIGKILL).unwrap(); sleep(DIE_TIME); assert!(!pid_alive(child), "child process should be dead"); leader.wait().unwrap(); assert!(!pid_alive(parent), "parent process should be dead"); Ok(()) } #[test] fn process_session_kill_leader() -> Result<()> { let mut leader = StdCommandWrap::with_new("tests/multiproc_helper.rs", |command| { command .arg("1") .arg("10") .stdout(Stdio::piped()) .stderr(Stdio::null()); }) .wrap(ProcessSession) .spawn()?; assert!(leader.try_wait()?.is_none(), "leader: pre kill"); sleep(DIE_TIME); let stdout = leader .stdout() .take() .expect("Option.unwrap(): get leader stdout"); let mut lines = BufReader::new(stdout).lines(); let Some(Ok(line)) = lines.next() else { panic!("expected line with child pid"); }; let Some((parent, child)) = line.split_once(':') else { panic!("expected line with parent and child pids"); }; let parent = parent.parse::().unwrap(); let child = child.parse::().unwrap(); assert_eq!(parent, leader.id() as _); assert!(pid_alive(parent), "parent process should be alive"); assert!(pid_alive(child), "child process should be alive"); leader.kill().unwrap(); sleep(DIE_TIME); assert!(!pid_alive(parent), "parent process should be dead"); assert!(!pid_alive(child), "child process should be dead"); Ok(()) } #[test] fn process_session_kill_group() -> Result<()> { let mut leader = StdCommandWrap::with_new("tests/multiproc_helper.rs", |command| { command .arg("1") .arg("10") .stdout(Stdio::piped()) .stderr(Stdio::null()); }) .wrap(ProcessSession) .spawn()?; assert!(leader.try_wait()?.is_none(), "leader: pre kill"); sleep(DIE_TIME); let stdout = leader .stdout() .take() .expect("Option.unwrap(): get leader stdout"); let mut lines = BufReader::new(stdout).lines(); let Some(Ok(line)) = lines.next() else { panic!("expected line with child pid"); }; let Some((parent, child)) = line.split_once(':') else { panic!("expected line with parent and child pids"); }; let parent = parent.parse::().unwrap(); let child = child.parse::().unwrap(); assert_eq!(parent, leader.id() as _); assert!(pid_alive(parent), "parent process should be alive"); assert!(pid_alive(child), "child process should be alive"); nix::sys::signal::killpg(nix::unistd::Pid::from_raw(parent), Signal::SIGKILL).unwrap(); sleep(DIE_TIME); assert!(!pid_alive(child), "child process should be dead"); leader.wait().unwrap(); assert!(!pid_alive(parent), "parent process should be dead"); Ok(()) }