Skip to content

Commit 4204ed5

Browse files
authored
Add fault injection tests to construction/destroy APIs. (#144)
Signed-off-by: Michel Hidalgo <[email protected]>
1 parent 9abac34 commit 4204ed5

File tree

9 files changed

+331
-33
lines changed

9 files changed

+331
-33
lines changed

test_rmw_implementation/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ if(BUILD_TESTING)
7272
ament_add_gtest(test_subscription${target_suffix}
7373
test/test_subscription.cpp
7474
ENV ${rmw_implementation_env_var}
75-
TIMEOUT 80
75+
TIMEOUT 120
7676
)
7777
target_compile_definitions(test_subscription${target_suffix}
7878
PUBLIC "RMW_IMPLEMENTATION=${rmw_implementation}")

test_rmw_implementation/test/test_client.cpp

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,44 @@ TEST_F(CLASSNAME(TestClient, RMW_IMPLEMENTATION), create_with_bad_arguments) {
159159
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
160160
}
161161

162+
TEST_F(CLASSNAME(TestClient, RMW_IMPLEMENTATION), create_with_internal_errors) {
163+
constexpr char service_name[] = "/test";
164+
const rosidl_service_type_support_t * ts =
165+
ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes);
166+
RCUTILS_FAULT_INJECTION_TEST(
167+
{
168+
rmw_client_t * client =
169+
rmw_create_client(node, ts, service_name, &rmw_qos_profile_default);
170+
if (client) {
171+
RCUTILS_NO_FAULT_INJECTION(
172+
{
173+
rmw_ret_t ret = rmw_destroy_client(node, client);
174+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
175+
});
176+
} else {
177+
rmw_reset_error();
178+
}
179+
});
180+
}
181+
182+
TEST_F(CLASSNAME(TestClient, RMW_IMPLEMENTATION), destroy_with_internal_errors) {
183+
constexpr char service_name[] = "/test";
184+
const rosidl_service_type_support_t * ts =
185+
ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes);
186+
RCUTILS_FAULT_INJECTION_TEST(
187+
{
188+
rmw_client_t * client = nullptr;
189+
RCUTILS_NO_FAULT_INJECTION(
190+
{
191+
client = rmw_create_client(node, ts, service_name, &rmw_qos_profile_default);
192+
ASSERT_NE(nullptr, client) << rmw_get_error_string().str;
193+
});
194+
if (RMW_RET_OK != rmw_destroy_client(node, client)) {
195+
rmw_reset_error();
196+
}
197+
});
198+
}
199+
162200
class CLASSNAME (TestClientUse, RMW_IMPLEMENTATION)
163201
: public CLASSNAME(TestClient, RMW_IMPLEMENTATION)
164202
{
@@ -373,26 +411,3 @@ TEST_F(CLASSNAME(TestClientUse, RMW_IMPLEMENTATION), service_server_is_available
373411
ret = rmw_destroy_service(node, service);
374412
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
375413
}
376-
377-
TEST_F(CLASSNAME(TestClient, RMW_IMPLEMENTATION), create_client_with_internal_errors)
378-
{
379-
RCUTILS_FAULT_INJECTION_TEST(
380-
{
381-
const rosidl_service_type_support_t * ts = ROSIDL_GET_SRV_TYPE_SUPPORT(
382-
test_msgs, srv, BasicTypes);
383-
rmw_client_t * client_fault = rmw_create_client(
384-
node, ts, "/service_name_test",
385-
&rmw_qos_profile_default);
386-
387-
int64_t count = rcutils_fault_injection_get_count();
388-
rcutils_fault_injection_set_count(RCUTILS_FAULT_INJECTION_NEVER_FAIL);
389-
390-
if (client_fault != nullptr) {
391-
rmw_ret_t ret = rmw_destroy_client(node, client_fault);
392-
EXPECT_EQ(ret, RMW_RET_OK) << rcutils_get_error_string().str;
393-
} else {
394-
rmw_reset_error();
395-
}
396-
rcutils_fault_injection_set_count(count);
397-
});
398-
}

test_rmw_implementation/test/test_create_destroy_node.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@
1414

1515
#include <gtest/gtest.h>
1616

17+
#include "osrf_testing_tools_cpp/memory_tools/memory_tools.hpp"
18+
1719
#include "rcutils/allocator.h"
1820
#include "rcutils/strdup.h"
1921

2022
#include "rmw/error_handling.h"
2123
#include "rmw/rmw.h"
2224

25+
#include "./testing_macros.hpp"
26+
2327

2428
#ifdef RMW_IMPLEMENTATION
2529
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
@@ -173,3 +177,42 @@ TEST_F(
173177
ASSERT_NE(nullptr, node) << rmw_get_error_string().str;
174178
EXPECT_EQ(RMW_RET_OK, rmw_destroy_node(node)) << rmw_get_error_string().str;
175179
}
180+
181+
TEST_F(
182+
CLASSNAME(TestNodeConstructionDestruction, RMW_IMPLEMENTATION),
183+
create_with_internal_errors) {
184+
RCUTILS_FAULT_INJECTION_TEST(
185+
{
186+
constexpr char node_name[] = "my_node";
187+
constexpr char node_namespace[] = "/my_ns";
188+
rmw_node_t * node = rmw_create_node(&context, node_name, node_namespace);
189+
if (node) {
190+
RCUTILS_NO_FAULT_INJECTION(
191+
{
192+
rmw_ret_t ret = rmw_destroy_node(node);
193+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
194+
});
195+
} else {
196+
rmw_reset_error();
197+
}
198+
});
199+
}
200+
201+
TEST_F(
202+
CLASSNAME(TestNodeConstructionDestruction, RMW_IMPLEMENTATION),
203+
destroy_with_internal_errors) {
204+
RCUTILS_FAULT_INJECTION_TEST(
205+
{
206+
constexpr char node_name[] = "my_node";
207+
constexpr char node_namespace[] = "/my_ns";
208+
rmw_node_t * node = nullptr;
209+
RCUTILS_NO_FAULT_INJECTION(
210+
{
211+
node = rmw_create_node(&context, node_name, node_namespace);
212+
ASSERT_NE(nullptr, node) << rmw_get_error_string().str;
213+
});
214+
if (RMW_RET_OK != rmw_destroy_node(node)) {
215+
rmw_reset_error();
216+
}
217+
});
218+
}

test_rmw_implementation/test/test_init_shutdown.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,18 @@
1414

1515
#include <gtest/gtest.h>
1616

17+
#include "osrf_testing_tools_cpp/memory_tools/memory_tools.hpp"
18+
1719
#include "rcutils/allocator.h"
1820
#include "rcutils/error_handling.h"
21+
#include "rcutils/macros.h"
1922
#include "rcutils/strdup.h"
2023

24+
#include "rmw/error_handling.h"
2125
#include "rmw/rmw.h"
2226

27+
#include "./testing_macros.hpp"
28+
2329
#ifdef RMW_IMPLEMENTATION
2430
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
2531
# define CLASSNAME(NAME, SUFFIX) CLASSNAME_(NAME, SUFFIX)
@@ -170,3 +176,69 @@ TEST_F(CLASSNAME(TestInitShutdown, RMW_IMPLEMENTATION), init_shutdown) {
170176
ret = rmw_context_fini(&context);
171177
EXPECT_EQ(RMW_RET_OK, ret) << rcutils_get_error_string().str;
172178
}
179+
180+
TEST_F(CLASSNAME(TestInitShutdown, RMW_IMPLEMENTATION), init_with_internal_errors) {
181+
RCUTILS_FAULT_INJECTION_TEST(
182+
{
183+
rmw_context_t context = rmw_get_zero_initialized_context();
184+
rmw_ret_t ret = rmw_init(&options, &context);
185+
186+
RCUTILS_NO_FAULT_INJECTION(
187+
{
188+
if (RMW_RET_OK == ret) {
189+
ret = rmw_shutdown(&context);
190+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
191+
ret = rmw_context_fini(&context);
192+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
193+
} else {
194+
rmw_reset_error();
195+
}
196+
});
197+
});
198+
}
199+
200+
TEST_F(CLASSNAME(TestInitShutdown, RMW_IMPLEMENTATION), shutdown_with_internal_errors) {
201+
RCUTILS_FAULT_INJECTION_TEST(
202+
{
203+
rmw_ret_t ret = RMW_RET_OK;
204+
rmw_context_t context = rmw_get_zero_initialized_context();
205+
206+
RCUTILS_NO_FAULT_INJECTION(
207+
{
208+
ret = rmw_init(&options, &context);
209+
ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
210+
});
211+
212+
ret = rmw_shutdown(&context);
213+
214+
RCUTILS_NO_FAULT_INJECTION(
215+
{
216+
if (RMW_RET_OK != ret) {
217+
rmw_reset_error();
218+
219+
ret = rmw_shutdown(&context);
220+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
221+
}
222+
ret = rmw_context_fini(&context);
223+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
224+
});
225+
});
226+
}
227+
228+
TEST_F(CLASSNAME(TestInitShutdown, RMW_IMPLEMENTATION), context_fini_with_internal_errors) {
229+
RCUTILS_FAULT_INJECTION_TEST(
230+
{
231+
rmw_context_t context = rmw_get_zero_initialized_context();
232+
RCUTILS_NO_FAULT_INJECTION(
233+
{
234+
rmw_ret_t ret = rmw_init(&options, &context);
235+
ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
236+
ret = rmw_shutdown(&context);
237+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
238+
});
239+
240+
if (RMW_RET_OK != rmw_context_fini(&context)) {
241+
rmw_reset_error();
242+
}
243+
});
244+
}

test_rmw_implementation/test/test_publisher.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
#include <gtest/gtest.h>
1616

1717
#include "osrf_testing_tools_cpp/memory_tools/gtest_quickstart.hpp"
18+
#include "osrf_testing_tools_cpp/scope_exit.hpp"
1819

1920
#include "rcutils/allocator.h"
21+
#include "rcutils/macros.h"
2022
#include "rcutils/strdup.h"
2123

2224
#include "rmw/rmw.h"
@@ -82,6 +84,28 @@ TEST_F(CLASSNAME(TestPublisher, RMW_IMPLEMENTATION), create_and_destroy) {
8284
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
8385
}
8486

87+
TEST_F(CLASSNAME(TestPublisher, RMW_IMPLEMENTATION), create_with_internal_errors) {
88+
constexpr char topic_name[] = "/test";
89+
const rosidl_message_type_support_t * ts =
90+
ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes);
91+
92+
RCUTILS_FAULT_INJECTION_TEST(
93+
{
94+
rmw_publisher_t * pub = nullptr;
95+
rmw_publisher_options_t options = rmw_get_default_publisher_options();
96+
pub = rmw_create_publisher(node, ts, topic_name, &rmw_qos_profile_default, &options);
97+
if (pub) {
98+
RCUTILS_NO_FAULT_INJECTION(
99+
{
100+
rmw_ret_t ret = rmw_destroy_publisher(node, pub);
101+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
102+
});
103+
} else {
104+
rmw_reset_error();
105+
}
106+
});
107+
}
108+
85109
TEST_F(CLASSNAME(TestPublisher, RMW_IMPLEMENTATION), create_and_destroy_native) {
86110
rmw_publisher_options_t options = rmw_get_default_publisher_options();
87111
constexpr char topic_name[] = "test";
@@ -194,6 +218,26 @@ TEST_F(CLASSNAME(TestPublisher, RMW_IMPLEMENTATION), destroy_with_bad_arguments)
194218
rmw_reset_error();
195219
}
196220

