From 4638f388ff89d47b9bb9d052b4b58849627c0ef8 Mon Sep 17 00:00:00 2001 From: "Minju, Lee" <70446214+leeminju531@users.noreply.github.com> Date: Fri, 29 Sep 2023 21:35:00 +0900 Subject: [PATCH] Add rmw_count_clients,services & test (#208) * Add rmw_count_clients,services & test Signed-off-by: leeminju531 --- rmw_implementation/src/functions.cpp | 14 ++ test_rmw_implementation/CMakeLists.txt | 2 +- .../test/test_graph_api.cpp | 150 ++++++++++++++++++ 3 files changed, 165 insertions(+), 1 deletion(-) diff --git a/rmw_implementation/src/functions.cpp b/rmw_implementation/src/functions.cpp index e8d35c64..dceb680a 100644 --- a/rmw_implementation/src/functions.cpp +++ b/rmw_implementation/src/functions.cpp @@ -646,6 +646,16 @@ RMW_INTERFACE_FN( rmw_ret_t, RMW_RET_ERROR, 3, ARG_TYPES(const rmw_node_t *, const char *, size_t *)) +RMW_INTERFACE_FN( + rmw_count_clients, + rmw_ret_t, RMW_RET_ERROR, + 3, ARG_TYPES(const rmw_node_t *, const char *, size_t *)) + +RMW_INTERFACE_FN( + rmw_count_services, + rmw_ret_t, RMW_RET_ERROR, + 3, ARG_TYPES(const rmw_node_t *, const char *, size_t *)) + RMW_INTERFACE_FN( rmw_get_gid_for_client, rmw_ret_t, RMW_RET_ERROR, @@ -847,6 +857,8 @@ void prefetch_symbols(void) GET_SYMBOL(rmw_get_node_names_with_enclaves) GET_SYMBOL(rmw_count_publishers) GET_SYMBOL(rmw_count_subscribers) + GET_SYMBOL(rmw_count_clients) + GET_SYMBOL(rmw_count_services) GET_SYMBOL(rmw_get_gid_for_client) GET_SYMBOL(rmw_get_gid_for_publisher) GET_SYMBOL(rmw_compare_gids_equal) @@ -969,6 +981,8 @@ unload_library() symbol_rmw_get_node_names_with_enclaves = nullptr; symbol_rmw_count_publishers = nullptr; symbol_rmw_count_subscribers = nullptr; + symbol_rmw_count_clients = nullptr; + symbol_rmw_count_services = nullptr; symbol_rmw_get_gid_for_client = nullptr; symbol_rmw_get_gid_for_publisher = nullptr; symbol_rmw_compare_gids_equal = nullptr; diff --git a/test_rmw_implementation/CMakeLists.txt b/test_rmw_implementation/CMakeLists.txt index a137e441..811e5a74 100644 --- a/test_rmw_implementation/CMakeLists.txt +++ b/test_rmw_implementation/CMakeLists.txt @@ -128,7 +128,7 @@ if(BUILD_TESTING) target_compile_definitions(test_graph_api${target_suffix} PUBLIC "RMW_IMPLEMENTATION=${rmw_implementation}") ament_target_dependencies(test_graph_api${target_suffix} - osrf_testing_tools_cpp rcutils rmw rmw_implementation + osrf_testing_tools_cpp rcutils rmw rmw_implementation test_msgs ) ament_add_gtest(test_unique_identifiers${target_suffix} diff --git a/test_rmw_implementation/test/test_graph_api.cpp b/test_rmw_implementation/test/test_graph_api.cpp index 128e4c66..d482f74b 100644 --- a/test_rmw_implementation/test/test_graph_api.cpp +++ b/test_rmw_implementation/test/test_graph_api.cpp @@ -27,6 +27,8 @@ #include "rmw/rmw.h" #include "rmw/sanity_checks.h" +#include "test_msgs/srv/basic_types.h" + #include "./config.hpp" #include "./testing_macros.hpp" @@ -913,3 +915,151 @@ TEST_F(CLASSNAME(TestGraphAPI, RMW_IMPLEMENTATION), count_subscribers_with_bad_a EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_count_subscribers(node, topic_name, nullptr)); rmw_reset_error(); } + +TEST_F(CLASSNAME(TestGraphAPI, RMW_IMPLEMENTATION), count_clients_with_bad_arguments) { + size_t count = 0u; + constexpr char service_name[] = "/test_service"; + + // A null node is an invalid argument. + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_count_clients(nullptr, service_name, &count)); + rmw_reset_error(); + + // A node from a different implementation cannot be used to query. + const char * implementation_identifier = node->implementation_identifier; + node->implementation_identifier = "not-an-rmw-implementation-identifier"; + EXPECT_EQ(RMW_RET_INCORRECT_RMW_IMPLEMENTATION, rmw_count_clients(node, service_name, &count)); + node->implementation_identifier = implementation_identifier; + rmw_reset_error(); + + // A null service name is an invalid argument. + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_count_clients(node, nullptr, &count)); + rmw_reset_error(); + + // An invalid service name is an invalid argument. + constexpr char invalid_service_name[] = "not a valid service name !"; + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_count_clients(node, invalid_service_name, &count)); + rmw_reset_error(); + + // A null count is an invalid argument. + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_count_clients(node, service_name, nullptr)); + rmw_reset_error(); +} + +TEST_F(CLASSNAME(TestGraphAPI, RMW_IMPLEMENTATION), count_services_with_bad_arguments) { + size_t count = 0u; + constexpr char service_name[] = "/test_service"; + // A null node is an invalid argument. + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_count_services(nullptr, service_name, &count)); + rmw_reset_error(); + + // A node from a different implementation cannot be used to query. + const char * implementation_identifier = node->implementation_identifier; + node->implementation_identifier = "not-an-rmw-implementation-identifier"; + EXPECT_EQ(RMW_RET_INCORRECT_RMW_IMPLEMENTATION, rmw_count_services(node, service_name, &count)); + node->implementation_identifier = implementation_identifier; + rmw_reset_error(); + + // A null service name is an invalid argument. + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_count_services(node, nullptr, &count)); + rmw_reset_error(); + + // An invalid service name is an invalid argument. + constexpr char invalid_service_name[] = "not a valid service name !"; + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_count_services(node, invalid_service_name, &count)); + rmw_reset_error(); + + // A null count is an invalid argument. + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_count_services(node, service_name, nullptr)); + rmw_reset_error(); +} + +TEST_F(CLASSNAME(TestGraphAPI, RMW_IMPLEMENTATION), count_clients_and_services) { + constexpr char service_name[] = "/test_service"; + const rosidl_service_type_support_t * ts = + ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes); + size_t count = 0u; + rmw_ret_t ret; + rmw_service_t * srv = rmw_create_service( + other_node, ts, service_name, &rmw_qos_profile_services_default); + ASSERT_NE(nullptr, srv) << rmw_get_error_string().str; + + SLEEP_AND_RETRY_UNTIL(rmw_intraprocess_discovery_delay, rmw_intraprocess_discovery_delay * 10) { + ret = rmw_count_services(node, service_name, &count); + ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + if (RMW_RET_OK == ret && 1u == count) { + break; + } + } + + EXPECT_NO_MEMORY_OPERATIONS( + { + ret = rmw_count_services(node, service_name, &count); + }); + EXPECT_EQ(RMW_RET_OK, ret); + EXPECT_EQ(1u, count); + count = 0u; + + rmw_client_t * client = rmw_create_client( + other_node, ts, service_name, &rmw_qos_profile_services_default); + ASSERT_NE(nullptr, client) << rmw_get_error_string().str; + + SLEEP_AND_RETRY_UNTIL(rmw_intraprocess_discovery_delay, rmw_intraprocess_discovery_delay * 10) { + ret = rmw_count_clients(node, service_name, &count); + ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + if (RMW_RET_OK == ret && 1u == count) { + break; + } + } + + EXPECT_NO_MEMORY_OPERATIONS( + { + ret = rmw_count_clients(node, service_name, &count); + }); + EXPECT_EQ(RMW_RET_OK, ret); + EXPECT_EQ(1u, count); + count = 0u; + + rmw_service_t * srv2 = rmw_create_service( + node, ts, service_name, &rmw_qos_profile_services_default); + ASSERT_NE(nullptr, srv2) << rmw_get_error_string().str; + + SLEEP_AND_RETRY_UNTIL(rmw_intraprocess_discovery_delay, rmw_intraprocess_discovery_delay * 10) { + ret = rmw_count_services(node, service_name, &count); + ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + if (RMW_RET_OK == ret && 2u == count) { + break; + } + } + + EXPECT_NO_MEMORY_OPERATIONS( + { + ret = rmw_count_services(node, service_name, &count); + }); + EXPECT_EQ(RMW_RET_OK, ret); + EXPECT_EQ(2u, count); + count = 0u; + + rmw_client_t * client2 = rmw_create_client( + node, ts, service_name, &rmw_qos_profile_services_default); + ASSERT_NE(nullptr, client2) << rmw_get_error_string().str; + + SLEEP_AND_RETRY_UNTIL(rmw_intraprocess_discovery_delay, rmw_intraprocess_discovery_delay * 10) { + ret = rmw_count_clients(node, service_name, &count); + ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + if (RMW_RET_OK == ret && 2u == count) { + break; + } + } + + EXPECT_NO_MEMORY_OPERATIONS( + { + ret = rmw_count_clients(node, service_name, &count); + }); + EXPECT_EQ(RMW_RET_OK, ret); + EXPECT_EQ(2u, count); + + EXPECT_EQ(RMW_RET_OK, rmw_destroy_client(other_node, client)) << rmw_get_error_string().str; + EXPECT_EQ(RMW_RET_OK, rmw_destroy_service(other_node, srv)) << rmw_get_error_string().str; + EXPECT_EQ(RMW_RET_OK, rmw_destroy_client(node, client2)) << rmw_get_error_string().str; + EXPECT_EQ(RMW_RET_OK, rmw_destroy_service(node, srv2)) << rmw_get_error_string().str; +}