use anyhow::Result;
use std::process::{Command, Stdio};
use std::time::Duration;
use tokio::time::sleep;
#[tokio::test]
async fn test_rpc_simple_separate_processes() -> Result<()> {
println!("Testing basic with separate server/client processes");
let build_status = Command::new("cargo")
.args(&["build", "--example", "basic"])
.current_dir(env!("CARGO_MANIFEST_DIR"))
.status()?;
assert!(build_status.success(), "Failed to build basic example");
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")?;
let example_path = format!("{}/../../target/debug/examples/basic", manifest_dir);
println!("Starting server process...");
let mut server = Command::new(&example_path)
.arg("--server")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
sleep(Duration::from_millis(500)).await;
if let Some(status) = server.try_wait()? {
panic!("Server exited early with status: {}", status);
}
println!("Starting client process...");
let client_output = Command::new(&example_path)
.arg("--client")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()?;
assert!(
client_output.status.success(),
"Client failed with status: {}\nstdout: {}\nstderr: {}",
client_output.status,
String::from_utf8_lossy(&client_output.stdout),
String::from_utf8_lossy(&client_output.stderr)
);
let stdout = String::from_utf8_lossy(&client_output.stdout);
assert!(stdout.contains("Connected!"), "Client didn't connect");
assert!(stdout.contains("Echo response:"), "Client didn't get echo response");
assert!(stdout.contains("Add response:"), "Client didn't get add response");
assert!(stdout.contains("Total calls"), "Client didn't get stats");
assert!(
stdout.contains("All requests completed successfully"),
"Client didn't complete all requests"
);
println!("Client completed successfully");
server.kill()?;
server.wait()?;
println!("Test passed!");
Ok(())
}
#[tokio::test]
async fn test_rpc_simple_demo_mode() -> Result<()> {
println!("Testing basic in demo mode");
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")?;
let example_path = format!("{}/../../target/debug/examples/basic", manifest_dir);
let output = Command::new(&example_path).output()?;
assert!(
output.status.success(),
"Demo mode failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("Demo Mode"), "Not in demo mode");
assert!(stdout.contains("Echo:"), "Demo didn't echo");
assert!(stdout.contains("Sum:"), "Demo didn't add");
println!("Demo mode passed!");
Ok(())
}
#[tokio::test]
async fn test_rpc_simple_multiple_clients() -> Result<()> {
println!("Testing basic with multiple sequential clients");
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")?;
let example_path = format!("{}/../../target/debug/examples/basic", manifest_dir);
let mut server = Command::new(&example_path)
.arg("--server")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
sleep(Duration::from_millis(500)).await;
println!("Running first client...");
let client1 = Command::new(&example_path).arg("--client").output()?;
assert!(client1.status.success(), "First client failed");
println!("Running second client...");
let client2 = Command::new(&example_path).arg("--client").output()?;
assert!(client2.status.success(), "Second client failed");
let stdout2 = String::from_utf8_lossy(&client2.stdout);
assert!(stdout2.contains("Total calls"), "Second client didn't get stats");
println!("Multiple clients passed!");
server.kill()?;
server.wait()?;
Ok(())
}
#[tokio::test]
async fn test_rpc_simple_shutdown_rpc() -> Result<()> {
println!("Testing basic shutdown RPC");
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")?;
let example_path = format!("{}/../../target/debug/examples/basic", manifest_dir);
let mut server = Command::new(&example_path)
.arg("--server")
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
sleep(Duration::from_millis(500)).await;
let client_output = Command::new(&example_path).arg("--client").output()?;
assert!(client_output.status.success(), "Client failed");
let stdout = String::from_utf8_lossy(&client_output.stdout);
assert!(
stdout.contains("Shutdown response:"),
"Client didn't get shutdown response"
);
sleep(Duration::from_millis(100)).await;
assert!(
server.try_wait()?.is_none(),
"Server should still be running after shutdown RPC"
);
println!("Shutdown RPC test passed!");
server.kill()?;
server.wait()?;
Ok(())
}