From 6a5ff6003c04800b32aba0ad36bb1e0d1a1eb35a Mon Sep 17 00:00:00 2001 From: Jaison Titus Date: Mon, 7 Oct 2019 16:59:54 -0700 Subject: [PATCH] Implementing get_qos_for_publishers/subscribers - Implemented the functions defined in #511 - rcl_get_qos_for_publishers - rcl_get_qos_for_subscribers - Wrote tests for the same Note: colcon build --packages-up-to rcl && colcon test --packages-select rcl && colcon test-result --verbose --test-result-base build/rcl runs successfully without any errors or failures. Signed-off-by: Jaison Titus --- rcl/src/rcl/graph.c | 61 ++++++++++++++++ rcl/test/rcl/test_graph.cpp | 138 ++++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+) diff --git a/rcl/src/rcl/graph.c b/rcl/src/rcl/graph.c index 331d780277..ee983ec082 100644 --- a/rcl/src/rcl/graph.c +++ b/rcl/src/rcl/graph.c @@ -375,6 +375,67 @@ rcl_count_subscribers( return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret); } + +typedef rmw_ret_t (* get_qos_func)( + const rmw_node_t * node, const char * topic_name, + rmw_participants_t * participants); + +rcl_ret_t +__rcl_get_qos_for_participants( + const rcl_node_t * node, + const char * topic_name, + rmw_participants_t * participants, + get_qos_func get_qos_for_participants) +{ + if (!rcl_node_is_valid(node)) { + RCL_SET_ERROR_MSG("Invalid node provided."); + return RCL_RET_NODE_INVALID; // error already set + } + const rcl_node_options_t * node_options = rcl_node_get_options(node); + if (!node_options) { + RCL_SET_ERROR_MSG("Node options are invalid."); + return RCL_RET_NODE_INVALID; // shouldn't happen, but error is already set if so + } + RCL_CHECK_ARGUMENT_FOR_NULL(topic_name, RCL_RET_INVALID_ARGUMENT); + RCL_CHECK_ARGUMENT_FOR_NULL(participants, RCL_RET_INVALID_ARGUMENT); + if (participants->participants != NULL) { + RCL_SET_ERROR_MSG("The variable participants inside rmw_participants_t should be set to null. " + "It will be malloc'd where it gets populated."); + return RCL_RET_INVALID_ARGUMENT; + } + rmw_ret_t rmw_ret = get_qos_for_participants( + rcl_node_get_rmw_handle(node), + topic_name, + participants); + return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret); +} + +rcl_ret_t +rcl_get_qos_for_publishers( + const rcl_node_t * node, + const char * topic_name, + rmw_participants_t * publishers) +{ + return __rcl_get_qos_for_participants( + node, + topic_name, + publishers, + rmw_get_qos_for_publishers); +} + +rcl_ret_t +rcl_get_qos_for_subscribers( + const rcl_node_t * node, + const char * topic_name, + rmw_participants_t * subscribers) +{ + return __rcl_get_qos_for_participants( + node, + topic_name, + subscribers, + rmw_get_qos_for_subscribers); +} + rcl_ret_t rcl_service_server_is_available( const rcl_node_t * node, diff --git a/rcl/test/rcl/test_graph.cpp b/rcl/test/rcl/test_graph.cpp index 28f7cdae78..dd425ed1b6 100644 --- a/rcl/test/rcl/test_graph.cpp +++ b/rcl/test/rcl/test_graph.cpp @@ -63,6 +63,9 @@ class CLASSNAME (TestGraphFixture, RMW_IMPLEMENTATION) : public ::testing::Test rcl_wait_set_t * wait_set_ptr; const char * test_graph_node_name = "test_graph_node"; + rmw_participants_t * participants; + const char * topic_name = "valid_topic_name"; + void SetUp() { rcl_ret_t ret; @@ -101,6 +104,12 @@ class CLASSNAME (TestGraphFixture, RMW_IMPLEMENTATION) : public ::testing::Test ret = rcl_wait_set_init( this->wait_set_ptr, 0, 1, 0, 0, 0, 0, this->context_ptr, rcl_get_default_allocator()); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + + rmw_participants_t valid_participants = { + 0, /*count*/ + nullptr /*participants*/ + }; + this->participants = &valid_participants; } void TearDown() @@ -1321,3 +1330,132 @@ TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), test_rcl_service_server_ wait_for_service_state_to_change(false, is_available); ASSERT_FALSE(is_available); } + + +/* + * This does not test content of the response. + * It only tests if the return code is the one expected. + */ +TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), + test_rcl_get_qos_for_publishers_null_node) +{ + auto ret = rcl_get_qos_for_publishers(nullptr, this->topic_name, this->participants); + EXPECT_EQ(RCL_RET_NODE_INVALID, ret); +} + +/* + * This does not test content of the response. + * It only tests if the return code is the one expected. + */ +TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), + test_rcl_get_qos_for_subscribers_null_node) +{ + auto ret = rcl_get_qos_for_subscribers(nullptr, this->topic_name, this->participants); + EXPECT_EQ(RCL_RET_NODE_INVALID, ret); +} + +/* + * This does not test content of the response. + * It only tests if the return code is the one expected. + */ +TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), + test_rcl_get_qos_for_publishers_invalid_node) +{ + // this->old_node_ptr is a pointer to an invalid node. + auto ret = + rcl_get_qos_for_publishers(this->old_node_ptr, this->topic_name, this->participants); + EXPECT_EQ(RCL_RET_NODE_INVALID, ret); +} + +/* + * This does not test content of the response. + * It only tests if the return code is the one expected. + */ +TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), + test_rcl_get_qos_for_subscribers_invalid_node) +{ + // this->old_node_ptr is a pointer to an invalid node. + auto ret = rcl_get_qos_for_subscribers(this->old_node_ptr, this->topic_name, + this->participants); + EXPECT_EQ(RCL_RET_NODE_INVALID, ret); +} + +/* + * This does not test content of the response. + * It only tests if the return code is the one expected. + */ +TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), + test_rcl_get_qos_for_publishers_null_topic) +{ + auto ret = rcl_get_qos_for_publishers(this->node_ptr, nullptr, this->participants); + EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret); +} + +/* + * This does not test content of the response. + * It only tests if the return code is the one expected. + */ +TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), + test_rcl_get_qos_for_subscribers_null_topic) +{ + auto ret = rcl_get_qos_for_subscribers(this->node_ptr, nullptr, this->participants); + EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret); +} + +/* + * This does not test content of the response. + * It only tests if the return code is the one expected. + */ +TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), + test_rcl_get_qos_for_publishers_null_participants) +{ + auto ret = rcl_get_qos_for_publishers(this->node_ptr, this->topic_name, nullptr); + EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret); +} + +/* + * This does not test content of the response. + * It only tests if the return code is the one expected. + */ +TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), + test_rcl_get_qos_for_subscribers_null_participants) +{ + auto ret = rcl_get_qos_for_subscribers(this->node_ptr, this->topic_name, nullptr); + EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret); +} + +/* + * This does not test content of the response. + * It only tests if the return code is the one expected. + */ +TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), + test_rcl_get_qos_for_publishers_invalid_participants) +{ + // this participant is invalid as the pointer "participants" inside is expected to be null. + this->participants->participants = + reinterpret_cast(malloc( + sizeof(rmw_participant_qos_profile_t *))); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + free(this->participants->participants); + }); + auto ret = rcl_get_qos_for_publishers(this->node_ptr, this->topic_name, this->participants); + EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret); +} + +/* + * This does not test content of the response. + * It only tests if the return code is the one expected. + */ +TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), + test_rcl_get_qos_for_subscribers_invalid_participants) +{ + // this participant is invalid as the pointer "participants" inside is expected to be null. + this->participants->participants = + reinterpret_cast(malloc( + sizeof(rmw_participant_qos_profile_t *))); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT({ + free(this->participants->participants); + }); + auto ret = rcl_get_qos_for_subscribers(this->node_ptr, this->topic_name, this->participants); + EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret); +}