mirror of
https://github.com/Tencent/BrowserSkill.git
synced 2026-09-10 13:01:23 +08:00
108 lines
3.2 KiB
Rust
108 lines
3.2 KiB
Rust
//! Verify the daemon self-exits after `--daemon-idle` elapses.
|
|
|
|
#![cfg(unix)]
|
|
|
|
use std::path::PathBuf;
|
|
use std::process::Command;
|
|
use std::time::{Duration, Instant};
|
|
|
|
use tempfile::TempDir;
|
|
use tokio::net::UnixStream;
|
|
|
|
fn bsk_bin() -> PathBuf {
|
|
PathBuf::from(env!("CARGO_BIN_EXE_bsk"))
|
|
}
|
|
|
|
fn wait_for_pid_exit(pid: i32, timeout: Duration) -> bool {
|
|
let deadline = Instant::now() + timeout;
|
|
while Instant::now() < deadline {
|
|
let alive = unsafe { libc::kill(pid, 0) } == 0;
|
|
if !alive {
|
|
return true;
|
|
}
|
|
std::thread::sleep(Duration::from_millis(50));
|
|
}
|
|
false
|
|
}
|
|
|
|
#[test]
|
|
fn daemon_self_exits_after_idle_timeout() {
|
|
let tmp = TempDir::new().unwrap();
|
|
let home = tmp.path().join("bsk");
|
|
std::fs::create_dir_all(&home).unwrap();
|
|
|
|
let out = Command::new(bsk_bin())
|
|
.env("BSK_HOME", &home)
|
|
.env("RUST_LOG", "warn")
|
|
.args(["daemon", "start", "--port", "0", "--daemon-idle", "2s"])
|
|
.output()
|
|
.expect("spawn bsk daemon start");
|
|
assert!(
|
|
out.status.success(),
|
|
"daemon start failed: {}",
|
|
String::from_utf8_lossy(&out.stderr)
|
|
);
|
|
|
|
let info_path = home.join("daemon.json");
|
|
let info: serde_json::Value =
|
|
serde_json::from_slice(&std::fs::read(&info_path).unwrap()).unwrap();
|
|
let pid = info["pid"].as_u64().expect("pid number") as i32;
|
|
|
|
assert!(
|
|
wait_for_pid_exit(pid, Duration::from_secs(6)),
|
|
"daemon should self-exit within 6s of starting with --daemon-idle=2s"
|
|
);
|
|
// daemon.json should be cleaned up on graceful shutdown.
|
|
assert!(
|
|
!info_path.exists(),
|
|
"daemon.json should be removed after idle exit"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn daemon_stays_alive_while_ipc_connection_is_open() {
|
|
let tmp = TempDir::new().unwrap();
|
|
let home = tmp.path().join("bsk");
|
|
std::fs::create_dir_all(&home).unwrap();
|
|
|
|
let out = Command::new(bsk_bin())
|
|
.env("BSK_HOME", &home)
|
|
.env("RUST_LOG", "warn")
|
|
.args(["daemon", "start", "--port", "0", "--daemon-idle", "2s"])
|
|
.output()
|
|
.expect("spawn bsk daemon start");
|
|
assert!(
|
|
out.status.success(),
|
|
"daemon start failed: {}",
|
|
String::from_utf8_lossy(&out.stderr)
|
|
);
|
|
|
|
let info_path = home.join("daemon.json");
|
|
let info: serde_json::Value =
|
|
serde_json::from_slice(&std::fs::read(&info_path).unwrap()).unwrap();
|
|
let pid = info["pid"].as_u64().expect("pid number") as i32;
|
|
let sock = info["sock_path"].as_str().expect("sock path").to_string();
|
|
|
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
|
let stream = rt
|
|
.block_on(UnixStream::connect(sock))
|
|
.expect("connect to daemon IPC");
|
|
|
|
std::thread::sleep(Duration::from_secs(3));
|
|
assert!(
|
|
unsafe { libc::kill(pid, 0) } == 0,
|
|
"daemon should stay alive while IPC connection is open"
|
|
);
|
|
|
|
drop(stream);
|
|
std::thread::sleep(Duration::from_millis(500));
|
|
assert!(
|
|
unsafe { libc::kill(pid, 0) } == 0,
|
|
"daemon should restart the idle clock when the last IPC connection closes"
|
|
);
|
|
assert!(
|
|
wait_for_pid_exit(pid, Duration::from_secs(6)),
|
|
"daemon should self-exit after the IPC connection closes"
|
|
);
|
|
}
|