diff --git a/test_rmw_implementation/CMakeLists.txt b/test_rmw_implementation/CMakeLists.txt index c24e6405e..2f6a1889b 100644 --- a/test_rmw_implementation/CMakeLists.txt +++ b/test_rmw_implementation/CMakeLists.txt @@ -72,7 +72,7 @@ if(BUILD_TESTING) ament_add_gtest(test_subscription${target_suffix} test/test_subscription.cpp ENV ${rmw_implementation_env_var} - TIMEOUT 80 + TIMEOUT 120 ) target_compile_definitions(test_subscription${target_suffix} PUBLIC "RMW_IMPLEMENTATION=${rmw_implementation}") diff --git a/test_rmw_implementation/test/test_client.cpp b/test_rmw_implementation/test/test_client.cpp index 185e6d7fb..191886e3e 100644 --- a/test_rmw_implementation/test/test_client.cpp +++ b/test_rmw_implementation/test/test_client.cpp @@ -150,6 +150,44 @@ TEST_F(CLASSNAME(TestClient, RMW_IMPLEMENTATION), create_with_bad_arguments) { EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; } +TEST_F(CLASSNAME(TestClient, RMW_IMPLEMENTATION), create_with_internal_errors) { + constexpr char service_name[] = "/test"; + const rosidl_service_type_support_t * ts = + ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes); + RCUTILS_FAULT_INJECTION_TEST( + { + rmw_client_t * client = + rmw_create_client(node, ts, service_name, &rmw_qos_profile_default); + if (client) { + RCUTILS_NO_FAULT_INJECTION( + { + rmw_ret_t ret = rmw_destroy_client(node, client); + EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + }); + } else { + rmw_reset_error(); + } + }); +} + +TEST_F(CLASSNAME(TestClient, RMW_IMPLEMENTATION), destroy_with_internal_errors) { + constexpr char service_name[] = "/test"; + const rosidl_service_type_support_t * ts = + ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes); + RCUTILS_FAULT_INJECTION_TEST( + { + rmw_client_t * client = nullptr; + RCUTILS_NO_FAULT_INJECTION( + { + client = rmw_create_client(node, ts, service_name, &rmw_qos_profile_default); + ASSERT_NE(nullptr, client) << rmw_get_error_string().str; + }); + if (RMW_RET_OK != rmw_destroy_client(node, client)) { + rmw_reset_error(); + } + }); +} + class CLASSNAME (TestClientUse, RMW_IMPLEMENTATION) : public CLASSNAME(TestClient, RMW_IMPLEMENTATION) { @@ -364,26 +402,3 @@ TEST_F(CLASSNAME(TestClientUse, RMW_IMPLEMENTATION), service_server_is_available ret = rmw_destroy_service(node, service); EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; } - -TEST_F(CLASSNAME(TestClient, RMW_IMPLEMENTATION), create_client_with_internal_errors) -{ - RCUTILS_FAULT_INJECTION_TEST( - { - const rosidl_service_type_support_t * ts = ROSIDL_GET_SRV_TYPE_SUPPORT( - test_msgs, srv, BasicTypes); - rmw_client_t * client_fault = rmw_create_client( - node, ts, "/service_name_test", - &rmw_qos_profile_default); - - int64_t count = rcutils_fault_injection_get_count(); - rcutils_fault_injection_set_count(RCUTILS_FAULT_INJECTION_NEVER_FAIL); - - if (client_fault != nullptr) { - rmw_ret_t ret = rmw_destroy_client(node, client_fault); - EXPECT_EQ(ret, RMW_RET_OK) << rcutils_get_error_string().str; - } else { - rmw_reset_error(); - } - rcutils_fault_injection_set_count(count); - }); -} diff --git a/test_rmw_implementation/test/test_create_destroy_node.cpp b/test_rmw_implementation/test/test_create_destroy_node.cpp index aaf047ee2..62e84c06d 100644 --- a/test_rmw_implementation/test/test_create_destroy_node.cpp +++ b/test_rmw_implementation/test/test_create_destroy_node.cpp @@ -14,12 +14,16 @@ #include +#include "osrf_testing_tools_cpp/memory_tools/memory_tools.hpp" + #include "rcutils/allocator.h" #include "rcutils/strdup.h" #include "rmw/error_handling.h" #include "rmw/rmw.h" +#include "./testing_macros.hpp" + #ifdef RMW_IMPLEMENTATION # define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX @@ -173,3 +177,42 @@ TEST_F( ASSERT_NE(nullptr, node) << rmw_get_error_string().str; EXPECT_EQ(RMW_RET_OK, rmw_destroy_node(node)) << rmw_get_error_string().str; } + +TEST_F( + CLASSNAME(TestNodeConstructionDestruction, RMW_IMPLEMENTATION), + create_with_internal_errors) { + RCUTILS_FAULT_INJECTION_TEST( + { + constexpr char node_name[] = "my_node"; + constexpr char node_namespace[] = "/my_ns"; + rmw_node_t * node = rmw_create_node(&context, node_name, node_namespace); + if (node) { + RCUTILS_NO_FAULT_INJECTION( + { + rmw_ret_t ret = rmw_destroy_node(node); + EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + }); + } else { + rmw_reset_error(); + } + }); +} + +TEST_F( + CLASSNAME(TestNodeConstructionDestruction, RMW_IMPLEMENTATION), + destroy_with_internal_errors) { + RCUTILS_FAULT_INJECTION_TEST( + { + constexpr char node_name[] = "my_node"; + constexpr char node_namespace[] = "/my_ns"; + rmw_node_t * node = nullptr; + RCUTILS_NO_FAULT_INJECTION( + { + node = rmw_create_node(&context, node_name, node_namespace); + ASSERT_NE(nullptr, node) << rmw_get_error_string().str; + }); + if (RMW_RET_OK != rmw_destroy_node(node)) { + rmw_reset_error(); + } + }); +} diff --git a/test_rmw_implementation/test/test_init_shutdown.cpp b/test_rmw_implementation/test/test_init_shutdown.cpp index e7bb0d2c7..013944005 100644 --- a/test_rmw_implementation/test/test_init_shutdown.cpp +++ b/test_rmw_implementation/test/test_init_shutdown.cpp @@ -14,12 +14,18 @@ #include +#include "osrf_testing_tools_cpp/memory_tools/memory_tools.hpp" + #include "rcutils/allocator.h" #include "rcutils/error_handling.h" +#include "rcutils/macros.h" #include "rcutils/strdup.h" +#include "rmw/error_handling.h" #include "rmw/rmw.h" +#include "./testing_macros.hpp" + #ifdef RMW_IMPLEMENTATION # define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX # define CLASSNAME(NAME, SUFFIX) CLASSNAME_(NAME, SUFFIX) @@ -170,3 +176,69 @@ TEST_F(CLASSNAME(TestInitShutdown, RMW_IMPLEMENTATION), init_shutdown) { ret = rmw_context_fini(&context); EXPECT_EQ(RMW_RET_OK, ret) << rcutils_get_error_string().str; } + +TEST_F(CLASSNAME(TestInitShutdown, RMW_IMPLEMENTATION), init_with_internal_errors) { + RCUTILS_FAULT_INJECTION_TEST( + { + rmw_context_t context = rmw_get_zero_initialized_context(); + rmw_ret_t ret = rmw_init(&options, &context); + + RCUTILS_NO_FAULT_INJECTION( + { + if (RMW_RET_OK == ret) { + ret = rmw_shutdown(&context); + EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + ret = rmw_context_fini(&context); + EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + } else { + rmw_reset_error(); + } + }); + }); +} + +TEST_F(CLASSNAME(TestInitShutdown, RMW_IMPLEMENTATION), shutdown_with_internal_errors) { + RCUTILS_FAULT_INJECTION_TEST( + { + rmw_ret_t ret = RMW_RET_OK; + rmw_context_t context = rmw_get_zero_initialized_context(); + + RCUTILS_NO_FAULT_INJECTION( + { + ret = rmw_init(&options, &context); + ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + }); + + ret = rmw_shutdown(&context); + + RCUTILS_NO_FAULT_INJECTION( + { + if (RMW_RET_OK != ret) { + rmw_reset_error(); + + ret = rmw_shutdown(&context); + EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + } + ret = rmw_context_fini(&context); + EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + }); + }); +} + +TEST_F(CLASSNAME(TestInitShutdown, RMW_IMPLEMENTATION), context_fini_with_internal_errors) { + RCUTILS_FAULT_INJECTION_TEST( + { + rmw_context_t context = rmw_get_zero_initialized_context(); + RCUTILS_NO_FAULT_INJECTION( + { + rmw_ret_t ret = rmw_init(&options, &context); + ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + ret = rmw_shutdown(&context); + EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + }); + + if (RMW_RET_OK != rmw_context_fini(&context)) { + rmw_reset_error(); + } + }); +} diff --git a/test_rmw_implementation/test/test_publisher.cpp b/test_rmw_implementation/test/test_publisher.cpp index 62dfbde5b..fbd73c6cf 100644 --- a/test_rmw_implementation/test/test_publisher.cpp +++ b/test_rmw_implementation/test/test_publisher.cpp @@ -15,8 +15,10 @@ #include #include "osrf_testing_tools_cpp/memory_tools/gtest_quickstart.hpp" +#include "osrf_testing_tools_cpp/scope_exit.hpp" #include "rcutils/allocator.h" +#include "rcutils/macros.h" #include "rcutils/strdup.h" #include "rmw/rmw.h" @@ -82,6 +84,28 @@ TEST_F(CLASSNAME(TestPublisher, RMW_IMPLEMENTATION), create_and_destroy) { EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; } +TEST_F(CLASSNAME(TestPublisher, RMW_IMPLEMENTATION), create_with_internal_errors) { + constexpr char topic_name[] = "/test"; + const rosidl_message_type_support_t * ts = + ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); + + RCUTILS_FAULT_INJECTION_TEST( + { + rmw_publisher_t * pub = nullptr; + rmw_publisher_options_t options = rmw_get_default_publisher_options(); + pub = rmw_create_publisher(node, ts, topic_name, &rmw_qos_profile_default, &options); + if (pub) { + RCUTILS_NO_FAULT_INJECTION( + { + rmw_ret_t ret = rmw_destroy_publisher(node, pub); + EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + }); + } else { + rmw_reset_error(); + } + }); +} + TEST_F(CLASSNAME(TestPublisher, RMW_IMPLEMENTATION), create_and_destroy_native) { rmw_publisher_options_t options = rmw_get_default_publisher_options(); constexpr char topic_name[] = "test"; @@ -185,6 +209,26 @@ TEST_F(CLASSNAME(TestPublisher, RMW_IMPLEMENTATION), destroy_with_bad_arguments) rmw_reset_error(); } +TEST_F(CLASSNAME(TestPublisher, RMW_IMPLEMENTATION), destroy_with_internal_errors) { + constexpr char topic_name[] = "/test"; + const rosidl_message_type_support_t * ts = + ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); + + RCUTILS_FAULT_INJECTION_TEST( + { + rmw_publisher_t * pub = nullptr; + RCUTILS_NO_FAULT_INJECTION( + { + rmw_publisher_options_t options = rmw_get_default_publisher_options(); + pub = rmw_create_publisher(node, ts, topic_name, &rmw_qos_profile_default, &options); + ASSERT_NE(nullptr, pub) << rmw_get_error_string().str; + }); + if (RMW_RET_OK != rmw_destroy_publisher(node, pub)) { + rmw_reset_error(); + } + }); +} + TEST_F(CLASSNAME(TestPublisher, RMW_IMPLEMENTATION), get_actual_qos_from_system_defaults) { rmw_publisher_options_t options = rmw_get_default_publisher_options(); constexpr char topic_name[] = "/test"; @@ -405,6 +449,20 @@ TEST_F( test_msgs__msg__BasicTypes__fini(&input_message); } +TEST_F(CLASSNAME(TestPublisherUse, RMW_IMPLEMENTATION), publish_with_internal_errors) { + test_msgs__msg__BasicTypes message{}; + ASSERT_TRUE(test_msgs__msg__BasicTypes__init(&message)); + rmw_publisher_allocation_t * null_allocation{nullptr}; // still a valid allocation + + RCUTILS_FAULT_INJECTION_TEST( + { + rmw_ret_t ret = rmw_publish(pub, &message, null_allocation); + if (RMW_RET_OK != ret) { + rmw_reset_error(); + } + }); +} + TEST_F( CLASSNAME(TestPublisherUse, RMW_IMPLEMENTATION), publish_serialized_message_with_bad_arguments) { @@ -434,6 +492,33 @@ TEST_F( RMW_RET_OK, rmw_serialized_message_fini(&serialized_message)) << rmw_get_error_string().str; } +TEST_F(CLASSNAME(TestPublisherUse, RMW_IMPLEMENTATION), publish_serialized_with_internal_errors) { + test_msgs__msg__BasicTypes message{}; + ASSERT_TRUE(test_msgs__msg__BasicTypes__init(&message)); + rcutils_allocator_t default_allocator = rcutils_get_default_allocator(); + rmw_serialized_message_t serialized_message = rmw_get_zero_initialized_serialized_message(); + rmw_ret_t ret = rmw_serialized_message_init(&serialized_message, 0lu, &default_allocator); + ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( + { + rmw_ret_t ret = rmw_serialized_message_fini(&serialized_message); + EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + }); + ret = rmw_serialize(&message, ts, &serialized_message); + ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + rmw_publisher_allocation_t * null_allocation{nullptr}; // still a valid allocation + + RCUTILS_FAULT_INJECTION_TEST( + { + ret = rmw_publish_serialized_message( + pub, &serialized_message, null_allocation); + if (RMW_RET_OK != ret) { + rmw_reset_error(); + } + }); +} + + class CLASSNAME (TestPublisherUseLoan, RMW_IMPLEMENTATION) : public CLASSNAME(TestPublisherUse, RMW_IMPLEMENTATION) { diff --git a/test_rmw_implementation/test/test_service.cpp b/test_rmw_implementation/test/test_service.cpp index ad3cfd938..75da38b7e 100644 --- a/test_rmw_implementation/test/test_service.cpp +++ b/test_rmw_implementation/test/test_service.cpp @@ -151,6 +151,44 @@ TEST_F(CLASSNAME(TestService, RMW_IMPLEMENTATION), create_with_bad_arguments) { EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; } + +TEST_F(CLASSNAME(TestService, RMW_IMPLEMENTATION), create_with_internal_errors) { + constexpr char service_name[] = "/test"; + const rosidl_service_type_support_t * ts = + ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes); + RCUTILS_FAULT_INJECTION_TEST( + { + rmw_service_t * srv = rmw_create_service(node, ts, service_name, &rmw_qos_profile_default); + if (srv) { + RCUTILS_NO_FAULT_INJECTION( + { + rmw_ret_t ret = rmw_destroy_service(node, srv); + EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + }); + } else { + rmw_reset_error(); + } + }); +} + +TEST_F(CLASSNAME(TestService, RMW_IMPLEMENTATION), destroy_with_internal_errors) { + constexpr char service_name[] = "/test"; + const rosidl_service_type_support_t * ts = + ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes); + RCUTILS_FAULT_INJECTION_TEST( + { + rmw_service_t * srv = nullptr; + RCUTILS_NO_FAULT_INJECTION( + { + srv = rmw_create_service(node, ts, service_name, &rmw_qos_profile_default); + ASSERT_NE(nullptr, srv) << rmw_get_error_string().str; + }); + if (RMW_RET_OK != rmw_destroy_service(node, srv)) { + rmw_reset_error(); + } + }); +} + class CLASSNAME (TestServiceUse, RMW_IMPLEMENTATION) : public CLASSNAME(TestService, RMW_IMPLEMENTATION) { diff --git a/test_rmw_implementation/test/test_subscription.cpp b/test_rmw_implementation/test/test_subscription.cpp index 9d72d62cb..8316517ce 100644 --- a/test_rmw_implementation/test/test_subscription.cpp +++ b/test_rmw_implementation/test/test_subscription.cpp @@ -157,6 +157,28 @@ TEST_F(CLASSNAME(TestSubscription, RMW_IMPLEMENTATION), create_with_bad_argument EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; } +TEST_F(CLASSNAME(TestSubscription, RMW_IMPLEMENTATION), create_with_internal_errors) { + constexpr char topic_name[] = "/test"; + const rosidl_message_type_support_t * ts = + ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); + + RCUTILS_FAULT_INJECTION_TEST( + { + rmw_subscription_t * sub = nullptr; + rmw_subscription_options_t options = rmw_get_default_subscription_options(); + sub = rmw_create_subscription(node, ts, topic_name, &rmw_qos_profile_default, &options); + if (sub) { + RCUTILS_NO_FAULT_INJECTION( + { + rmw_ret_t ret = rmw_destroy_subscription(node, sub); + EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str; + }); + } else { + rmw_reset_error(); + } + }); +} + TEST_F(CLASSNAME(TestSubscription, RMW_IMPLEMENTATION), destroy_with_bad_arguments) { rmw_subscription_options_t options = rmw_get_default_subscription_options(); constexpr char topic_name[] = "/test"; @@ -188,6 +210,26 @@ TEST_F(CLASSNAME(TestSubscription, RMW_IMPLEMENTATION), destroy_with_bad_argumen rmw_reset_error(); } +TEST_F(CLASSNAME(TestSubscription, RMW_IMPLEMENTATION), destroy_with_internal_errors) { + constexpr char topic_name[] = "/test"; + const rosidl_message_type_support_t * ts = + ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); + + RCUTILS_FAULT_INJECTION_TEST( + { + rmw_subscription_t * sub = nullptr; + RCUTILS_NO_FAULT_INJECTION( + { + rmw_subscription_options_t options = rmw_get_default_subscription_options(); + sub = rmw_create_subscription(node, ts, topic_name, &rmw_qos_profile_default, &options); + ASSERT_NE(nullptr, sub) << rmw_get_error_string().str; + }); + if (RMW_RET_OK != rmw_destroy_subscription(node, sub)) { + rmw_reset_error(); + } + }); +} + TEST_F(CLASSNAME(TestSubscription, RMW_IMPLEMENTATION), get_actual_qos_from_system_defaults) { rmw_subscription_options_t options = rmw_get_default_subscription_options(); constexpr char topic_name[] = "/test"; diff --git a/test_rmw_implementation/test/test_wait_set.cpp b/test_rmw_implementation/test/test_wait_set.cpp index 38b6e2701..721240b5f 100644 --- a/test_rmw_implementation/test/test_wait_set.cpp +++ b/test_rmw_implementation/test/test_wait_set.cpp @@ -86,16 +86,15 @@ TEST_F(CLASSNAME(TestWaitSet, RMW_IMPLEMENTATION), rmw_create_wait_set) { wait_set = rmw_create_wait_set(&context, 0); - int64_t count = rcutils_fault_injection_get_count(); - rcutils_fault_injection_set_count(RCUTILS_FAULT_INJECTION_NEVER_FAIL); - - if (wait_set != nullptr) { - ret = rmw_destroy_wait_set(wait_set); - EXPECT_EQ(ret, RMW_RET_OK) << rcutils_get_error_string().str; + if (wait_set) { + RCUTILS_NO_FAULT_INJECTION( + { + ret = rmw_destroy_wait_set(wait_set); + EXPECT_EQ(ret, RMW_RET_OK) << rcutils_get_error_string().str; + }); } else { rmw_reset_error(); } - rcutils_fault_injection_set_count(count); }); } @@ -377,7 +376,7 @@ TEST_F(CLASSNAME(TestWaitSetUse, RMW_IMPLEMENTATION), rmw_wait) ret = rmw_wait( &subscriptions, &guard_conditions, &services, &clients, &events, wait_set, &timeout_argument); - + EXPECT_NE(RMW_RET_OK, ret); if (RMW_RET_TIMEOUT == ret) { EXPECT_EQ(nullptr, subscriptions.subscribers[0]); EXPECT_EQ(nullptr, guard_conditions.guard_conditions[0]); @@ -385,7 +384,6 @@ TEST_F(CLASSNAME(TestWaitSetUse, RMW_IMPLEMENTATION), rmw_wait) EXPECT_EQ(nullptr, clients.clients[0]); EXPECT_EQ(nullptr, events.events[0]); } else { - EXPECT_EQ(RMW_RET_ERROR, ret); rmw_reset_error(); } }); diff --git a/test_rmw_implementation/test/testing_macros.hpp b/test_rmw_implementation/test/testing_macros.hpp index ec9d924de..bc8d3f5e4 100644 --- a/test_rmw_implementation/test/testing_macros.hpp +++ b/test_rmw_implementation/test/testing_macros.hpp @@ -18,6 +18,11 @@ #include #include +#include "osrf_testing_tools_cpp/memory_tools/memory_tools.hpp" + +#include "rcutils/macros.h" +#include "rcutils/testing/fault_injection.h" + /// Retry until `timeout` expires, sleeping for `delay` in between attempts. /* * \note Time is measured against OS provided steady clock.