diff --git a/rclrs/Cargo.toml b/rclrs/Cargo.toml index ec761ef3e..69319f659 100644 --- a/rclrs/Cargo.toml +++ b/rclrs/Cargo.toml @@ -26,12 +26,11 @@ libloading = { version = "0.8", optional = true } # Needed for the Message trait, among others rosidl_runtime_rs = "0.4" -[dependencies.builtin_interfaces] -version = "*" - [dev-dependencies] # Needed for e.g. writing yaml files in tests tempfile = "3.3.0" +# Needed for publisher and subscriber tests +test_msgs = {version = "*"} [build-dependencies] # Needed for FFI diff --git a/rclrs/package.xml b/rclrs/package.xml index 12acc5831..4c3754f48 100644 --- a/rclrs/package.xml +++ b/rclrs/package.xml @@ -19,6 +19,8 @@ builtin_interfaces rcl_interfaces rosgraph_msgs + + test_msgs ament_cargo diff --git a/rclrs/src/client.rs b/rclrs/src/client.rs index a8387604f..b7db3a9c4 100644 --- a/rclrs/src/client.rs +++ b/rclrs/src/client.rs @@ -289,3 +289,38 @@ where Ok(()) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::test_helpers::*; + use test_msgs::srv; + + #[test] + fn traits() { + assert_send::>(); + assert_sync::>(); + } + + #[test] + fn test_clients() -> Result<(), RclrsError> { + let namespace = "/test_clients_graph"; + let graph = construct_test_graph(namespace)?; + let _node_2_empty_client = graph + .node2 + .create_client::("graph_test_topic_4")?; + + std::thread::sleep(std::time::Duration::from_millis(200)); + + let client_names_and_types = graph + .node2 + .get_client_names_and_types_by_node(&graph.node2.name(), &graph.node2.namespace())?; + let types = client_names_and_types + .get("/test_clients_graph/graph_test_topic_4") + .unwrap(); + + assert!(types.contains(&"test_msgs/srv/Empty".to_string())); + + Ok(()) + } +} diff --git a/rclrs/src/clock.rs b/rclrs/src/clock.rs index 018c6f5b7..c9253ffed 100644 --- a/rclrs/src/clock.rs +++ b/rclrs/src/clock.rs @@ -195,11 +195,10 @@ unsafe impl Send for rcl_clock_t {} mod tests { use super::*; - fn assert_send() {} - fn assert_sync() {} - #[test] - fn clock_is_send_and_sync() { + fn traits() { + use crate::test_helpers::*; + assert_send::(); assert_sync::(); } diff --git a/rclrs/src/context.rs b/rclrs/src/context.rs index 83ef17c56..7c5d6a763 100644 --- a/rclrs/src/context.rs +++ b/rclrs/src/context.rs @@ -120,11 +120,10 @@ impl Context { mod tests { use super::*; - fn assert_send() {} - fn assert_sync() {} - #[test] - fn context_is_send_and_sync() { + fn traits() { + use crate::test_helpers::*; + assert_send::(); assert_sync::(); } diff --git a/rclrs/src/dynamic_message.rs b/rclrs/src/dynamic_message.rs index 9bbcf7e75..b7b71a506 100644 --- a/rclrs/src/dynamic_message.rs +++ b/rclrs/src/dynamic_message.rs @@ -253,11 +253,10 @@ impl DynamicMessageMetadata { mod tests { use super::*; - fn assert_send() {} - fn assert_sync() {} - #[test] - fn all_types_are_sync_and_send() { + fn traits() { + use crate::test_helpers::*; + assert_send::(); assert_sync::(); } diff --git a/rclrs/src/lib.rs b/rclrs/src/lib.rs index 325cd5b9a..d1ad1f530 100644 --- a/rclrs/src/lib.rs +++ b/rclrs/src/lib.rs @@ -22,6 +22,9 @@ mod time_source; mod vendor; mod wait; +#[cfg(test)] +mod test_helpers; + mod rcl_bindings; #[cfg(feature = "dyn_msg")] diff --git a/rclrs/src/node.rs b/rclrs/src/node.rs index 87702ab0f..c89a1ef74 100644 --- a/rclrs/src/node.rs +++ b/rclrs/src/node.rs @@ -454,13 +454,56 @@ pub(crate) unsafe fn call_string_getter_with_handle( #[cfg(test)] mod tests { use super::*; - - fn assert_send() {} - fn assert_sync() {} + use crate::test_helpers::*; #[test] - fn node_is_send_and_sync() { + fn traits() { assert_send::(); assert_sync::(); } + + #[test] + fn test_topic_names_and_types() -> Result<(), RclrsError> { + use crate::QOS_PROFILE_SYSTEM_DEFAULT; + use test_msgs::msg; + + let graph = construct_test_graph("test_topics_graph")?; + + let _node_1_defaults_subscription = graph.node1.create_subscription::( + "graph_test_topic_3", + QOS_PROFILE_SYSTEM_DEFAULT, + |_msg: msg::Defaults| {}, + )?; + let _node_2_empty_subscription = graph.node2.create_subscription::( + "graph_test_topic_1", + QOS_PROFILE_SYSTEM_DEFAULT, + |_msg: msg::Empty| {}, + )?; + let _node_2_basic_types_subscription = + graph.node2.create_subscription::( + "graph_test_topic_2", + QOS_PROFILE_SYSTEM_DEFAULT, + |_msg: msg::BasicTypes| {}, + )?; + + std::thread::sleep(std::time::Duration::from_millis(100)); + + let topic_names_and_types = graph.node1.get_topic_names_and_types()?; + + let types = topic_names_and_types + .get("/test_topics_graph/graph_test_topic_1") + .unwrap(); + assert!(types.contains(&"test_msgs/msg/Empty".to_string())); + let types = topic_names_and_types + .get("/test_topics_graph/graph_test_topic_2") + .unwrap(); + assert!(types.contains(&"test_msgs/msg/BasicTypes".to_string())); + + let types = topic_names_and_types + .get("/test_topics_graph/graph_test_topic_3") + .unwrap(); + assert!(types.contains(&"test_msgs/msg/Defaults".to_string())); + + Ok(()) + } } diff --git a/rclrs/src/node/graph.rs b/rclrs/src/node/graph.rs index cacf96837..968bb5c4b 100644 --- a/rclrs/src/node/graph.rs +++ b/rclrs/src/node/graph.rs @@ -457,7 +457,6 @@ fn convert_names_and_types( #[cfg(test)] mod tests { - use super::*; use crate::Context; diff --git a/rclrs/src/publisher.rs b/rclrs/src/publisher.rs index a77a41aa4..0f512c5f6 100644 --- a/rclrs/src/publisher.rs +++ b/rclrs/src/publisher.rs @@ -230,3 +230,81 @@ impl<'a, T: Message> MessageCow<'a, T> for &'a T { Cow::Borrowed(self) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::test_helpers::*; + + #[test] + fn traits() { + assert_send::>(); + assert_sync::>(); + } + + #[test] + fn test_publishers() -> Result<(), RclrsError> { + use crate::TopicEndpointInfo; + use crate::QOS_PROFILE_SYSTEM_DEFAULT; + use test_msgs::msg; + + let namespace = "/test_publishers_graph"; + let graph = construct_test_graph(namespace)?; + + let node_1_empty_publisher = graph + .node1 + .create_publisher::("graph_test_topic_1", QOS_PROFILE_SYSTEM_DEFAULT)?; + let topic1 = node_1_empty_publisher.topic_name(); + let node_1_basic_types_publisher = graph.node1.create_publisher::( + "graph_test_topic_2", + QOS_PROFILE_SYSTEM_DEFAULT, + )?; + let topic2 = node_1_basic_types_publisher.topic_name(); + let node_2_default_publisher = graph + .node2 + .create_publisher::("graph_test_topic_3", QOS_PROFILE_SYSTEM_DEFAULT)?; + let topic3 = node_2_default_publisher.topic_name(); + + std::thread::sleep(std::time::Duration::from_millis(100)); + + // Test count_publishers() + assert_eq!(graph.node1.count_publishers(&topic1)?, 1); + assert_eq!(graph.node1.count_publishers(&topic2)?, 1); + assert_eq!(graph.node1.count_publishers(&topic3)?, 1); + + // Test get_publisher_names_and_types_by_node() + let node_1_publisher_names_and_types = graph + .node1 + .get_publisher_names_and_types_by_node(&graph.node1.name(), namespace)?; + + let types = node_1_publisher_names_and_types.get(&topic1).unwrap(); + assert!(types.contains(&"test_msgs/msg/Empty".to_string())); + + let types = node_1_publisher_names_and_types.get(&topic2).unwrap(); + assert!(types.contains(&"test_msgs/msg/BasicTypes".to_string())); + + let node_2_publisher_names_and_types = graph + .node1 + .get_publisher_names_and_types_by_node(&graph.node2.name(), namespace)?; + + let types = node_2_publisher_names_and_types.get(&topic3).unwrap(); + assert!(types.contains(&"test_msgs/msg/Defaults".to_string())); + + // Test get_publishers_info_by_topic() + let expected_publishers_info = vec![TopicEndpointInfo { + node_name: String::from("graph_test_node_1"), + node_namespace: String::from(namespace), + topic_type: String::from("test_msgs/msg/Empty"), + }]; + assert_eq!( + graph.node1.get_publishers_info_by_topic(&topic1)?, + expected_publishers_info + ); + assert_eq!( + graph.node2.get_publishers_info_by_topic(&topic1)?, + expected_publishers_info + ); + + Ok(()) + } +} diff --git a/rclrs/src/publisher/loaned_message.rs b/rclrs/src/publisher/loaned_message.rs index c9b06f1a2..350c1ad23 100644 --- a/rclrs/src/publisher/loaned_message.rs +++ b/rclrs/src/publisher/loaned_message.rs @@ -92,3 +92,16 @@ where Ok(()) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn traits() { + use crate::test_helpers::*; + + assert_send::>(); + assert_sync::>(); + } +} diff --git a/rclrs/src/service.rs b/rclrs/src/service.rs index 8cac799b1..6e55094d6 100644 --- a/rclrs/src/service.rs +++ b/rclrs/src/service.rs @@ -199,3 +199,54 @@ where .ok() } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::test_helpers::*; + + #[test] + fn traits() { + assert_send::>(); + assert_sync::>(); + } + + #[test] + fn test_services() -> Result<(), RclrsError> { + use crate::TopicNamesAndTypes; + use test_msgs::srv; + + let namespace = "/test_services_graph"; + let graph = construct_test_graph(namespace)?; + let check_names_and_types = |names_and_types: TopicNamesAndTypes| { + let types = names_and_types + .get("/test_services_graph/graph_test_topic_4") + .unwrap(); + assert!(types.contains(&"test_msgs/srv/Empty".to_string())); + }; + + let _node_1_empty_service = + graph + .node1 + .create_service::("graph_test_topic_4", |_, _| { + srv::Empty_Response { + structure_needs_at_least_one_member: 0, + } + })?; + let _node_2_empty_client = graph + .node2 + .create_client::("graph_test_topic_4")?; + + std::thread::sleep(std::time::Duration::from_millis(100)); + + let service_names_and_types = graph.node1.get_service_names_and_types()?; + check_names_and_types(service_names_and_types); + + let service_names_and_types = graph + .node1 + .get_service_names_and_types_by_node(&graph.node1.name(), namespace)?; + check_names_and_types(service_names_and_types); + + Ok(()) + } +} diff --git a/rclrs/src/subscription.rs b/rclrs/src/subscription.rs index e684866c2..7e3439df1 100644 --- a/rclrs/src/subscription.rs +++ b/rclrs/src/subscription.rs @@ -300,3 +300,85 @@ where } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::test_helpers::*; + use test_msgs::msg; + + #[test] + fn traits() { + assert_send::>(); + assert_sync::>(); + } + + #[test] + fn test_subscriptions() -> Result<(), RclrsError> { + use crate::TopicEndpointInfo; + use crate::QOS_PROFILE_SYSTEM_DEFAULT; + + let namespace = "/test_subscriptions_graph"; + let graph = construct_test_graph(namespace)?; + + let node_2_empty_subscription = graph.node2.create_subscription::( + "graph_test_topic_1", + QOS_PROFILE_SYSTEM_DEFAULT, + |_msg: msg::Empty| {}, + )?; + let topic1 = node_2_empty_subscription.topic_name(); + let node_2_basic_types_subscription = + graph.node2.create_subscription::( + "graph_test_topic_2", + QOS_PROFILE_SYSTEM_DEFAULT, + |_msg: msg::BasicTypes| {}, + )?; + let topic2 = node_2_basic_types_subscription.topic_name(); + let node_1_defaults_subscription = graph.node1.create_subscription::( + "graph_test_topic_3", + QOS_PROFILE_SYSTEM_DEFAULT, + |_msg: msg::Defaults| {}, + )?; + let topic3 = node_1_defaults_subscription.topic_name(); + + std::thread::sleep(std::time::Duration::from_millis(100)); + + // Test count_subscriptions() + assert_eq!(graph.node2.count_subscriptions(&topic1)?, 1); + assert_eq!(graph.node2.count_subscriptions(&topic2)?, 1); + + // Test get_subscription_names_and_types_by_node() + let node_1_subscription_names_and_types = graph + .node1 + .get_subscription_names_and_types_by_node(&graph.node1.name(), namespace)?; + + let types = node_1_subscription_names_and_types.get(&topic3).unwrap(); + assert!(types.contains(&"test_msgs/msg/Defaults".to_string())); + + let node_2_subscription_names_and_types = graph + .node2 + .get_subscription_names_and_types_by_node(&graph.node2.name(), namespace)?; + + let types = node_2_subscription_names_and_types.get(&topic1).unwrap(); + assert!(types.contains(&"test_msgs/msg/Empty".to_string())); + + let types = node_2_subscription_names_and_types.get(&topic2).unwrap(); + assert!(types.contains(&"test_msgs/msg/BasicTypes".to_string())); + + // Test get_subscriptions_info_by_topic() + let expected_subscriptions_info = vec![TopicEndpointInfo { + node_name: String::from("graph_test_node_2"), + node_namespace: String::from(namespace), + topic_type: String::from("test_msgs/msg/Empty"), + }]; + assert_eq!( + graph.node1.get_subscriptions_info_by_topic(&topic1)?, + expected_subscriptions_info + ); + assert_eq!( + graph.node2.get_subscriptions_info_by_topic(&topic1)?, + expected_subscriptions_info + ); + Ok(()) + } +} diff --git a/rclrs/src/subscription/callback.rs b/rclrs/src/subscription/callback.rs index 9c2931470..d5e9fba8e 100644 --- a/rclrs/src/subscription/callback.rs +++ b/rclrs/src/subscription/callback.rs @@ -132,3 +132,43 @@ where AnySubscriptionCallback::LoanedWithMessageInfo(Box::new(func)) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn callback_conversion() { + type Message = test_msgs::msg::BoundedSequences; + let cb = |_msg: Message| {}; + assert!(matches!( + cb.into_callback(), + AnySubscriptionCallback::::Regular(_) + )); + let cb = |_msg: Message, _info: MessageInfo| {}; + assert!(matches!( + cb.into_callback(), + AnySubscriptionCallback::::RegularWithMessageInfo(_) + )); + let cb = |_msg: Box| {}; + assert!(matches!( + cb.into_callback(), + AnySubscriptionCallback::::Boxed(_) + )); + let cb = |_msg: Box, _info: MessageInfo| {}; + assert!(matches!( + cb.into_callback(), + AnySubscriptionCallback::::BoxedWithMessageInfo(_) + )); + let cb = |_msg: ReadOnlyLoanedMessage<'_, Message>| {}; + assert!(matches!( + cb.into_callback(), + AnySubscriptionCallback::::Loaned(_) + )); + let cb = |_msg: ReadOnlyLoanedMessage<'_, Message>, _info: MessageInfo| {}; + assert!(matches!( + cb.into_callback(), + AnySubscriptionCallback::::LoanedWithMessageInfo(_) + )); + } +} diff --git a/rclrs/src/subscription/message_info.rs b/rclrs/src/subscription/message_info.rs index 1c2ba9936..010bf28ec 100644 --- a/rclrs/src/subscription/message_info.rs +++ b/rclrs/src/subscription/message_info.rs @@ -152,11 +152,10 @@ mod tests { ); } - fn assert_send() {} - fn assert_sync() {} - #[test] - fn wait_set_is_send_and_sync() { + fn traits() { + use crate::test_helpers::*; + assert_send::(); assert_sync::(); } diff --git a/rclrs/src/subscription/readonly_loaned_message.rs b/rclrs/src/subscription/readonly_loaned_message.rs index 7a3e6b550..0e4b55e6f 100644 --- a/rclrs/src/subscription/readonly_loaned_message.rs +++ b/rclrs/src/subscription/readonly_loaned_message.rs @@ -54,3 +54,16 @@ where unsafe impl<'a, T> Send for ReadOnlyLoanedMessage<'a, T> where T: Message {} // SAFETY: This type has no interior mutability, in fact it has no mutability at all. unsafe impl<'a, T> Sync for ReadOnlyLoanedMessage<'a, T> where T: Message {} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn traits() { + use crate::test_helpers::*; + + assert_send::>(); + assert_sync::>(); + } +} diff --git a/rclrs/src/test_helpers/graph_helpers.rs b/rclrs/src/test_helpers/graph_helpers.rs new file mode 100644 index 000000000..1e9b581ae --- /dev/null +++ b/rclrs/src/test_helpers/graph_helpers.rs @@ -0,0 +1,19 @@ +use crate::{Context, Node, NodeBuilder, RclrsError}; +use std::sync::Arc; + +pub(crate) struct TestGraph { + pub node1: Arc, + pub node2: Arc, +} + +pub(crate) fn construct_test_graph(namespace: &str) -> Result { + let context = Context::new([])?; + Ok(TestGraph { + node1: NodeBuilder::new(&context, "graph_test_node_1") + .namespace(namespace) + .build()?, + node2: NodeBuilder::new(&context, "graph_test_node_2") + .namespace(namespace) + .build()?, + }) +} diff --git a/rclrs/src/test_helpers/mod.rs b/rclrs/src/test_helpers/mod.rs new file mode 100644 index 000000000..cd805e6ec --- /dev/null +++ b/rclrs/src/test_helpers/mod.rs @@ -0,0 +1,7 @@ +// #[cfg(test)] + +pub(crate) mod graph_helpers; +pub(crate) use self::graph_helpers::*; + +pub(crate) fn assert_send() {} +pub(crate) fn assert_sync() {} diff --git a/rclrs/src/time.rs b/rclrs/src/time.rs index 53eb45efd..845dd1505 100644 --- a/rclrs/src/time.rs +++ b/rclrs/src/time.rs @@ -1,4 +1,5 @@ use crate::rcl_bindings::*; +use crate::vendor::builtin_interfaces; use std::num::TryFromIntError; use std::ops::{Add, Sub}; use std::sync::{Mutex, Weak}; @@ -70,7 +71,7 @@ mod tests { fn compare_times_from_same_clock() { let clock = Clock::system(); let t1 = clock.now(); - std::thread::sleep(std::time::Duration::from_micros(1)); + std::thread::sleep(Duration::from_micros(1)); let t2 = clock.now(); assert_eq!(t1.compare_with(&t2, |t1, t2| t1 > t2), Some(false)); assert_eq!(t1.compare_with(&t2, |t1, t2| t2 > t1), Some(true)); diff --git a/rclrs/src/wait.rs b/rclrs/src/wait.rs index d8c0e3cb1..94811c75a 100644 --- a/rclrs/src/wait.rs +++ b/rclrs/src/wait.rs @@ -404,11 +404,10 @@ impl WaitSet { mod tests { use super::*; - fn assert_send() {} - fn assert_sync() {} - #[test] - fn wait_set_is_send_and_sync() { + fn traits() { + use crate::test_helpers::*; + assert_send::(); assert_sync::(); } diff --git a/rclrs/src/wait/guard_condition.rs b/rclrs/src/wait/guard_condition.rs index 2bc9ebf64..f4d9f651d 100644 --- a/rclrs/src/wait/guard_condition.rs +++ b/rclrs/src/wait/guard_condition.rs @@ -179,11 +179,10 @@ mod tests { Ok(()) } - fn assert_send() {} - fn assert_sync() {} - #[test] - fn test_guard_condition_is_send_and_sync() { + fn traits() { + use crate::test_helpers::*; + assert_send::(); assert_sync::(); } diff --git a/rclrs_tests/Cargo.toml b/rclrs_tests/Cargo.toml deleted file mode 100644 index 2f484a352..000000000 --- a/rclrs_tests/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "rclrs_tests" -version = "0.4.1" -authors = ["Chris Reid "] -edition = "2021" - -[lib] -path = "src/lib.rs" - -[dependencies] -anyhow = {version = "1", features = ["backtrace"]} -test_msgs = {version = "*"} - -[dependencies.rclrs] -version = "*" - -[dependencies.rosidl_runtime_rs] -version = "*" diff --git a/rclrs_tests/package.xml b/rclrs_tests/package.xml deleted file mode 100644 index e18023270..000000000 --- a/rclrs_tests/package.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - rclrs_tests - 0.4.1 - Package containing tests for rclrs that make use of msgs and other dependencies - Chris Reid - Apache License 2.0 - - test_msgs - rclrs - rosidl_runtime_rs - - - ament_cargo - - diff --git a/rclrs_tests/src/client_service_tests.rs b/rclrs_tests/src/client_service_tests.rs deleted file mode 100644 index a6efa091c..000000000 --- a/rclrs_tests/src/client_service_tests.rs +++ /dev/null @@ -1,16 +0,0 @@ -use rclrs::{Client, Service}; - -fn assert_send() {} -fn assert_sync() {} - -#[test] -fn client_is_send_and_sync() { - assert_send::>(); - assert_sync::>(); -} - -#[test] -fn service_is_send_and_sync() { - assert_send::>(); - assert_sync::>(); -} diff --git a/rclrs_tests/src/graph_tests.rs b/rclrs_tests/src/graph_tests.rs deleted file mode 100644 index 11072e09c..000000000 --- a/rclrs_tests/src/graph_tests.rs +++ /dev/null @@ -1,246 +0,0 @@ -use rclrs::{ - Context, Node, NodeBuilder, RclrsError, TopicEndpointInfo, TopicNamesAndTypes, - QOS_PROFILE_SYSTEM_DEFAULT, -}; -use std::sync::Arc; -use test_msgs::{msg, srv}; - -struct TestGraph { - node1: Arc, - node2: Arc, -} - -fn construct_test_graph(namespace: &str) -> Result { - let context = Context::new([])?; - Ok(TestGraph { - node1: NodeBuilder::new(&context, "graph_test_node_1") - .namespace(namespace) - .build()?, - node2: NodeBuilder::new(&context, "graph_test_node_2") - .namespace(namespace) - .build()?, - }) -} - -#[test] -fn test_publishers() -> Result<(), RclrsError> { - let namespace = "/test_publishers_graph"; - let graph = construct_test_graph(namespace)?; - - let node_1_empty_publisher = graph - .node1 - .create_publisher::("graph_test_topic_1", QOS_PROFILE_SYSTEM_DEFAULT)?; - let topic1 = node_1_empty_publisher.topic_name(); - let node_1_basic_types_publisher = graph - .node1 - .create_publisher::("graph_test_topic_2", QOS_PROFILE_SYSTEM_DEFAULT)?; - let topic2 = node_1_basic_types_publisher.topic_name(); - let node_2_default_publisher = graph - .node2 - .create_publisher::("graph_test_topic_3", QOS_PROFILE_SYSTEM_DEFAULT)?; - let topic3 = node_2_default_publisher.topic_name(); - - std::thread::sleep(std::time::Duration::from_millis(100)); - - // Test count_publishers() - assert_eq!(graph.node1.count_publishers(&topic1)?, 1); - assert_eq!(graph.node1.count_publishers(&topic2)?, 1); - assert_eq!(graph.node1.count_publishers(&topic3)?, 1); - - // Test get_publisher_names_and_types_by_node() - let node_1_publisher_names_and_types = graph - .node1 - .get_publisher_names_and_types_by_node(&graph.node1.name(), namespace)?; - - let types = node_1_publisher_names_and_types.get(&topic1).unwrap(); - assert!(types.contains(&"test_msgs/msg/Empty".to_string())); - - let types = node_1_publisher_names_and_types.get(&topic2).unwrap(); - assert!(types.contains(&"test_msgs/msg/BasicTypes".to_string())); - - let node_2_publisher_names_and_types = graph - .node1 - .get_publisher_names_and_types_by_node(&graph.node2.name(), namespace)?; - - let types = node_2_publisher_names_and_types.get(&topic3).unwrap(); - assert!(types.contains(&"test_msgs/msg/Defaults".to_string())); - - // Test get_publishers_info_by_topic() - let expected_publishers_info = vec![TopicEndpointInfo { - node_name: String::from("graph_test_node_1"), - node_namespace: String::from(namespace), - topic_type: String::from("test_msgs/msg/Empty"), - }]; - assert_eq!( - graph.node1.get_publishers_info_by_topic(&topic1)?, - expected_publishers_info - ); - assert_eq!( - graph.node2.get_publishers_info_by_topic(&topic1)?, - expected_publishers_info - ); - - Ok(()) -} - -#[test] -fn test_subscriptions() -> Result<(), RclrsError> { - let namespace = "/test_subscriptions_graph"; - let graph = construct_test_graph(namespace)?; - - let node_2_empty_subscription = graph.node2.create_subscription::( - "graph_test_topic_1", - QOS_PROFILE_SYSTEM_DEFAULT, - |_msg: msg::Empty| {}, - )?; - let topic1 = node_2_empty_subscription.topic_name(); - let node_2_basic_types_subscription = graph.node2.create_subscription::( - "graph_test_topic_2", - QOS_PROFILE_SYSTEM_DEFAULT, - |_msg: msg::BasicTypes| {}, - )?; - let topic2 = node_2_basic_types_subscription.topic_name(); - let node_1_defaults_subscription = graph.node1.create_subscription::( - "graph_test_topic_3", - QOS_PROFILE_SYSTEM_DEFAULT, - |_msg: msg::Defaults| {}, - )?; - let topic3 = node_1_defaults_subscription.topic_name(); - - std::thread::sleep(std::time::Duration::from_millis(100)); - - // Test count_subscriptions() - assert_eq!(graph.node2.count_subscriptions(&topic1)?, 1); - assert_eq!(graph.node2.count_subscriptions(&topic2)?, 1); - - // Test get_subscription_names_and_types_by_node() - let node_1_subscription_names_and_types = graph - .node1 - .get_subscription_names_and_types_by_node(&graph.node1.name(), namespace)?; - - let types = node_1_subscription_names_and_types.get(&topic3).unwrap(); - assert!(types.contains(&"test_msgs/msg/Defaults".to_string())); - - let node_2_subscription_names_and_types = graph - .node2 - .get_subscription_names_and_types_by_node(&graph.node2.name(), namespace)?; - - let types = node_2_subscription_names_and_types.get(&topic1).unwrap(); - assert!(types.contains(&"test_msgs/msg/Empty".to_string())); - - let types = node_2_subscription_names_and_types.get(&topic2).unwrap(); - assert!(types.contains(&"test_msgs/msg/BasicTypes".to_string())); - - // Test get_subscriptions_info_by_topic() - let expected_subscriptions_info = vec![TopicEndpointInfo { - node_name: String::from("graph_test_node_2"), - node_namespace: String::from(namespace), - topic_type: String::from("test_msgs/msg/Empty"), - }]; - assert_eq!( - graph.node1.get_subscriptions_info_by_topic(&topic1)?, - expected_subscriptions_info - ); - assert_eq!( - graph.node2.get_subscriptions_info_by_topic(&topic1)?, - expected_subscriptions_info - ); - Ok(()) -} - -#[test] -fn test_topic_names_and_types() -> Result<(), RclrsError> { - let graph = construct_test_graph("test_topics_graph")?; - - let _node_1_defaults_subscription = graph.node1.create_subscription::( - "graph_test_topic_3", - QOS_PROFILE_SYSTEM_DEFAULT, - |_msg: msg::Defaults| {}, - )?; - let _node_2_empty_subscription = graph.node2.create_subscription::( - "graph_test_topic_1", - QOS_PROFILE_SYSTEM_DEFAULT, - |_msg: msg::Empty| {}, - )?; - let _node_2_basic_types_subscription = graph.node2.create_subscription::( - "graph_test_topic_2", - QOS_PROFILE_SYSTEM_DEFAULT, - |_msg: msg::BasicTypes| {}, - )?; - - std::thread::sleep(std::time::Duration::from_millis(100)); - - let topic_names_and_types = graph.node1.get_topic_names_and_types()?; - - let types = topic_names_and_types - .get("/test_topics_graph/graph_test_topic_1") - .unwrap(); - assert!(types.contains(&"test_msgs/msg/Empty".to_string())); - let types = topic_names_and_types - .get("/test_topics_graph/graph_test_topic_2") - .unwrap(); - assert!(types.contains(&"test_msgs/msg/BasicTypes".to_string())); - - let types = topic_names_and_types - .get("/test_topics_graph/graph_test_topic_3") - .unwrap(); - assert!(types.contains(&"test_msgs/msg/Defaults".to_string())); - - Ok(()) -} - -#[test] -fn test_services() -> Result<(), RclrsError> { - let namespace = "/test_services_graph"; - let graph = construct_test_graph(namespace)?; - let check_names_and_types = |names_and_types: TopicNamesAndTypes| { - let types = names_and_types - .get("/test_services_graph/graph_test_topic_4") - .unwrap(); - assert!(types.contains(&"test_msgs/srv/Empty".to_string())); - }; - - let _node_1_empty_service = - graph - .node1 - .create_service::("graph_test_topic_4", |_, _| srv::Empty_Response { - structure_needs_at_least_one_member: 0, - })?; - let _node_2_empty_client = graph - .node2 - .create_client::("graph_test_topic_4")?; - - std::thread::sleep(std::time::Duration::from_millis(100)); - - let service_names_and_types = graph.node1.get_service_names_and_types()?; - check_names_and_types(service_names_and_types); - - let service_names_and_types = graph - .node1 - .get_service_names_and_types_by_node(&graph.node1.name(), namespace)?; - check_names_and_types(service_names_and_types); - - Ok(()) -} - -#[test] -fn test_clients() -> Result<(), RclrsError> { - let namespace = "/test_clients_graph"; - let graph = construct_test_graph(namespace)?; - let _node_2_empty_client = graph - .node2 - .create_client::("graph_test_topic_4")?; - - std::thread::sleep(std::time::Duration::from_millis(200)); - - let client_names_and_types = graph - .node2 - .get_client_names_and_types_by_node(&graph.node2.name(), &graph.node2.namespace())?; - let types = client_names_and_types - .get("/test_clients_graph/graph_test_topic_4") - .unwrap(); - - assert!(types.contains(&"test_msgs/srv/Empty".to_string())); - - Ok(()) -} diff --git a/rclrs_tests/src/lib.rs b/rclrs_tests/src/lib.rs deleted file mode 100644 index 7cabab86c..000000000 --- a/rclrs_tests/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![cfg(test)] - -mod client_service_tests; -mod graph_tests; -mod pub_sub_tests; diff --git a/rclrs_tests/src/pub_sub_tests.rs b/rclrs_tests/src/pub_sub_tests.rs deleted file mode 100644 index 039c53350..000000000 --- a/rclrs_tests/src/pub_sub_tests.rs +++ /dev/null @@ -1,66 +0,0 @@ -use rclrs::{ - AnySubscriptionCallback, LoanedMessage, MessageInfo, Publisher, ReadOnlyLoanedMessage, - Subscription, SubscriptionCallback, -}; - -fn assert_send() {} -fn assert_sync() {} - -#[test] -fn publisher_is_send_and_sync() { - assert_send::>(); - assert_sync::>(); -} - -#[test] -fn subscription_is_send_and_sync() { - assert_send::>(); - assert_sync::>(); -} - -#[test] -fn loaned_message_is_send_and_sync() { - assert_send::>(); - assert_sync::>(); -} - -#[test] -fn readonly_loaned_message_is_send_and_sync() { - assert_send::>(); - assert_sync::>(); -} - -#[test] -fn callback_conversion() { - type Message = test_msgs::msg::BoundedSequences; - let cb = |_msg: Message| {}; - assert!(matches!( - cb.into_callback(), - AnySubscriptionCallback::::Regular(_) - )); - let cb = |_msg: Message, _info: MessageInfo| {}; - assert!(matches!( - cb.into_callback(), - AnySubscriptionCallback::::RegularWithMessageInfo(_) - )); - let cb = |_msg: Box| {}; - assert!(matches!( - cb.into_callback(), - AnySubscriptionCallback::::Boxed(_) - )); - let cb = |_msg: Box, _info: MessageInfo| {}; - assert!(matches!( - cb.into_callback(), - AnySubscriptionCallback::::BoxedWithMessageInfo(_) - )); - let cb = |_msg: ReadOnlyLoanedMessage<'_, Message>| {}; - assert!(matches!( - cb.into_callback(), - AnySubscriptionCallback::::Loaned(_) - )); - let cb = |_msg: ReadOnlyLoanedMessage<'_, Message>, _info: MessageInfo| {}; - assert!(matches!( - cb.into_callback(), - AnySubscriptionCallback::::LoanedWithMessageInfo(_) - )); -}