mod common;
use std::io::Write;
use std::time::Duration;
use nix::sys::signal::{Signal, kill};
use nix::unistd::Pid;
use common::{control_frame, start_daemon, wait_until};
#[test]
fn sigterm_kills_daemon_and_its_jobs() {
let (dir, mut daemon, mut stream) = start_daemon("sigterm", |_| {});
let sock = dir.join("default.sock");
let pidfile = dir.join("job.pid");
let spawn = format!(
r#"{{"t":"spawn","command":"echo $$ > {pf} && sleep 300","cwd":"{cwd}"}}"#,
pf = pidfile.display(),
cwd = dir.display()
);
stream.write_all(&control_frame(&spawn)).unwrap();
let job_up = wait_until(Duration::from_secs(5), || {
std::fs::read_to_string(&pidfile)
.map(|s| !s.trim().is_empty())
.unwrap_or(false)
});
assert!(job_up, "the spawned job never wrote its pid");
let job = Pid::from_raw(
std::fs::read_to_string(&pidfile)
.unwrap()
.trim()
.parse::<i32>()
.unwrap(),
);
assert!(
kill(job, None).is_ok(),
"job should be alive before SIGTERM"
);
kill(Pid::from_raw(daemon.0.id() as i32), Signal::SIGTERM).unwrap();
let exited = wait_until(Duration::from_secs(10), || {
daemon.0.try_wait().map(|s| s.is_some()).unwrap_or(false)
});
assert!(exited, "daemon did not exit on SIGTERM");
let job_dead = wait_until(Duration::from_secs(5), || kill(job, None).is_err());
assert!(job_dead, "job survived the daemon's SIGTERM shutdown");
assert!(!sock.exists(), "socket file left behind");
let _ = std::fs::remove_dir_all(&dir);
}