From dc3307be5a7472b0d0a91f153253f71dcf125955 Mon Sep 17 00:00:00 2001 From: Mauro Passerino Date: Fri, 24 Sep 2021 17:33:14 +0100 Subject: [PATCH 1/5] Add client/service QoS getters Signed-off-by: Mauro Passerino --- rcl/include/rcl/client.h | 26 ++++++++++++++++++++++++++ rcl/include/rcl/service.h | 26 ++++++++++++++++++++++++++ rcl/src/rcl/client.c | 18 ++++++++++++++++++ rcl/src/rcl/service.c | 18 ++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/rcl/include/rcl/client.h b/rcl/include/rcl/client.h index 39715f181..28c9bd78d 100644 --- a/rcl/include/rcl/client.h +++ b/rcl/include/rcl/client.h @@ -409,6 +409,32 @@ RCL_PUBLIC bool rcl_client_is_valid(const rcl_client_t * client); +/// Get the actual qos settings of the client. +/** + * Used to get the actual qos settings of the client. + * The actual configuration applied when using RMW_*_SYSTEM_DEFAULT + * can only be resolved after the creation of the client, and it + * depends on the underlying rmw implementation. + * If the underlying setting in use can't be represented in ROS terms, + * it will be set to RMW_*_UNKNOWN. + * The returned struct is only valid as long as the rcl_client_t is valid. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[in] client pointer to the rcl client + * \return qos struct if successful, otherwise `NULL` + */ +RCL_PUBLIC +RCL_WARN_UNUSED +const rmw_qos_profile_t * +rcl_client_get_actual_qos(const rcl_client_t * client); + #ifdef __cplusplus } #endif diff --git a/rcl/include/rcl/service.h b/rcl/include/rcl/service.h index 82c33c110..d75a86109 100644 --- a/rcl/include/rcl/service.h +++ b/rcl/include/rcl/service.h @@ -440,6 +440,32 @@ RCL_PUBLIC bool rcl_service_is_valid(const rcl_service_t * service); +/// Get the actual qos settings of the service. +/** + * Used to get the actual qos settings of the service. + * The actual configuration applied when using RMW_*_SYSTEM_DEFAULT + * can only be resolved after the creation of the service, and it + * depends on the underlying rmw implementation. + * If the underlying setting in use can't be represented in ROS terms, + * it will be set to RMW_*_UNKNOWN. + * The returned struct is only valid as long as the rcl_service_t is valid. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[in] service pointer to the rcl service + * \return qos struct if successful, otherwise `NULL` + */ +RCL_PUBLIC +RCL_WARN_UNUSED +const rmw_qos_profile_t * +rcl_service_get_actual_qos(const rcl_service_t * service); + #ifdef __cplusplus } #endif diff --git a/rcl/src/rcl/client.c b/rcl/src/rcl/client.c index 433ed3f04..e1ff944bc 100644 --- a/rcl/src/rcl/client.c +++ b/rcl/src/rcl/client.c @@ -36,6 +36,7 @@ extern "C" struct rcl_client_impl_s { rcl_client_options_t options; + rmw_qos_profile_t actual_qos; rmw_client_t * rmw_handle; atomic_int_least64_t sequence_number; }; @@ -111,6 +112,14 @@ rcl_client_init( RCL_SET_ERROR_MSG(rmw_get_error_string().str); goto fail; } + // get actual qos, and store it + rmw_ret_t rmw_ret = rmw_client_get_actual_qos( + client->impl->rmw_handle, + &client->impl->actual_qos); + if (RMW_RET_OK != rmw_ret) { + RCL_SET_ERROR_MSG(rmw_get_error_string().str); + goto fail; + } // options client->impl->options = *options; atomic_init(&client->impl->sequence_number, 0); @@ -280,6 +289,15 @@ rcl_client_is_valid(const rcl_client_t * client) client->impl->rmw_handle, "client's rmw handle is invalid", return false); return true; } + +const rmw_qos_profile_t * +rcl_client_get_actual_qos(const rcl_client_t * client) +{ + if (!rcl_client_is_valid(client)) { + return NULL; + } + return &client->impl->actual_qos; +} #ifdef __cplusplus } #endif diff --git a/rcl/src/rcl/service.c b/rcl/src/rcl/service.c index f97110659..6aef0f8ea 100644 --- a/rcl/src/rcl/service.c +++ b/rcl/src/rcl/service.c @@ -33,6 +33,7 @@ extern "C" struct rcl_service_impl_s { rcl_service_options_t options; + rmw_qos_profile_t actual_qos; rmw_service_t * rmw_handle; }; @@ -122,6 +123,14 @@ rcl_service_init( RCL_SET_ERROR_MSG(rmw_get_error_string().str); goto fail; } + // get actual qos, and store it + rmw_ret_t rmw_ret = rmw_service_get_actual_qos( + service->impl->rmw_handle, + &service->impl->actual_qos); + if (RMW_RET_OK != rmw_ret) { + RCL_SET_ERROR_MSG(rmw_get_error_string().str); + goto fail; + } // options service->impl->options = *options; RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Service initialized"); @@ -301,6 +310,15 @@ rcl_service_is_valid(const rcl_service_t * service) return true; } +const rmw_qos_profile_t * +rcl_service_get_actual_qos(const rcl_service_t * service) +{ + if (!rcl_service_is_valid(service)) { + return NULL; + } + return &service->impl->actual_qos; +} + #ifdef __cplusplus } #endif From 23e9da395a21b1f76c457e4b8f3abd4b4f8ce7b3 Mon Sep 17 00:00:00 2001 From: Mauro Passerino Date: Thu, 14 Oct 2021 18:28:32 +0100 Subject: [PATCH 2/5] Don't allow Client/Services to use system default QoS Signed-off-by: Mauro Passerino --- rcl/src/rcl/client.c | 20 ++++++++++++++++++++ rcl/src/rcl/service.c | 18 ++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/rcl/src/rcl/client.c b/rcl/src/rcl/client.c index e1ff944bc..5dedc933e 100644 --- a/rcl/src/rcl/client.c +++ b/rcl/src/rcl/client.c @@ -100,6 +100,20 @@ rcl_client_init( sizeof(rcl_client_impl_t), allocator->state); RCL_CHECK_FOR_NULL_WITH_MSG( client->impl, "allocating memory failed", ret = RCL_RET_BAD_ALLOC; goto cleanup); + + // Check the qos profile. If some fields are set as system default, + // it can happen that the DDS chooses different QoS policies for entities + // belonging to the client. The QoS of the client should match the QoS of + // all entities belonging to it. + const rmw_qos_profile_t * qos = &options->qos; + if (qos->history == RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT || + qos->reliability == RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT || + qos->durability == RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT || + qos->depth == RMW_QOS_POLICY_DEPTH_SYSTEM_DEFAULT) + { + RCL_SET_ERROR_MSG("system default qos not supported on clients"); + goto fail; + } // Fill out implementation struct. // rmw handle (create rmw client) // TODO(wjwwood): pass along the allocator to rmw when it supports it @@ -116,6 +130,12 @@ rcl_client_init( rmw_ret_t rmw_ret = rmw_client_get_actual_qos( client->impl->rmw_handle, &client->impl->actual_qos); + + // ROS specific namespacing conventions avoidance + // is not retrieved by get_actual_qos + client->impl->actual_qos.avoid_ros_namespace_conventions = + options->qos.avoid_ros_namespace_conventions; + if (RMW_RET_OK != rmw_ret) { RCL_SET_ERROR_MSG(rmw_get_error_string().str); goto fail; diff --git a/rcl/src/rcl/service.c b/rcl/src/rcl/service.c index 6aef0f8ea..f26ace6e4 100644 --- a/rcl/src/rcl/service.c +++ b/rcl/src/rcl/service.c @@ -111,6 +111,19 @@ rcl_service_init( "Warning: Setting QoS durability to 'transient local' for service servers " "can cause them to receive requests from clients that have since terminated."); } + // Check the qos profile. If some fields are set as system default, + // it can happen that the DDS chooses different QoS policies for entities + // belonging to the service. The QoS of the service should match the QoS of + // all entities belonging to it. + const rmw_qos_profile_t * qos = &options->qos; + if (qos->history == RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT || + qos->reliability == RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT || + qos->durability == RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT || + qos->depth == RMW_QOS_POLICY_DEPTH_SYSTEM_DEFAULT) + { + RCL_SET_ERROR_MSG("system default qos not supported on clients"); + goto fail; + } // Fill out implementation struct. // rmw handle (create rmw service) // TODO(wjwwood): pass along the allocator to rmw when it supports it @@ -131,6 +144,11 @@ rcl_service_init( RCL_SET_ERROR_MSG(rmw_get_error_string().str); goto fail; } + + // ROS specific namespacing conventions is not retrieved by get_actual_qos + service->impl->actual_qos.avoid_ros_namespace_conventions = + options->qos.avoid_ros_namespace_conventions; + // options service->impl->options = *options; RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Service initialized"); From 52b04a99a1b98086b54a9fb3e624323b7941e8e1 Mon Sep 17 00:00:00 2001 From: Mauro Passerino Date: Mon, 1 Nov 2021 13:43:25 +0000 Subject: [PATCH 3/5] Add serv/cli request/response qos getters Signed-off-by: Mauro Passerino --- rcl/include/rcl/client.h | 32 ++++++++++++++++++++--- rcl/include/rcl/service.h | 32 ++++++++++++++++++++--- rcl/src/rcl/client.c | 55 +++++++++++++++++++++++---------------- rcl/src/rcl/service.c | 47 +++++++++++++++++++-------------- 4 files changed, 118 insertions(+), 48 deletions(-) diff --git a/rcl/include/rcl/client.h b/rcl/include/rcl/client.h index 28c9bd78d..94290982a 100644 --- a/rcl/include/rcl/client.h +++ b/rcl/include/rcl/client.h @@ -409,9 +409,9 @@ RCL_PUBLIC bool rcl_client_is_valid(const rcl_client_t * client); -/// Get the actual qos settings of the client. +/// Get the actual qos settings of the client's request publisher. /** - * Used to get the actual qos settings of the client. + * Used to get the actual qos settings of the client's request publisher. * The actual configuration applied when using RMW_*_SYSTEM_DEFAULT * can only be resolved after the creation of the client, and it * depends on the underlying rmw implementation. @@ -433,7 +433,33 @@ rcl_client_is_valid(const rcl_client_t * client); RCL_PUBLIC RCL_WARN_UNUSED const rmw_qos_profile_t * -rcl_client_get_actual_qos(const rcl_client_t * client); +rcl_client_request_publisher_get_actual_qos(const rcl_client_t * client); + +/// Get the actual qos settings of the client's response subscription. +/** + * Used to get the actual qos settings of the client's response subscription. + * The actual configuration applied when using RMW_*_SYSTEM_DEFAULT + * can only be resolved after the creation of the client, and it + * depends on the underlying rmw implementation. + * If the underlying setting in use can't be represented in ROS terms, + * it will be set to RMW_*_UNKNOWN. + * The returned struct is only valid as long as the rcl_client_t is valid. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[in] client pointer to the rcl client + * \return qos struct if successful, otherwise `NULL` + */ +RCL_PUBLIC +RCL_WARN_UNUSED +const rmw_qos_profile_t * +rcl_client_response_subscription_get_actual_qos(const rcl_client_t * client); #ifdef __cplusplus } diff --git a/rcl/include/rcl/service.h b/rcl/include/rcl/service.h index d75a86109..b102d14c9 100644 --- a/rcl/include/rcl/service.h +++ b/rcl/include/rcl/service.h @@ -440,9 +440,9 @@ RCL_PUBLIC bool rcl_service_is_valid(const rcl_service_t * service); -/// Get the actual qos settings of the service. +/// Get the actual qos settings of the service's request subscription. /** - * Used to get the actual qos settings of the service. + * Used to get the actual qos settings of the service's request subscription. * The actual configuration applied when using RMW_*_SYSTEM_DEFAULT * can only be resolved after the creation of the service, and it * depends on the underlying rmw implementation. @@ -464,7 +464,33 @@ rcl_service_is_valid(const rcl_service_t * service); RCL_PUBLIC RCL_WARN_UNUSED const rmw_qos_profile_t * -rcl_service_get_actual_qos(const rcl_service_t * service); +rcl_service_request_subscription_get_actual_qos(const rcl_service_t * service); + +/// Get the actual qos settings of the service's response publisher. +/** + * Used to get the actual qos settings of the service's response publisher. + * The actual configuration applied when using RMW_*_SYSTEM_DEFAULT + * can only be resolved after the creation of the service, and it + * depends on the underlying rmw implementation. + * If the underlying setting in use can't be represented in ROS terms, + * it will be set to RMW_*_UNKNOWN. + * The returned struct is only valid as long as the rcl_service_t is valid. + * + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + * + * \param[in] service pointer to the rcl service + * \return qos struct if successful, otherwise `NULL` + */ +RCL_PUBLIC +RCL_WARN_UNUSED +const rmw_qos_profile_t * +rcl_service_response_publisher_get_actual_qos(const rcl_service_t * service); #ifdef __cplusplus } diff --git a/rcl/src/rcl/client.c b/rcl/src/rcl/client.c index 5dedc933e..bd38efa7a 100644 --- a/rcl/src/rcl/client.c +++ b/rcl/src/rcl/client.c @@ -36,7 +36,8 @@ extern "C" struct rcl_client_impl_s { rcl_client_options_t options; - rmw_qos_profile_t actual_qos; + rmw_qos_profile_t actual_request_publisher_qos; + rmw_qos_profile_t actual_response_subscription_qos; rmw_client_t * rmw_handle; atomic_int_least64_t sequence_number; }; @@ -100,20 +101,6 @@ rcl_client_init( sizeof(rcl_client_impl_t), allocator->state); RCL_CHECK_FOR_NULL_WITH_MSG( client->impl, "allocating memory failed", ret = RCL_RET_BAD_ALLOC; goto cleanup); - - // Check the qos profile. If some fields are set as system default, - // it can happen that the DDS chooses different QoS policies for entities - // belonging to the client. The QoS of the client should match the QoS of - // all entities belonging to it. - const rmw_qos_profile_t * qos = &options->qos; - if (qos->history == RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT || - qos->reliability == RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT || - qos->durability == RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT || - qos->depth == RMW_QOS_POLICY_DEPTH_SYSTEM_DEFAULT) - { - RCL_SET_ERROR_MSG("system default qos not supported on clients"); - goto fail; - } // Fill out implementation struct. // rmw handle (create rmw client) // TODO(wjwwood): pass along the allocator to rmw when it supports it @@ -126,20 +113,33 @@ rcl_client_init( RCL_SET_ERROR_MSG(rmw_get_error_string().str); goto fail; } + // get actual qos, and store it - rmw_ret_t rmw_ret = rmw_client_get_actual_qos( + rmw_ret_t rmw_ret = rmw_client_request_publisher_get_actual_qos( client->impl->rmw_handle, - &client->impl->actual_qos); + &client->impl->actual_request_publisher_qos); - // ROS specific namespacing conventions avoidance - // is not retrieved by get_actual_qos - client->impl->actual_qos.avoid_ros_namespace_conventions = - options->qos.avoid_ros_namespace_conventions; + if (RMW_RET_OK != rmw_ret) { + RCL_SET_ERROR_MSG(rmw_get_error_string().str); + goto fail; + } + + rmw_ret = rmw_client_response_subscription_get_actual_qos( + client->impl->rmw_handle, + &client->impl->actual_response_subscription_qos); if (RMW_RET_OK != rmw_ret) { RCL_SET_ERROR_MSG(rmw_get_error_string().str); goto fail; } + + // ROS specific namespacing conventions avoidance + // is not retrieved by get_actual_qos + client->impl->actual_request_publisher_qos.avoid_ros_namespace_conventions = + options->qos.avoid_ros_namespace_conventions; + client->impl->actual_response_subscription_qos.avoid_ros_namespace_conventions = + options->qos.avoid_ros_namespace_conventions; + // options client->impl->options = *options; atomic_init(&client->impl->sequence_number, 0); @@ -311,12 +311,21 @@ rcl_client_is_valid(const rcl_client_t * client) } const rmw_qos_profile_t * -rcl_client_get_actual_qos(const rcl_client_t * client) +rcl_client_request_publisher_get_actual_qos(const rcl_client_t * client) +{ + if (!rcl_client_is_valid(client)) { + return NULL; + } + return &client->impl->actual_request_publisher_qos; +} + +const rmw_qos_profile_t * +rcl_client_response_subscription_get_actual_qos(const rcl_client_t * client) { if (!rcl_client_is_valid(client)) { return NULL; } - return &client->impl->actual_qos; + return &client->impl->actual_response_subscription_qos; } #ifdef __cplusplus } diff --git a/rcl/src/rcl/service.c b/rcl/src/rcl/service.c index f26ace6e4..42222b996 100644 --- a/rcl/src/rcl/service.c +++ b/rcl/src/rcl/service.c @@ -33,7 +33,8 @@ extern "C" struct rcl_service_impl_s { rcl_service_options_t options; - rmw_qos_profile_t actual_qos; + rmw_qos_profile_t actual_request_subscription_qos; + rmw_qos_profile_t actual_response_publisher_qos; rmw_service_t * rmw_handle; }; @@ -111,19 +112,6 @@ rcl_service_init( "Warning: Setting QoS durability to 'transient local' for service servers " "can cause them to receive requests from clients that have since terminated."); } - // Check the qos profile. If some fields are set as system default, - // it can happen that the DDS chooses different QoS policies for entities - // belonging to the service. The QoS of the service should match the QoS of - // all entities belonging to it. - const rmw_qos_profile_t * qos = &options->qos; - if (qos->history == RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT || - qos->reliability == RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT || - qos->durability == RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT || - qos->depth == RMW_QOS_POLICY_DEPTH_SYSTEM_DEFAULT) - { - RCL_SET_ERROR_MSG("system default qos not supported on clients"); - goto fail; - } // Fill out implementation struct. // rmw handle (create rmw service) // TODO(wjwwood): pass along the allocator to rmw when it supports it @@ -137,16 +125,28 @@ rcl_service_init( goto fail; } // get actual qos, and store it - rmw_ret_t rmw_ret = rmw_service_get_actual_qos( + rmw_ret_t rmw_ret = rmw_service_request_subscription_get_actual_qos( service->impl->rmw_handle, - &service->impl->actual_qos); + &service->impl->actual_request_subscription_qos); + + if (RMW_RET_OK != rmw_ret) { + RCL_SET_ERROR_MSG(rmw_get_error_string().str); + goto fail; + } + + rmw_ret = rmw_service_response_publisher_get_actual_qos( + service->impl->rmw_handle, + &service->impl->actual_response_publisher_qos); + if (RMW_RET_OK != rmw_ret) { RCL_SET_ERROR_MSG(rmw_get_error_string().str); goto fail; } // ROS specific namespacing conventions is not retrieved by get_actual_qos - service->impl->actual_qos.avoid_ros_namespace_conventions = + service->impl->actual_request_subscription_qos.avoid_ros_namespace_conventions = + options->qos.avoid_ros_namespace_conventions; + service->impl->actual_response_publisher_qos.avoid_ros_namespace_conventions = options->qos.avoid_ros_namespace_conventions; // options @@ -329,12 +329,21 @@ rcl_service_is_valid(const rcl_service_t * service) } const rmw_qos_profile_t * -rcl_service_get_actual_qos(const rcl_service_t * service) +rcl_service_request_subscription_get_actual_qos(const rcl_service_t * service) +{ + if (!rcl_service_is_valid(service)) { + return NULL; + } + return &service->impl->actual_request_subscription_qos; +} + +const rmw_qos_profile_t * +rcl_service_response_publisher_get_actual_qos(const rcl_service_t * service) { if (!rcl_service_is_valid(service)) { return NULL; } - return &service->impl->actual_qos; + return &service->impl->actual_response_publisher_qos; } #ifdef __cplusplus From 0427a139bccb15047ca5af9567761c6cb438739d Mon Sep 17 00:00:00 2001 From: Mauro Passerino Date: Thu, 13 Jan 2022 17:52:25 -0300 Subject: [PATCH 4/5] Add unit tests for client/services qos getters Signed-off-by: Mauro Passerino --- rcl/test/rcl/test_client.cpp | 18 ++++++++++++++++++ rcl/test/rcl/test_service.cpp | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/rcl/test/rcl/test_client.cpp b/rcl/test/rcl/test_client.cpp index 72bfa3ce9..f19c105ce 100644 --- a/rcl/test/rcl/test_client.cpp +++ b/rcl/test/rcl/test_client.cpp @@ -91,6 +91,20 @@ TEST_F(TestClientFixture, test_client_nominal) { EXPECT_EQ(rmw_qos_profile_services_default.depth, client_internal_options->qos.depth); EXPECT_EQ(rmw_qos_profile_services_default.durability, client_internal_options->qos.durability); + const rmw_qos_profile_t * request_publisher_qos = + rcl_client_request_publisher_get_actual_qos(&client); + EXPECT_EQ(rmw_qos_profile_services_default.reliability, request_publisher_qos->reliability); + EXPECT_EQ(rmw_qos_profile_services_default.history, request_publisher_qos->history); + EXPECT_EQ(rmw_qos_profile_services_default.depth, request_publisher_qos->depth); + EXPECT_EQ(rmw_qos_profile_services_default.durability, request_publisher_qos->durability); + + const rmw_qos_profile_t * response_subscription_qos = + rcl_client_response_subscription_get_actual_qos(&client); + EXPECT_EQ(rmw_qos_profile_services_default.reliability, response_subscription_qos->reliability); + EXPECT_EQ(rmw_qos_profile_services_default.history, response_subscription_qos->history); + EXPECT_EQ(rmw_qos_profile_services_default.depth, response_subscription_qos->depth); + EXPECT_EQ(rmw_qos_profile_services_default.durability, response_subscription_qos->durability); + // Check the return code of initialization and that the service name matches what's expected ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; EXPECT_EQ(strcmp(rcl_client_get_service_name(&client), expected_topic_name), 0); @@ -261,6 +275,8 @@ TEST_F(TestClientFixture, test_client_bad_arguments) { RCL_RET_CLIENT_INVALID, rcl_send_request( nullptr, &client_request, &sequence_number)) << rcl_get_error_string().str; EXPECT_EQ(24, sequence_number); + EXPECT_EQ(nullptr, rcl_client_request_publisher_get_actual_qos(nullptr)); + EXPECT_EQ(nullptr, rcl_client_response_subscription_get_actual_qos(nullptr)); // Not init client EXPECT_EQ(nullptr, rcl_client_get_rmw_handle(&client)); @@ -277,6 +293,8 @@ TEST_F(TestClientFixture, test_client_bad_arguments) { RCL_RET_CLIENT_INVALID, rcl_send_request( &client, &client_request, &sequence_number)) << rcl_get_error_string().str; EXPECT_EQ(24, sequence_number); + EXPECT_EQ(nullptr, rcl_client_request_publisher_get_actual_qos(&client)); + EXPECT_EQ(nullptr, rcl_client_response_subscription_get_actual_qos(&client)); } TEST_F(TestClientFixture, test_client_init_fini_maybe_fail) diff --git a/rcl/test/rcl/test_service.cpp b/rcl/test/rcl/test_service.cpp index b4f6df67c..047eb3ebb 100644 --- a/rcl/test/rcl/test_service.cpp +++ b/rcl/test/rcl/test_service.cpp @@ -93,6 +93,20 @@ TEST_F(CLASSNAME(TestServiceFixture, RMW_IMPLEMENTATION), test_service_nominal) ret = rcl_service_init(&service, this->node_ptr, ts, topic, &service_options); EXPECT_EQ(RCL_RET_ALREADY_INIT, ret) << rcl_get_error_string().str; + const rmw_qos_profile_t * request_subscription_qos = + rcl_service_request_subscription_get_actual_qos(&service); + EXPECT_EQ(rmw_qos_profile_services_default.reliability, request_subscription_qos->reliability); + EXPECT_EQ(rmw_qos_profile_services_default.history, request_subscription_qos->history); + EXPECT_EQ(rmw_qos_profile_services_default.depth, request_subscription_qos->depth); + EXPECT_EQ(rmw_qos_profile_services_default.durability, request_subscription_qos->durability); + + const rmw_qos_profile_t * response_publisher_qos = + rcl_service_response_publisher_get_actual_qos(&service); + EXPECT_EQ(rmw_qos_profile_services_default.reliability, response_publisher_qos->reliability); + EXPECT_EQ(rmw_qos_profile_services_default.history, response_publisher_qos->history); + EXPECT_EQ(rmw_qos_profile_services_default.depth, response_publisher_qos->depth); + EXPECT_EQ(rmw_qos_profile_services_default.durability, response_publisher_qos->durability); + ret = rcl_service_fini(&service, this->node_ptr); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; @@ -388,6 +402,8 @@ TEST_F(CLASSNAME(TestServiceFixture, RMW_IMPLEMENTATION), test_bad_arguments) { RCL_RET_SERVICE_INVALID, rcl_send_response(nullptr, &header.request_id, &service_response)); EXPECT_EQ( RCL_RET_SERVICE_INVALID, rcl_take_request(nullptr, &(header.request_id), &service_request)); + EXPECT_EQ(nullptr, rcl_service_request_subscription_get_actual_qos(nullptr)); + EXPECT_EQ(nullptr, rcl_service_response_publisher_get_actual_qos(nullptr)); EXPECT_EQ(nullptr, rcl_service_get_service_name(&service)); EXPECT_EQ(nullptr, rcl_service_get_options(&service)); @@ -404,6 +420,9 @@ TEST_F(CLASSNAME(TestServiceFixture, RMW_IMPLEMENTATION), test_bad_arguments) { RCL_RET_BAD_ALLOC, rcl_service_init( &service, this->node_ptr, ts, topic, &service_options_bad_alloc)) << rcl_get_error_string().str; + + EXPECT_EQ(nullptr, rcl_service_request_subscription_get_actual_qos(&service)); + EXPECT_EQ(nullptr, rcl_service_response_publisher_get_actual_qos(&service)); } /* Name failed tests From 2b61cd939b2dd929a2fd0890cf0d561a989361b5 Mon Sep 17 00:00:00 2001 From: Mauro Passerino Date: Tue, 1 Feb 2022 10:02:59 -0300 Subject: [PATCH 5/5] Check avoid_ros_namespace_conventions in unit test Signed-off-by: Mauro Passerino --- rcl/test/rcl/test_client.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rcl/test/rcl/test_client.cpp b/rcl/test/rcl/test_client.cpp index f19c105ce..9c3330b54 100644 --- a/rcl/test/rcl/test_client.cpp +++ b/rcl/test/rcl/test_client.cpp @@ -97,6 +97,9 @@ TEST_F(TestClientFixture, test_client_nominal) { EXPECT_EQ(rmw_qos_profile_services_default.history, request_publisher_qos->history); EXPECT_EQ(rmw_qos_profile_services_default.depth, request_publisher_qos->depth); EXPECT_EQ(rmw_qos_profile_services_default.durability, request_publisher_qos->durability); + EXPECT_EQ( + rmw_qos_profile_services_default.avoid_ros_namespace_conventions, + request_publisher_qos->avoid_ros_namespace_conventions); const rmw_qos_profile_t * response_subscription_qos = rcl_client_response_subscription_get_actual_qos(&client); @@ -104,6 +107,9 @@ TEST_F(TestClientFixture, test_client_nominal) { EXPECT_EQ(rmw_qos_profile_services_default.history, response_subscription_qos->history); EXPECT_EQ(rmw_qos_profile_services_default.depth, response_subscription_qos->depth); EXPECT_EQ(rmw_qos_profile_services_default.durability, response_subscription_qos->durability); + EXPECT_EQ( + rmw_qos_profile_services_default.avoid_ros_namespace_conventions, + response_subscription_qos->avoid_ros_namespace_conventions); // Check the return code of initialization and that the service name matches what's expected ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;