221+
TEST_F(CLASSNAME(TestPublisher, RMW_IMPLEMENTATION), destroy_with_internal_errors) {
222+
constexpr char topic_name[] = "/test";
223+
const rosidl_message_type_support_t * ts =
224+
ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes);
225+
226+
RCUTILS_FAULT_INJECTION_TEST(
227+
{
228+
rmw_publisher_t * pub = nullptr;
229+
RCUTILS_NO_FAULT_INJECTION(
230+
{
231+
rmw_publisher_options_t options = rmw_get_default_publisher_options();
232+
pub = rmw_create_publisher(node, ts, topic_name, &rmw_qos_profile_default, &options);
233+
ASSERT_NE(nullptr, pub) << rmw_get_error_string().str;
234+
});
235+
if (RMW_RET_OK != rmw_destroy_publisher(node, pub)) {
236+
rmw_reset_error();
237+
}
238+
});
239+
}
240+
197241
TEST_F(CLASSNAME(TestPublisher, RMW_IMPLEMENTATION), get_actual_qos_from_system_defaults) {
198242
rmw_publisher_options_t options = rmw_get_default_publisher_options();
199243
constexpr char topic_name[] = "/test";
@@ -414,6 +458,20 @@ TEST_F(
414458
test_msgs__msg__BasicTypes__fini(&input_message);
415459
}
416460

461+
TEST_F(CLASSNAME(TestPublisherUse, RMW_IMPLEMENTATION), publish_with_internal_errors) {
462+
test_msgs__msg__BasicTypes message{};
463+
ASSERT_TRUE(test_msgs__msg__BasicTypes__init(&message));
464+
rmw_publisher_allocation_t * null_allocation{nullptr}; // still a valid allocation
465+
466+
RCUTILS_FAULT_INJECTION_TEST(
467+
{
468+
rmw_ret_t ret = rmw_publish(pub, &message, null_allocation);
469+
if (RMW_RET_OK != ret) {
470+
rmw_reset_error();
471+
}
472+
});
473+
}
474+
417475
TEST_F(
418476
CLASSNAME(TestPublisherUse, RMW_IMPLEMENTATION),
419477
publish_serialized_message_with_bad_arguments) {
@@ -443,6 +501,33 @@ TEST_F(
443501
RMW_RET_OK, rmw_serialized_message_fini(&serialized_message)) << rmw_get_error_string().str;
444502
}
445503

504+
TEST_F(CLASSNAME(TestPublisherUse, RMW_IMPLEMENTATION), publish_serialized_with_internal_errors) {
505+
test_msgs__msg__BasicTypes message{};
506+
ASSERT_TRUE(test_msgs__msg__BasicTypes__init(&message));
507+
rcutils_allocator_t default_allocator = rcutils_get_default_allocator();
508+
rmw_serialized_message_t serialized_message = rmw_get_zero_initialized_serialized_message();
509+
rmw_ret_t ret = rmw_serialized_message_init(&serialized_message, 0lu, &default_allocator);
510+
ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
511+
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
512+
{
513+
rmw_ret_t ret = rmw_serialized_message_fini(&serialized_message);
514+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
515+
});
516+
ret = rmw_serialize(&message, ts, &serialized_message);
517+
ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
518+
rmw_publisher_allocation_t * null_allocation{nullptr}; // still a valid allocation
519+
520+
RCUTILS_FAULT_INJECTION_TEST(
521+
{
522+
ret = rmw_publish_serialized_message(
523+
pub, &serialized_message, null_allocation);
524+
if (RMW_RET_OK != ret) {
525+
rmw_reset_error();
526+
}
527+
});
528+
}
529+
530+
446531
class CLASSNAME (TestPublisherUseLoan, RMW_IMPLEMENTATION)
447532
: public CLASSNAME(TestPublisherUse, RMW_IMPLEMENTATION)
448533
{

test_rmw_implementation/test/test_service.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,44 @@ TEST_F(CLASSNAME(TestService, RMW_IMPLEMENTATION), create_with_bad_arguments) {
160160
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
161161
}
162162

163+
164+
TEST_F(CLASSNAME(TestService, RMW_IMPLEMENTATION), create_with_internal_errors) {
165+
constexpr char service_name[] = "/test";
166+
const rosidl_service_type_support_t * ts =
167+
ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes);
168+
RCUTILS_FAULT_INJECTION_TEST(
169+
{
170+
rmw_service_t * srv = rmw_create_service(node, ts, service_name, &rmw_qos_profile_default);
171+
if (srv) {
172+
RCUTILS_NO_FAULT_INJECTION(
173+
{
174+
rmw_ret_t ret = rmw_destroy_service(node, srv);
175+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
176+
});
177+
} else {
178+
rmw_reset_error();
179+
}
180+
});
181+
}
182+
183+
TEST_F(CLASSNAME(TestService, RMW_IMPLEMENTATION), destroy_with_internal_errors) {
184+
constexpr char service_name[] = "/test";
185+
const rosidl_service_type_support_t * ts =
186+
ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes);
187+
RCUTILS_FAULT_INJECTION_TEST(
188+
{
189+
rmw_service_t * srv = nullptr;
190+
RCUTILS_NO_FAULT_INJECTION(
191+
{
192+
srv = rmw_create_service(node, ts, service_name, &rmw_qos_profile_default);
193+
ASSERT_NE(nullptr, srv) << rmw_get_error_string().str;
194+
});
195+
if (RMW_RET_OK != rmw_destroy_service(node, srv)) {
196+
rmw_reset_error();
197+
}
198+
});
199+
}
200+
163201
class CLASSNAME (TestServiceUse, RMW_IMPLEMENTATION)
164202
: public CLASSNAME(TestService, RMW_IMPLEMENTATION)
165203
{

0 commit comments

Comments
 (0)