diff --git a/rcl/include/rcl/client.h b/rcl/include/rcl/client.h index d8bba97..77b8e32 100644 --- a/rcl/include/rcl/client.h +++ b/rcl/include/rcl/client.h @@ -389,6 +389,7 @@ rcl_client_get_rmw_handle(const rcl_client_t * client); * \param[in] client pointer to the rcl client * \return `true` if `client` is valid, otherwise `false` */ +RCL_PUBLIC bool rcl_client_is_valid(const rcl_client_t * client); diff --git a/rcl/include/rcl/publisher.h b/rcl/include/rcl/publisher.h index 315df65..d3d1a04 100644 --- a/rcl/include/rcl/publisher.h +++ b/rcl/include/rcl/publisher.h @@ -353,9 +353,9 @@ rcl_publisher_get_rmw_handle(const rcl_publisher_t * publisher); * Lock-Free | Yes * * \param[in] publisher pointer to the rcl publisher - * \return `true` if the publisher is valid, otherwise `false` + * \return `true` if `publisher` is valid, otherwise `false` */ - +RCL_PUBLIC bool rcl_publisher_is_valid(const rcl_publisher_t * publisher); diff --git a/rcl/include/rcl/service.h b/rcl/include/rcl/service.h index 44e6f7e..5133779 100644 --- a/rcl/include/rcl/service.h +++ b/rcl/include/rcl/service.h @@ -401,6 +401,7 @@ rcl_service_get_rmw_handle(const rcl_service_t * service); * \param[in] service pointer to the rcl service * \return `true` if `service` is valid, otherwise `false` */ +RCL_PUBLIC bool rcl_service_is_valid(const rcl_service_t * service); diff --git a/rcl/include/rcl/subscription.h b/rcl/include/rcl/subscription.h index e78c213..76390e4 100644 --- a/rcl/include/rcl/subscription.h +++ b/rcl/include/rcl/subscription.h @@ -358,6 +358,7 @@ rcl_subscription_get_rmw_handle(const rcl_subscription_t * subscription); * \param[in] subscription pointer to the rcl subscription * \return `true` if `subscription` is valid, otherwise `false` */ +RCL_PUBLIC bool rcl_subscription_is_valid(const rcl_subscription_t * subscription); diff --git a/rcl/test/rcl/test_client.cpp b/rcl/test/rcl/test_client.cpp index fe50085..e7fd362 100644 --- a/rcl/test/rcl/test_client.cpp +++ b/rcl/test/rcl/test_client.cpp @@ -129,6 +129,22 @@ TEST_F(TestClientFixture, test_client_init_fini) { EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret) << rcl_get_error_string_safe(); rcl_reset_error(); + // Check if null publisher is valid + EXPECT_FALSE(rcl_client_is_valid(nullptr)); + rcl_reset_error(); + + // Check if zero initialized client is valid + client = rcl_get_zero_initialized_client(); + EXPECT_FALSE(rcl_client_is_valid(&client)); + rcl_reset_error(); + + // Check that a valid client is valid + client = rcl_get_zero_initialized_client(); + ret = rcl_client_init(&client, this->node_ptr, ts, topic_name, &default_client_options); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe(); + EXPECT_TRUE(rcl_client_is_valid(&client)); + rcl_reset_error(); + // Try passing an invalid (uninitialized) node in init. client = rcl_get_zero_initialized_client(); rcl_node_t invalid_node = rcl_get_zero_initialized_node(); diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 93a3091..d8b993d 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -144,6 +144,21 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_publisher_init_ const char * topic_name = "chatter"; rcl_publisher_options_t default_publisher_options = rcl_publisher_get_default_options(); + // Check if null publisher is valid + EXPECT_FALSE(rcl_publisher_is_valid(nullptr)); + + // Check if zero initialized node is valid + publisher = rcl_get_zero_initialized_publisher(); + EXPECT_FALSE(rcl_publisher_is_valid(&publisher)); + rcl_reset_error(); + + // Check that valid publisher is valid + publisher = rcl_get_zero_initialized_publisher(); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &default_publisher_options); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe(); + EXPECT_TRUE(rcl_publisher_is_valid(&publisher)); + rcl_reset_error(); + // Try passing null for publisher in init. ret = rcl_publisher_init(nullptr, this->node_ptr, ts, topic_name, &default_publisher_options); EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret) << rcl_get_error_string_safe(); diff --git a/rcl/test/rcl/test_service.cpp b/rcl/test/rcl/test_service.cpp index 29f19b8..e51d787 100644 --- a/rcl/test/rcl/test_service.cpp +++ b/rcl/test/rcl/test_service.cpp @@ -127,6 +127,22 @@ TEST_F(CLASSNAME(TestServiceFixture, RMW_IMPLEMENTATION), test_service_nominal) ret = rcl_service_init(&service, this->node_ptr, ts, topic, &service_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe(); + // Check if null service is valid + EXPECT_FALSE(rcl_service_is_valid(nullptr)); + rcl_reset_error(); + + // Check if zero initialized client is valid + service = rcl_get_zero_initialized_service(); + EXPECT_FALSE(rcl_service_is_valid(&service)); + rcl_reset_error(); + + // Check that a valid service is valid + service = rcl_get_zero_initialized_service(); + ret = rcl_service_init(&service, this->node_ptr, ts, topic, &service_options); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe(); + EXPECT_TRUE(rcl_service_is_valid(&service)); + rcl_reset_error(); + // Check that the service name matches what we assigned. EXPECT_EQ(strcmp(rcl_service_get_service_name(&service), expected_topic), 0); auto service_exit = make_scope_exit( @@ -147,7 +163,6 @@ TEST_F(CLASSNAME(TestServiceFixture, RMW_IMPLEMENTATION), test_service_nominal) EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe(); }); - // TODO(wjwwood): add logic to wait for the connection to be established // use count_services busy wait mechanism // until then we will sleep for a short period of time diff --git a/rcl/test/rcl/test_subscription.cpp b/rcl/test/rcl/test_subscription.cpp index d30e58c..9d5e39f 100644 --- a/rcl/test/rcl/test_subscription.cpp +++ b/rcl/test/rcl/test_subscription.cpp @@ -152,6 +152,23 @@ TEST_F(CLASSNAME(TestSubscriptionFixture, RMW_IMPLEMENTATION), test_subscription EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe(); }); EXPECT_EQ(strcmp(rcl_subscription_get_topic_name(&subscription), expected_topic), 0); + + // Test is_valid for subscription with nullptr + EXPECT_FALSE(rcl_subscription_is_valid(nullptr)); + rcl_reset_error(); + + // Test is_valid for zero initialized subscription + subscription = rcl_get_zero_initialized_subscription(); + EXPECT_FALSE(rcl_subscription_is_valid(&subscription)); + rcl_reset_error(); + + // Check that valid subscriber is valid + subscription = rcl_get_zero_initialized_subscription(); + ret = rcl_subscription_init(&subscription, this->node_ptr, ts, topic, &subscription_options); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string_safe(); + EXPECT_TRUE(rcl_subscription_is_valid(&subscription)); + rcl_reset_error(); + // TODO(wjwwood): add logic to wait for the connection to be established // probably using the count_subscriptions busy wait mechanism // until then we will sleep for a short period of time