#![cfg(unix)]
use crate::config::profile::{active_profile, is_pid_alive, preempt_instances_in};
use std::fs;
use tempfile::TempDir;
#[test]
fn empty_lock_dir_preempts_nothing() {
let tmp = TempDir::new().unwrap();
let preempted = preempt_instances_in(tmp.path(), false);
assert!(
preempted.is_empty(),
"an empty lock dir must preempt nothing, got: {preempted:?}"
);
}
#[test]
fn dead_pid_lock_is_skipped() {
let tmp = TempDir::new().unwrap();
let profile = active_profile().unwrap_or("default");
fs::write(
tmp.path().join("telegram_deadbeef.lock"),
format!("{profile}:999999"),
)
.unwrap();
let preempted = preempt_instances_in(tmp.path(), false);
assert!(
preempted.is_empty(),
"a dead-PID lock must be skipped, got: {preempted:?}"
);
}
#[test]
fn other_profile_lock_is_not_touched() {
let tmp = TempDir::new().unwrap();
let other = format!("not-{}", active_profile().unwrap_or("default"));
fs::write(
tmp.path().join("telegram_cafe.lock"),
format!("{other}:{}", std::process::id()),
)
.unwrap();
let preempted = preempt_instances_in(tmp.path(), false);
assert!(
preempted.is_empty(),
"a different profile's lock must not be preempted, got: {preempted:?}"
);
}
#[test]
#[ignore = "spawns and kills a child process; run with `cargo test -- --ignored`"]
fn preempts_and_kills_a_live_instance() {
let tmp = TempDir::new().unwrap();
let profile = active_profile().unwrap_or("default");
let mut child = std::process::Command::new("sleep")
.arg("60")
.spawn()
.expect("spawn sleep child");
let child_pid = child.id();
fs::write(
tmp.path().join("_test_iso_telegram_abc123.lock"),
format!("{profile}:{child_pid}"),
)
.unwrap();
let preempted = preempt_instances_in(tmp.path(), false);
let ours = preempted
.iter()
.find(|p| p.pid == child_pid)
.expect("the live instance must be detected and preempted");
assert!(
ours.channels.iter().any(|c| c == "_test_iso_telegram"),
"preempted instance must report the channel it held: {:?}",
ours.channels
);
assert!(
ours.stopped,
"the instance must be stopped (SIGTERM/SIGKILL)"
);
let killed = !is_pid_alive(child_pid);
let _ = child.kill();
let _ = child.wait();
assert!(
killed,
"the background process must be gone after preemption"
);
}