use super::common::*;
#[test]
fn topic_list_json_refresh_demo_contains_expected_fields() {
let report = temp_path("resource-report", "json");
let output = run_cli(&[
"topic",
"list",
"--report",
report.to_str().expect("utf-8 path"),
"--refresh-demo",
"--json",
]);
assert!(output.status.success(), "stderr: {}", output.stderr);
assert!(output.stdout.contains("\"kind\": \"topic\""));
assert!(output.stdout.contains("/demo/camera/raw"));
}
#[test]
fn middleware_load_refresh_demo_json_contains_totals() {
let report = temp_path("middleware-load", "json");
let output = run_cli(&[
"middleware",
"load",
"--report",
report.to_str().expect("utf-8 path"),
"--refresh-demo",
"--json",
]);
assert!(output.status.success(), "stderr: {}", output.stderr);
assert!(output.stdout.contains("\"topic_pending_total\""));
assert!(output.stdout.contains("\"service_pending_requests_total\""));
}
#[test]
fn help_command_and_flag_show_usage() {
let help = run_cli(&["help"]);
assert!(help.status.success(), "stderr: {}", help.stderr);
assert!(help.stdout.contains("robotrt-cli commands:"));
assert!(help.stdout.contains("topic hz <name>"));
let flag = run_cli(&["--help"]);
assert!(flag.status.success(), "stderr: {}", flag.stderr);
assert!(flag.stdout.contains("plugin list"));
}
#[test]
fn bag_record_and_play_json_roundtrip() {
let bag = temp_path("demo-bag", "rrbag");
let record = run_cli(&[
"bag",
"record",
"--output",
bag.to_str().expect("utf-8 path"),
"--count",
"5",
"--topic",
"/demo/test",
]);
assert!(record.status.success(), "stderr: {}", record.stderr);
let play = run_cli(&[
"bag",
"play",
"--input",
bag.to_str().expect("utf-8 path"),
"--json",
]);
assert!(play.status.success(), "stderr: {}", play.stderr);
assert!(play.stdout.contains("\"total_entries\": 5"));
assert!(play.stdout.contains("\"emitted_entries\": 5"));
let hz = run_cli(&[
"topic",
"hz",
"/demo/test",
"--input",
bag.to_str().expect("utf-8 path"),
"--json",
]);
assert!(hz.status.success(), "stderr: {}", hz.stderr);
assert!(hz.stdout.contains("\"observed_entries\": 5"));
let echo = run_cli(&[
"topic",
"echo",
"/demo/test",
"--input",
bag.to_str().expect("utf-8 path"),
"--limit",
"2",
"--json",
]);
assert!(echo.status.success(), "stderr: {}", echo.stderr);
assert!(echo.stdout.contains("\"entries\""));
assert!(echo.stdout.contains("\"sequence\""));
}
#[test]
fn node_topic_health_graph_plugin_and_mission_commands_work_with_demo_refresh() {
let status = temp_path("status-report", "json");
let status_arg = status.to_str().expect("utf-8 path");
let node_info = run_cli(&[
"node",
"info",
"demo_node",
"--report",
status_arg,
"--refresh-demo",
"--json",
]);
assert!(node_info.status.success(), "stderr: {}", node_info.stderr);
assert!(
node_info
.stdout
.contains("\"api_version\": \"robotrt.node.info.v1\"")
);
assert!(node_info.stdout.contains("\"kind\": \"node_info\""));
assert!(node_info.stdout.contains("\"node_name\": \"demo_node\""));
assert!(node_info.stdout.contains("\"name\": \"demo_node\""));
let topic_info = run_cli(&[
"topic",
"info",
"/demo/camera/raw",
"--report",
status_arg,
"--json",
]);
assert!(topic_info.status.success(), "stderr: {}", topic_info.stderr);
assert!(
topic_info
.stdout
.contains("\"api_version\": \"robotrt.topic.info.v1\"")
);
assert!(topic_info.stdout.contains("\"kind\": \"topic_info\""));
assert!(
topic_info
.stdout
.contains("\"topic_name\": \"/demo/camera/raw\"")
);
assert!(topic_info.stdout.contains("\"schema\": \"sample.image\""));
let health = run_cli(&["health", "--report", status_arg, "--json"]);
assert!(health.status.success(), "stderr: {}", health.stderr);
assert!(health.stdout.contains("\"component\": \"runtime\""));
let graph = run_cli(&["graph", "--report", status_arg, "--json"]);
assert!(graph.status.success(), "stderr: {}", graph.stderr);
assert!(graph.stdout.contains("\"relation\": \"publishes\""));
let plugins = run_cli(&[
"plugin", "list", "--report", status_arg, "--loaded", "--json",
]);
assert!(plugins.status.success(), "stderr: {}", plugins.stderr);
assert!(plugins.stdout.contains("\"loaded_only\": true"));
assert!(
plugins
.stdout
.contains("\"name\": \"sample-device-plugin\"")
);
let watch = run_cli(&[
"mission",
"watch",
"demo_mission",
"--report",
status_arg,
"--iterations",
"1",
"--json",
]);
assert!(watch.status.success(), "stderr: {}", watch.stderr);
assert!(watch.stdout.contains("\"name\": \"demo_mission\""));
let action_info = run_cli(&[
"action",
"info",
"/demo/calibrate",
"--report",
status_arg,
"--json",
]);
assert!(
action_info.status.success(),
"stderr: {}",
action_info.stderr
);
assert!(
action_info
.stdout
.contains("\"api_version\": \"robotrt.action.info.v1\"")
);
assert!(action_info.stdout.contains("\"health_state\": \"active\""));
let action_watch = run_cli(&[
"action",
"watch",
"/demo/calibrate",
"--report",
status_arg,
"--iterations",
"1",
"--json",
]);
assert!(
action_watch.status.success(),
"stderr: {}",
action_watch.stderr
);
assert!(
action_watch
.stdout
.contains("\"api_version\": \"robotrt.action.watch.v1\"")
);
}
#[test]
fn node_info_supports_remote_status_query_endpoint() {
let endpoint = allocate_udp_endpoint();
let mut server = Command::new(env!("CARGO_BIN_EXE_robotrt-cli"))
.args([
"status",
"serve",
"--bind",
endpoint.as_str(),
"--source",
"demo",
"--once",
])
.stdout(Stdio::null())
.stderr(Stdio::piped())
.spawn()
.expect("spawn robotrt-cli status serve");
std::thread::sleep(Duration::from_millis(120));
let mut output = run_cli(&[
"node",
"info",
"demo_node",
"--endpoint",
endpoint.as_str(),
"--timeout-ms",
"2000",
"--json",
]);
for _ in 0..4 {
if output.status.success() {
break;
}
std::thread::sleep(Duration::from_millis(150));
output = run_cli(&[
"node",
"info",
"demo_node",
"--endpoint",
endpoint.as_str(),
"--timeout-ms",
"2000",
"--json",
]);
}
assert!(output.status.success(), "stderr: {}", output.stderr);
assert!(output.stdout.contains("\"mode\": \"remote_service\""));
assert!(
output
.stdout
.contains("\"service\": \"/robotrt/status/query\"")
);
assert!(output.stdout.contains("\"endpoint\": \""));
assert!(
output
.stdout
.contains("\"api_version\": \"robotrt.node.info.v1\"")
);
let status = server.wait().expect("wait status server child");
assert!(
status.success(),
"status serve child exited with {status:?}"
);
}
#[test]
fn daemon_mode_switch_works_for_info_and_list_commands() {
let endpoint = allocate_udp_endpoint();
let mut server_info = Command::new(env!("CARGO_BIN_EXE_robotrt-cli"))
.args([
"status",
"serve",
"--bind",
endpoint.as_str(),
"--source",
"demo",
"--once",
])
.stdout(Stdio::null())
.stderr(Stdio::piped())
.spawn()
.expect("spawn robotrt-cli status serve for info");
std::thread::sleep(Duration::from_millis(120));
let mut info_output = run_cli(&[
"node",
"info",
"demo_node",
"--mode",
"daemon",
"--endpoint",
endpoint.as_str(),
"--json",
]);
for _ in 0..4 {
if info_output.status.success() {
break;
}
std::thread::sleep(Duration::from_millis(150));
info_output = run_cli(&[
"node",
"info",
"demo_node",
"--mode",
"daemon",
"--endpoint",
endpoint.as_str(),
"--json",
]);
}
assert!(info_output.status.success(), "stderr: {}", info_output.stderr);
assert!(info_output.stdout.contains("\"mode\": \"remote_service\""));
let status_info = server_info.wait().expect("wait status serve info child");
assert!(status_info.success(), "status serve info exited with {status_info:?}");
let mut server_list = Command::new(env!("CARGO_BIN_EXE_robotrt-cli"))
.args([
"status",
"serve",
"--bind",
endpoint.as_str(),
"--source",
"demo",
"--once",
])
.stdout(Stdio::null())
.stderr(Stdio::piped())
.spawn()
.expect("spawn robotrt-cli status serve for list");
std::thread::sleep(Duration::from_millis(120));
let mut list_output = run_cli(&[
"service",
"list",
"--mode",
"daemon",
"--endpoint",
endpoint.as_str(),
"--json",
]);
for _ in 0..4 {
if list_output.status.success() {
break;
}
std::thread::sleep(Duration::from_millis(150));
list_output = run_cli(&[
"service",
"list",
"--mode",
"daemon",
"--endpoint",
endpoint.as_str(),
"--json",
]);
}
assert!(list_output.status.success(), "stderr: {}", list_output.stderr);
assert!(list_output.stdout.contains("\"mode\": \"remote_service\""));
assert!(list_output.stdout.contains("\"/demo/echo\""));
let status_list = server_list.wait().expect("wait status serve list child");
assert!(status_list.success(), "status serve list exited with {status_list:?}");
}