Add fault injection macros to rcl functions (#727)
* Add fault injection macros to rcl functions Signed-off-by: Stephen Brawner <brawner@gmail.com> * PR fixup Signed-off-by: Stephen Brawner <brawner@gmail.com>
This commit is contained in:
parent
13ded97050
commit
97e066ff64
10 changed files with 120 additions and 0 deletions
|
@ -83,6 +83,10 @@ ament_target_dependencies(${PROJECT_NAME}
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE "RCL_BUILDING_DLL")
|
target_compile_definitions(${PROJECT_NAME} PRIVATE "RCL_BUILDING_DLL")
|
||||||
rcl_set_symbol_visibility_hidden(${PROJECT_NAME} LANGUAGE "C")
|
rcl_set_symbol_visibility_hidden(${PROJECT_NAME} LANGUAGE "C")
|
||||||
|
|
||||||
|
if(BUILD_TESTING AND NOT RCUTILS_DISABLE_FAULT_INJECTION)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PUBLIC RCUTILS_ENABLE_FAULT_INJECTION)
|
||||||
|
endif()
|
||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}
|
TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}
|
||||||
ARCHIVE DESTINATION lib
|
ARCHIVE DESTINATION lib
|
||||||
|
|
|
@ -26,6 +26,7 @@ extern "C"
|
||||||
#include "rcl/expand_topic_name.h"
|
#include "rcl/expand_topic_name.h"
|
||||||
#include "rcl/remap.h"
|
#include "rcl/remap.h"
|
||||||
#include "rcutils/logging_macros.h"
|
#include "rcutils/logging_macros.h"
|
||||||
|
#include "rcutils/macros.h"
|
||||||
#include "rcutils/stdatomic_helper.h"
|
#include "rcutils/stdatomic_helper.h"
|
||||||
#include "rmw/error_handling.h"
|
#include "rmw/error_handling.h"
|
||||||
#include "rmw/rmw.h"
|
#include "rmw/rmw.h"
|
||||||
|
@ -206,6 +207,10 @@ cleanup:
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_client_fini(rcl_client_t * client, rcl_node_t * node)
|
rcl_client_fini(rcl_client_t * client, rcl_node_t * node)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_NODE_INVALID);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
|
||||||
|
|
||||||
RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Finalizing client");
|
RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Finalizing client");
|
||||||
rcl_ret_t result = RCL_RET_OK;
|
rcl_ret_t result = RCL_RET_OK;
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(client, RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ARGUMENT_FOR_NULL(client, RCL_RET_INVALID_ARGUMENT);
|
||||||
|
|
|
@ -21,6 +21,7 @@ extern "C"
|
||||||
|
|
||||||
#include "rcl/error_handling.h"
|
#include "rcl/error_handling.h"
|
||||||
#include "rcutils/allocator.h"
|
#include "rcutils/allocator.h"
|
||||||
|
#include "rcutils/macros.h"
|
||||||
#include "rcutils/types.h"
|
#include "rcutils/types.h"
|
||||||
#include "rmw/error_handling.h"
|
#include "rmw/error_handling.h"
|
||||||
#include "rmw/get_node_info_and_types.h"
|
#include "rmw/get_node_info_and_types.h"
|
||||||
|
@ -289,6 +290,8 @@ rcl_names_and_types_init(
|
||||||
size_t size,
|
size_t size,
|
||||||
rcl_allocator_t * allocator)
|
rcl_allocator_t * allocator)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(names_and_types, RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ARGUMENT_FOR_NULL(names_and_types, RCL_RET_INVALID_ARGUMENT);
|
||||||
RCL_CHECK_ALLOCATOR(allocator, return RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ALLOCATOR(allocator, return RCL_RET_INVALID_ARGUMENT);
|
||||||
rmw_ret_t rmw_ret = rmw_names_and_types_init(names_and_types, size, allocator);
|
rmw_ret_t rmw_ret = rmw_names_and_types_init(names_and_types, size, allocator);
|
||||||
|
@ -298,6 +301,8 @@ rcl_names_and_types_init(
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_names_and_types_fini(rcl_names_and_types_t * topic_names_and_types)
|
rcl_names_and_types_fini(rcl_names_and_types_t * topic_names_and_types)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(topic_names_and_types, RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ARGUMENT_FOR_NULL(topic_names_and_types, RCL_RET_INVALID_ARGUMENT);
|
||||||
rmw_ret_t rmw_ret = rmw_names_and_types_fini(topic_names_and_types);
|
rmw_ret_t rmw_ret = rmw_names_and_types_fini(topic_names_and_types);
|
||||||
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
|
return rcl_convert_rmw_ret_to_rcl_ret(rmw_ret);
|
||||||
|
@ -514,6 +519,9 @@ rcl_service_server_is_available(
|
||||||
const rcl_client_t * client,
|
const rcl_client_t * client,
|
||||||
bool * is_available)
|
bool * is_available)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_NODE_INVALID);
|
||||||
|
|
||||||
if (!rcl_node_is_valid(node)) {
|
if (!rcl_node_is_valid(node)) {
|
||||||
return RCL_RET_NODE_INVALID; // error already set
|
return RCL_RET_NODE_INVALID; // error already set
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ extern "C"
|
||||||
#include "rcl/expand_topic_name.h"
|
#include "rcl/expand_topic_name.h"
|
||||||
#include "rcl/remap.h"
|
#include "rcl/remap.h"
|
||||||
#include "rcutils/logging_macros.h"
|
#include "rcutils/logging_macros.h"
|
||||||
|
#include "rcutils/macros.h"
|
||||||
#include "rmw/error_handling.h"
|
#include "rmw/error_handling.h"
|
||||||
#include "rmw/validate_full_topic_name.h"
|
#include "rmw/validate_full_topic_name.h"
|
||||||
#include "tracetools/tracetools.h"
|
#include "tracetools/tracetools.h"
|
||||||
|
@ -50,6 +51,13 @@ rcl_publisher_init(
|
||||||
const rcl_publisher_options_t * options
|
const rcl_publisher_options_t * options
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ALREADY_INIT);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_NODE_INVALID);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_BAD_ALLOC);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_TOPIC_NAME_INVALID);
|
||||||
|
|
||||||
rcl_ret_t fail_ret = RCL_RET_ERROR;
|
rcl_ret_t fail_ret = RCL_RET_ERROR;
|
||||||
|
|
||||||
// Check options and allocator first, so allocator can be used with errors.
|
// Check options and allocator first, so allocator can be used with errors.
|
||||||
|
@ -225,6 +233,11 @@ cleanup:
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_publisher_fini(rcl_publisher_t * publisher, rcl_node_t * node)
|
rcl_publisher_fini(rcl_publisher_t * publisher, rcl_node_t * node)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_PUBLISHER_INVALID);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_NODE_INVALID);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
|
||||||
|
|
||||||
rcl_ret_t result = RCL_RET_OK;
|
rcl_ret_t result = RCL_RET_OK;
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(publisher, RCL_RET_PUBLISHER_INVALID);
|
RCL_CHECK_ARGUMENT_FOR_NULL(publisher, RCL_RET_PUBLISHER_INVALID);
|
||||||
if (!rcl_node_is_valid_except_context(node)) {
|
if (!rcl_node_is_valid_except_context(node)) {
|
||||||
|
@ -295,6 +308,9 @@ rcl_publish(
|
||||||
const void * ros_message,
|
const void * ros_message,
|
||||||
rmw_publisher_allocation_t * allocation)
|
rmw_publisher_allocation_t * allocation)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_PUBLISHER_INVALID);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
|
||||||
|
|
||||||
if (!rcl_publisher_is_valid(publisher)) {
|
if (!rcl_publisher_is_valid(publisher)) {
|
||||||
return RCL_RET_PUBLISHER_INVALID; // error already set
|
return RCL_RET_PUBLISHER_INVALID; // error already set
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ extern "C"
|
||||||
#include "rcl/expand_topic_name.h"
|
#include "rcl/expand_topic_name.h"
|
||||||
#include "rcl/remap.h"
|
#include "rcl/remap.h"
|
||||||
#include "rcutils/logging_macros.h"
|
#include "rcutils/logging_macros.h"
|
||||||
|
#include "rcutils/macros.h"
|
||||||
#include "rmw/error_handling.h"
|
#include "rmw/error_handling.h"
|
||||||
#include "rmw/rmw.h"
|
#include "rmw/rmw.h"
|
||||||
#include "rmw/validate_full_topic_name.h"
|
#include "rmw/validate_full_topic_name.h"
|
||||||
|
@ -52,6 +53,13 @@ rcl_service_init(
|
||||||
const char * service_name,
|
const char * service_name,
|
||||||
const rcl_service_options_t * options)
|
const rcl_service_options_t * options)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ALREADY_INIT);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_NODE_INVALID);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_BAD_ALLOC);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_SERVICE_NAME_INVALID);
|
||||||
|
|
||||||
rcl_ret_t fail_ret = RCL_RET_ERROR;
|
rcl_ret_t fail_ret = RCL_RET_ERROR;
|
||||||
|
|
||||||
// Check options and allocator first, so the allocator can be used in errors.
|
// Check options and allocator first, so the allocator can be used in errors.
|
||||||
|
@ -209,6 +217,11 @@ cleanup:
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_service_fini(rcl_service_t * service, rcl_node_t * node)
|
rcl_service_fini(rcl_service_t * service, rcl_node_t * node)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_SERVICE_INVALID);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_NODE_INVALID);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
|
||||||
|
|
||||||
RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Finalizing service");
|
RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Finalizing service");
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(service, RCL_RET_SERVICE_INVALID);
|
RCL_CHECK_ARGUMENT_FOR_NULL(service, RCL_RET_SERVICE_INVALID);
|
||||||
if (!rcl_node_is_valid_except_context(node)) {
|
if (!rcl_node_is_valid_except_context(node)) {
|
||||||
|
|
|
@ -220,6 +220,11 @@ cleanup:
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_subscription_fini(rcl_subscription_t * subscription, rcl_node_t * node)
|
rcl_subscription_fini(rcl_subscription_t * subscription, rcl_node_t * node)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_SUBSCRIPTION_INVALID);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_NODE_INVALID);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
|
||||||
|
|
||||||
RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Finalizing subscription");
|
RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Finalizing subscription");
|
||||||
rcl_ret_t result = RCL_RET_OK;
|
rcl_ret_t result = RCL_RET_OK;
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(subscription, RCL_RET_SUBSCRIPTION_INVALID);
|
RCL_CHECK_ARGUMENT_FOR_NULL(subscription, RCL_RET_SUBSCRIPTION_INVALID);
|
||||||
|
@ -466,6 +471,9 @@ rcl_subscription_get_publisher_count(
|
||||||
const rcl_subscription_t * subscription,
|
const rcl_subscription_t * subscription,
|
||||||
size_t * publisher_count)
|
size_t * publisher_count)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_SUBSCRIPTION_INVALID);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
|
||||||
if (!rcl_subscription_is_valid(subscription)) {
|
if (!rcl_subscription_is_valid(subscription)) {
|
||||||
return RCL_RET_SUBSCRIPTION_INVALID;
|
return RCL_RET_SUBSCRIPTION_INVALID;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "./common.h"
|
#include "./common.h"
|
||||||
#include "rcl/allocator.h"
|
#include "rcl/allocator.h"
|
||||||
#include "rcl/error_handling.h"
|
#include "rcl/error_handling.h"
|
||||||
|
#include "rcutils/macros.h"
|
||||||
#include "rcutils/stdatomic_helper.h"
|
#include "rcutils/stdatomic_helper.h"
|
||||||
#include "rcutils/time.h"
|
#include "rcutils/time.h"
|
||||||
|
|
||||||
|
@ -251,6 +252,9 @@ rcl_difference_times(
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_clock_get_now(rcl_clock_t * clock, rcl_time_point_value_t * time_point_value)
|
rcl_clock_get_now(rcl_clock_t * clock, rcl_time_point_value_t * time_point_value)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_ERROR);
|
||||||
|
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(clock, RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ARGUMENT_FOR_NULL(clock, RCL_RET_INVALID_ARGUMENT);
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(time_point_value, RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ARGUMENT_FOR_NULL(time_point_value, RCL_RET_INVALID_ARGUMENT);
|
||||||
if (clock->type && clock->get_now) {
|
if (clock->type && clock->get_now) {
|
||||||
|
|
|
@ -345,6 +345,8 @@ rcl_timer_get_period(const rcl_timer_t * timer, int64_t * period)
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_timer_exchange_period(const rcl_timer_t * timer, int64_t new_period, int64_t * old_period)
|
rcl_timer_exchange_period(const rcl_timer_t * timer, int64_t new_period, int64_t * old_period)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(timer, RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ARGUMENT_FOR_NULL(timer, RCL_RET_INVALID_ARGUMENT);
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(old_period, RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ARGUMENT_FOR_NULL(old_period, RCL_RET_INVALID_ARGUMENT);
|
||||||
*old_period = rcutils_atomic_exchange_uint64_t(&timer->impl->period, new_period);
|
*old_period = rcutils_atomic_exchange_uint64_t(&timer->impl->period, new_period);
|
||||||
|
@ -375,6 +377,9 @@ rcl_timer_exchange_callback(rcl_timer_t * timer, const rcl_timer_callback_t new_
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_timer_cancel(rcl_timer_t * timer)
|
rcl_timer_cancel(rcl_timer_t * timer)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_TIMER_INVALID);
|
||||||
|
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(timer, RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ARGUMENT_FOR_NULL(timer, RCL_RET_INVALID_ARGUMENT);
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(timer->impl, "timer is invalid", return RCL_RET_TIMER_INVALID);
|
RCL_CHECK_FOR_NULL_WITH_MSG(timer->impl, "timer is invalid", return RCL_RET_TIMER_INVALID);
|
||||||
rcutils_atomic_store(&timer->impl->canceled, true);
|
rcutils_atomic_store(&timer->impl->canceled, true);
|
||||||
|
@ -394,6 +399,8 @@ rcl_timer_is_canceled(const rcl_timer_t * timer, bool * is_canceled)
|
||||||
rcl_ret_t
|
rcl_ret_t
|
||||||
rcl_timer_reset(rcl_timer_t * timer)
|
rcl_timer_reset(rcl_timer_t * timer)
|
||||||
{
|
{
|
||||||
|
RCUTILS_CAN_RETURN_WITH_ERROR_OF(RCL_RET_INVALID_ARGUMENT);
|
||||||
|
|
||||||
RCL_CHECK_ARGUMENT_FOR_NULL(timer, RCL_RET_INVALID_ARGUMENT);
|
RCL_CHECK_ARGUMENT_FOR_NULL(timer, RCL_RET_INVALID_ARGUMENT);
|
||||||
RCL_CHECK_FOR_NULL_WITH_MSG(timer->impl, "timer is invalid", return RCL_RET_TIMER_INVALID);
|
RCL_CHECK_FOR_NULL_WITH_MSG(timer->impl, "timer is invalid", return RCL_RET_TIMER_INVALID);
|
||||||
rcl_time_point_value_t now;
|
rcl_time_point_value_t now;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "rcl/client.h"
|
#include "rcl/client.h"
|
||||||
|
|
||||||
#include "rcl/rcl.h"
|
#include "rcl/rcl.h"
|
||||||
|
#include "rcutils/testing/fault_injection.h"
|
||||||
|
|
||||||
#include "test_msgs/srv/basic_types.h"
|
#include "test_msgs/srv/basic_types.h"
|
||||||
|
|
||||||
|
@ -277,3 +278,29 @@ TEST_F(TestClientFixture, test_client_bad_arguments) {
|
||||||
&client, &client_request, &sequence_number)) << rcl_get_error_string().str;
|
&client, &client_request, &sequence_number)) << rcl_get_error_string().str;
|
||||||
EXPECT_EQ(24, sequence_number);
|
EXPECT_EQ(24, sequence_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(TestClientFixture, test_client_init_fini_maybe_fail)
|
||||||
|
{
|
||||||
|
const rosidl_service_type_support_t * ts = ROSIDL_GET_SRV_TYPE_SUPPORT(
|
||||||
|
test_msgs, srv, BasicTypes);
|
||||||
|
constexpr char topic_name[] = "chatter";
|
||||||
|
rcl_client_options_t default_client_options = rcl_client_get_default_options();
|
||||||
|
|
||||||
|
RCUTILS_FAULT_INJECTION_TEST(
|
||||||
|
{
|
||||||
|
rcl_client_t client = rcl_get_zero_initialized_client();
|
||||||
|
rcl_ret_t ret = rcl_client_init(
|
||||||
|
&client, this->node_ptr, ts, topic_name, &default_client_options);
|
||||||
|
if (RCL_RET_OK == ret) {
|
||||||
|
EXPECT_TRUE(rcl_client_is_valid(&client));
|
||||||
|
ret = rcl_client_fini(&client, this->node_ptr);
|
||||||
|
if (RCL_RET_OK != ret) {
|
||||||
|
// If fault injection caused fini to fail, we should try it again.
|
||||||
|
EXPECT_EQ(RCL_RET_OK, rcl_client_fini(&client, this->node_ptr));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
EXPECT_TRUE(rcl_error_is_set());
|
||||||
|
rcl_reset_error();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "rmw/rmw.h"
|
#include "rmw/rmw.h"
|
||||||
#include "rmw/validate_full_topic_name.h"
|
#include "rmw/validate_full_topic_name.h"
|
||||||
|
|
||||||
|
#include "rcutils/testing/fault_injection.h"
|
||||||
#include "test_msgs/msg/basic_types.h"
|
#include "test_msgs/msg/basic_types.h"
|
||||||
#include "test_msgs/msg/strings.h"
|
#include "test_msgs/msg/strings.h"
|
||||||
#include "rosidl_runtime_c/string_functions.h"
|
#include "rosidl_runtime_c/string_functions.h"
|
||||||
|
@ -1065,3 +1066,30 @@ TEST_F(CLASSNAME(TestSubscriptionFixtureInit, RMW_IMPLEMENTATION), test_subscrip
|
||||||
EXPECT_EQ(NULL, rcl_subscription_get_options(&subscription_zero_init));
|
EXPECT_EQ(NULL, rcl_subscription_get_options(&subscription_zero_init));
|
||||||
rcl_reset_error();
|
rcl_reset_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CLASSNAME(TestSubscriptionFixture, RMW_IMPLEMENTATION), test_init_fini_maybe_fail)
|
||||||
|
{
|
||||||
|
const rosidl_message_type_support_t * ts =
|
||||||
|
ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes);
|
||||||
|
constexpr char topic[] = "chatter";
|
||||||
|
rcl_subscription_options_t subscription_options = rcl_subscription_get_default_options();
|
||||||
|
rcl_subscription_t subscription = rcl_get_zero_initialized_subscription();
|
||||||
|
|
||||||
|
RCUTILS_FAULT_INJECTION_TEST(
|
||||||
|
{
|
||||||
|
rcl_ret_t ret = rcl_subscription_init(
|
||||||
|
&subscription, this->node_ptr, ts, topic, &subscription_options);
|
||||||
|
|
||||||
|
if (RCL_RET_OK == ret) {
|
||||||
|
EXPECT_TRUE(rcl_subscription_is_valid(&subscription));
|
||||||
|
ret = rcl_subscription_fini(&subscription, this->node_ptr);
|
||||||
|
if (RCL_RET_OK != ret) {
|
||||||
|
// If fault injection caused fini to fail, we should try it again.
|
||||||
|
EXPECT_EQ(RCL_RET_OK, rcl_subscription_fini(&subscription, this->node_ptr));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
EXPECT_TRUE(rcl_error_is_set());
|
||||||
|
rcl_reset_error();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue