Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions ros-z-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ ros-z-msgs = { path = "../ros-z-msgs", optional = true }
tokio = { workspace = true, features = ["full"] }
once_cell = { workspace = true } # For lazy static zenohd daemon
serial_test = "3.0" # For sequential test execution
nix = { version = "0.29" , features = ["signal"] }# Used to send ctrl_c to child proccesses
rand = "0.8" # Used for test fuzzing

[features]
default = []
Expand Down
9 changes: 8 additions & 1 deletion ros-z-tests/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ impl Drop for ProcessGuard {
fn drop(&mut self) {
if let Some(mut child) = self.child.take() {
println!("Stopping process: {}", self.name);
let _ = child.kill();
// Note: cannot directly kill a `ros2` command line command
// As that will kill the commandline process without giving it time to shutdown whatever
// child processes it spawns.
let pid = child.id();
// Send Ctrl-C to trigger graceful shutdown
nix::sys::signal::kill(nix::unistd::Pid::from_raw(pid as _), nix::sys::signal::SIGINT)
.expect("Failed to send SIGINT to process");
// Wait for shutdown, we assume procces is well behaved and will exit
let _ = child.wait();
}
}
Expand Down
22 changes: 18 additions & 4 deletions ros-z-tests/tests/service_interop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,12 @@ fn test_ros_z_server_ros2_client() {

println!("\n=== Test: ros-z server <-> ROS2 client ===");

// Use shared state to confirm this specific server gets our specific request
let shared_state = std::sync::Arc::new(std::sync::Mutex::new(0));
let shared_state_clone = shared_state.clone();

// Start ros-z server
let _server = thread::spawn(|| {
let _server = thread::spawn(move || {
let ctx = create_ros_z_context().expect("Failed to create context");

let node = ctx
Expand All @@ -113,11 +117,17 @@ fn test_ros_z_server_ros2_client() {
println!("Sending response: {}", resp.sum);
zsrv.send_response(&resp, &key)
.expect("Failed to send response");
// Store most recent sum in shared state
*shared_state_clone.lock().unwrap() = resp.sum;
}
});

wait_for_ready(Duration::from_secs(10));

// Pick two random values to add
let a = rand::random::<u8>() as i64;
let b = rand::random::<u8>() as i64;

// Call from ros2 CLI
let output = Command::new("timeout")
.args([
Expand All @@ -127,7 +137,7 @@ fn test_ros_z_server_ros2_client() {
"call",
"/add_two_ints",
"example_interfaces/srv/AddTwoInts",
"{a: 10, b: 7}",
&format!("{{a: {}, b: {}}}", a, b),
])
.env("RMW_IMPLEMENTATION", "rmw_zenoh_cpp")
.output()
Expand All @@ -136,11 +146,15 @@ fn test_ros_z_server_ros2_client() {
let stdout = String::from_utf8_lossy(&output.stdout);
println!("ROS2 output: {}", stdout);
assert!(
stdout.contains("sum: 17") || stdout.contains("sum=17"),
"Expected sum: 17, got: {}",
stdout.contains(&format!("sum: {}", a + b)) || stdout.contains(&format!("sum={}", a + b)),
"Expected sum: {}, got: {}",
a + b,
stdout
);

// Confirm server received the request
let received_sum = shared_state.lock().unwrap();
assert_eq!(*received_sum, a + b as i64);
println!("✅ Test passed: ROS2 client called ros-z service");
}

Expand Down
Loading