use super::super::daemon::{
check_daemon_version, ensure_daemon, wait_for_daemon_teardown, VersionCheck,
};
#[tokio::test]
#[ignore] async fn ensure_daemon_auto_recovers_on_comm_error() {
let endpoint = crate::ipc::unique_test_endpoint();
let ep = endpoint.clone();
let mut listener = crate::ipc::IpcListener::bind(&ep).unwrap();
let server = tokio::spawn(async move {
let _ = listener.accept().await;
});
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
let result = ensure_daemon(&endpoint).await;
let _ = server.await;
if let Err(msg) = &result {
assert!(
!msg.contains("zccache stop"),
"Bug #27: ensure_daemon requires manual `zccache stop` instead of \
auto-recovering on protocol mismatch: {msg}"
);
}
}
#[test]
fn wait_for_daemon_teardown_returns_when_endpoint_unreachable() {
let tmp = tempfile::tempdir().expect("tempdir");
std::env::set_var("ZCCACHE_STOP_TIMEOUT_SECS", "2");
let unreachable_endpoint = if cfg!(windows) {
r"\\.\pipe\zccache-test-does-not-exist-182".to_string()
} else {
tmp.path()
.join("does-not-exist.sock")
.to_string_lossy()
.into_owned()
};
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("runtime");
let started = std::time::Instant::now();
rt.block_on(wait_for_daemon_teardown(&unreachable_endpoint));
let elapsed = started.elapsed();
std::env::remove_var("ZCCACHE_STOP_TIMEOUT_SECS");
assert!(
elapsed < std::time::Duration::from_secs(2),
"wait_for_daemon_teardown blocked for {elapsed:?} despite endpoint unreachable at t=0"
);
}
#[tokio::test]
async fn check_daemon_version_is_bounded_when_daemon_never_answers() {
std::env::set_var("ZCCACHE_STATUS_PROBE_TIMEOUT_SECS", "1");
let endpoint = crate::ipc::unique_test_endpoint();
let ep = endpoint.clone();
let mut listener = crate::ipc::IpcListener::bind(&ep).expect("bind listener");
let server = tokio::spawn(async move {
let _conn = listener.accept().await;
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
});
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
let started = std::time::Instant::now();
let verdict = check_daemon_version(&endpoint).await;
let elapsed = started.elapsed();
server.abort();
std::env::remove_var("ZCCACHE_STATUS_PROBE_TIMEOUT_SECS");
assert!(
matches!(verdict, VersionCheck::CommError),
"unresponsive Status probe should route to CommError recovery"
);
assert!(
elapsed < std::time::Duration::from_secs(3),
"check_daemon_version took {elapsed:?} against an unresponsive daemon — \
issue #554 expects bounded fail-fast (≤ probe timeout + epsilon)"
);
}
#[tokio::test]
#[ignore] async fn ensure_daemon_is_bounded_when_status_probe_never_answers() {
std::env::set_var("ZCCACHE_STATUS_PROBE_TIMEOUT_SECS", "1");
let endpoint = crate::ipc::unique_test_endpoint();
let ep = endpoint.clone();
let mut listener = crate::ipc::IpcListener::bind(&ep).expect("bind listener");
let server = tokio::spawn(async move {
let _conn = listener.accept().await;
tokio::time::sleep(std::time::Duration::from_secs(15)).await;
});
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
let started = std::time::Instant::now();
let result = ensure_daemon(&endpoint).await;
let elapsed = started.elapsed();
server.abort();
std::env::remove_var("ZCCACHE_STATUS_PROBE_TIMEOUT_SECS");
assert!(
elapsed < std::time::Duration::from_secs(10),
"ensure_daemon took {elapsed:?} against an unresponsive daemon; result={result:?}"
);
}