mirror of https://github.com/jackwener/wx-cli.git
test: Added real TCP daemon integration tests that spawn the actual wx…
- src/cli/transport.rs GSD context: - Milestone: M001 - TCP Transport - Slice: S04 - Task: T01 - Added real TCP daemon integration tests that spawn the actual wx binary, connect via TCP, verify ping round-trip, and test connection refused GSD-Task: S04/T01pull/43/head
parent
ee54abdc37
commit
7b50d6abd4
|
|
@ -389,3 +389,120 @@ mod integration_tests {
|
|||
assert!(!result, "Expected is_alive_tcp to return false for unused port");
|
||||
}
|
||||
}
|
||||
|
||||
/// Real TCP daemon integration tests — spawn the actual `wx` daemon binary,
|
||||
/// connect via TCP, and verify end-to-end request/response round-trip.
|
||||
///
|
||||
/// These tests are `#[cfg(unix)]` only and require the `wx` binary to have
|
||||
/// been built with `cargo build --bin wx`.
|
||||
#[cfg(unix)]
|
||||
#[cfg(test)]
|
||||
mod tcp_integration_tests {
|
||||
use super::*;
|
||||
use crate::ipc::Request;
|
||||
use std::process::Command;
|
||||
|
||||
/// Build the `wx` binary so the daemon subprocess is available.
|
||||
fn ensure_binary() -> std::path::PathBuf {
|
||||
let status = Command::new("cargo")
|
||||
.args(["build", "--bin", "wx"])
|
||||
.output()
|
||||
.expect("cargo build failed to execute");
|
||||
if !status.status.success() {
|
||||
panic!(
|
||||
"cargo build --bin wx failed:\n{}",
|
||||
String::from_utf8_lossy(&status.stderr)
|
||||
);
|
||||
}
|
||||
// Binary path: target/debug/wx
|
||||
let mut p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
p.push("target/debug/wx");
|
||||
assert!(p.exists(), "wx binary not found at {:?}", p);
|
||||
p
|
||||
}
|
||||
|
||||
/// Wait for the daemon TCP endpoint to become ready.
|
||||
fn wait_for_tcp_ready(addr: &str) -> bool {
|
||||
let deadline = std::time::Instant::now()
|
||||
+ std::time::Duration::from_secs(STARTUP_TIMEOUT_SECS);
|
||||
while std::time::Instant::now() < deadline {
|
||||
std::thread::sleep(std::time::Duration::from_millis(300));
|
||||
if is_alive_tcp(addr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tcp_daemon_ping_round_trip() {
|
||||
let binary = ensure_binary();
|
||||
|
||||
// Pick a free ephemeral port
|
||||
let port = {
|
||||
let listener = std::net::TcpListener::bind("127.0.0.1:0")
|
||||
.expect("failed to bind ephemeral port");
|
||||
listener.local_addr().unwrap().port()
|
||||
};
|
||||
let addr = format!("127.0.0.1:{}", port);
|
||||
|
||||
// Spawn the daemon subprocess in TCP-only mode
|
||||
let mut child = Command::new(&binary)
|
||||
.env("WX_DAEMON_MODE", "1")
|
||||
.env("WX_DAEMON_TCP_ADDR", &addr)
|
||||
.stdin(std::process::Stdio::null())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.expect("failed to spawn wx daemon");
|
||||
|
||||
let pid = child.id();
|
||||
eprintln!("[test] spawned daemon PID {}", pid);
|
||||
|
||||
// Wait for TCP readiness
|
||||
if !wait_for_tcp_ready(&addr) {
|
||||
let _ = child.kill();
|
||||
let _ = child.wait();
|
||||
panic!(
|
||||
"daemon did not become ready on {} within {}s (PID {})",
|
||||
addr, STARTUP_TIMEOUT_SECS, pid
|
||||
);
|
||||
}
|
||||
eprintln!("[test] daemon ready on {}", addr);
|
||||
|
||||
// Send Ping request and verify pong
|
||||
let resp = send_tcp(Request::Ping, &addr)
|
||||
.expect("send_tcp(Ping) should succeed");
|
||||
assert!(resp.ok, "Response ok flag should be true");
|
||||
|
||||
let pong = resp.data.get("pong").and_then(|v| v.as_bool());
|
||||
assert!(
|
||||
pong == Some(true),
|
||||
"Expected pong=true in response, got: {:?}",
|
||||
resp.data
|
||||
);
|
||||
|
||||
// Terminate daemon
|
||||
unsafe { libc::kill(pid as libc::pid_t, libc::SIGTERM) };
|
||||
|
||||
// Verify clean exit
|
||||
let exit_status = child.wait().expect("failed to wait on daemon");
|
||||
assert!(
|
||||
exit_status.success(),
|
||||
"daemon should exit cleanly, got: {:?}",
|
||||
exit_status
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tcp_daemon_connection_refused() {
|
||||
// Port 59889 is very unlikely to have a listener
|
||||
let addr = "127.0.0.1:59889";
|
||||
let result = send_tcp(Request::Ping, addr);
|
||||
assert!(
|
||||
result.is_err(),
|
||||
"Expected connection refused error when no daemon is listening on {}",
|
||||
addr
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue