2525#include " rcutils/snprintf.h"
2626
2727#include " ./allocator_testing_utils.h"
28+ #include " ../mocking_utils/patch.hpp"
2829#include " ../src/rcl/init_options_impl.h"
2930
3031#ifdef RMW_IMPLEMENTATION
@@ -104,16 +105,34 @@ struct FakeTestArgv
104105 */
105106TEST_F (CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_options_init) {
106107 rcl_init_options_t init_options = rcl_get_zero_initialized_init_options ();
107- rcl_ret_t ret = rcl_init_options_init (&init_options, rcl_get_default_allocator ());
108+
109+ // fini a not empty options
110+ rcl_ret_t ret = rcl_init_options_fini (&init_options);
111+ EXPECT_EQ (RCL_RET_INVALID_ARGUMENT, ret) << rcl_get_error_string ().str ;
112+ rcl_reset_error ();
113+
114+ // Expected usage
115+ ret = rcl_init_options_init (&init_options, rcl_get_default_allocator ());
108116 ASSERT_EQ (RCL_RET_OK, ret) << rcl_get_error_string ().str ;
109117 OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT (
110118 {
111119 EXPECT_EQ (RCL_RET_OK, rcl_init_options_fini (&init_options)) << rcl_get_error_string ().str ;
112120 });
121+
113122 // Already init
114123 ret = rcl_init_options_init (&init_options, rcl_get_default_allocator ());
115124 EXPECT_EQ (RCL_RET_ALREADY_INIT, ret) << rcl_get_error_string ().str ;
116125 rcl_reset_error ();
126+
127+ // nullptr
128+ ret = rcl_init_options_init (nullptr , rcl_get_default_allocator ());
129+ EXPECT_EQ (RCL_RET_INVALID_ARGUMENT, ret) << rcl_get_error_string ().str ;
130+ rcl_reset_error ();
131+
132+ // nullptr
133+ ret = rcl_init_options_fini (nullptr );
134+ EXPECT_EQ (RCL_RET_INVALID_ARGUMENT, ret) << rcl_get_error_string ().str ;
135+ rcl_reset_error ();
117136}
118137
119138/* Tests calling rcl_init() with invalid arguments fails.
@@ -364,6 +383,7 @@ TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_get_instance_id)
364383
365384TEST_F (CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_options_access) {
366385 rcl_init_options_t init_options = rcl_get_zero_initialized_init_options ();
386+ rcl_init_options_t not_ini_init_options = rcl_get_zero_initialized_init_options ();
367387 rcl_ret_t ret = rcl_init_options_init (&init_options, rcl_get_default_allocator ());
368388 ASSERT_EQ (RCL_RET_OK, ret) << rcl_get_error_string ().str ;
369389 OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT (
@@ -375,14 +395,21 @@ TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_options_acce
375395 ASSERT_NE (nullptr , options);
376396 EXPECT_EQ (0u , options->instance_id );
377397 EXPECT_EQ (nullptr , options->impl );
398+ EXPECT_EQ (NULL , rcl_init_options_get_rmw_init_options (nullptr ));
399+ EXPECT_EQ (NULL , rcl_init_options_get_rmw_init_options (¬_ini_init_options));
378400
379401 const rcl_allocator_t * options_allocator = rcl_init_options_get_allocator (&init_options);
380402 EXPECT_TRUE (rcutils_allocator_is_valid (options_allocator));
403+ EXPECT_EQ (NULL , rcl_init_options_get_allocator (nullptr ));
404+ EXPECT_EQ (NULL , rcl_init_options_get_allocator (¬_ini_init_options));
381405
382406 size_t domain_id;
383407 ret = rcl_init_options_get_domain_id (NULL , &domain_id);
384408 ASSERT_EQ (RCL_RET_INVALID_ARGUMENT, ret) << rcl_get_error_string ().str ;
385409 rcl_reset_error ();
410+ ret = rcl_init_options_get_domain_id (¬_ini_init_options, &domain_id);
411+ EXPECT_EQ (RCL_RET_INVALID_ARGUMENT, ret) << rcl_get_error_string ().str ;
412+ rcl_reset_error ();
386413 ret = rcl_init_options_get_domain_id (&init_options, NULL );
387414 ASSERT_EQ (RCL_RET_INVALID_ARGUMENT, ret) << rcl_get_error_string ().str ;
388415 rcl_reset_error ();
@@ -392,6 +419,9 @@ TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_options_acce
392419 ret = rcl_init_options_set_domain_id (NULL , domain_id);
393420 ASSERT_EQ (RCL_RET_INVALID_ARGUMENT, ret) << rcl_get_error_string ().str ;
394421 rcl_reset_error ();
422+ ret = rcl_init_options_set_domain_id (¬_ini_init_options, domain_id);
423+ EXPECT_EQ (RCL_RET_INVALID_ARGUMENT, ret) << rcl_get_error_string ().str ;
424+ rcl_reset_error ();
395425
396426 ret = rcl_init_options_get_domain_id (&init_options, &domain_id);
397427 ASSERT_EQ (RCL_RET_OK, ret) << rcl_get_error_string ().str ;
@@ -403,10 +433,82 @@ TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_options_acce
403433 EXPECT_EQ (0U , domain_id);
404434
405435 rcl_init_options_t init_options_dst = rcl_get_zero_initialized_init_options ();
436+
437+ // nullptr copy cases
438+ EXPECT_EQ (
439+ RCL_RET_INVALID_ARGUMENT, rcl_init_options_copy (nullptr , &init_options_dst));
440+ EXPECT_EQ (
441+ RCL_RET_INVALID_ARGUMENT, rcl_init_options_copy (&init_options, nullptr ));
442+
443+ // Expected usage copy
406444 ASSERT_EQ (RCL_RET_OK, rcl_init_options_copy (&init_options, &init_options_dst));
407445 ret = rcl_init_options_get_domain_id (&init_options_dst, &domain_id);
408446 ASSERT_EQ (RCL_RET_OK, ret) << rcl_get_error_string ().str ;
409447 EXPECT_EQ (0U , domain_id);
410448 EXPECT_EQ (RCL_RET_ALREADY_INIT, rcl_init_options_copy (&init_options, &init_options_dst));
411449 EXPECT_EQ (RCL_RET_OK, rcl_init_options_fini (&init_options_dst));
412450}
451+
452+ // Define dummy comparison operators for rcutils_allocator_t type for use with the Mimick Library
453+ MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE (rcutils_allocator_t , ==)
454+ MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t , <)
455+ MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t , >)
456+ MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t , !=)
457+
458+ // Tests rcl_init_options_init() mocked to fail
459+ TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_mocked_rcl_init_options_ini) {
460+ rcl_init_options_t init_options = rcl_get_zero_initialized_init_options ();
461+ auto mock = mocking_utils::patch_and_return (" lib:rcl" , rmw_init_options_init, RMW_RET_ERROR);
462+ EXPECT_EQ (RCL_RET_ERROR, rcl_init_options_init (&init_options, rcl_get_default_allocator ()));
463+ rcl_reset_error ();
464+ }
465+
466+ // Tests rcl_init_options_fini() mocked to fail
467+ TEST_F (CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_mocked_rcl_init_options_fini) {
468+ rcl_init_options_t init_options = rcl_get_zero_initialized_init_options ();
469+ rcl_ret_t ret = rcl_init_options_init (&init_options, rcl_get_default_allocator ());
470+ ASSERT_EQ (RCL_RET_OK, ret) << rcl_get_error_string ().str ;
471+ auto mock = mocking_utils::inject_on_return (" lib:rcl" , rmw_init_options_fini, RMW_RET_ERROR);
472+ EXPECT_EQ (RCL_RET_ERROR, rcl_init_options_fini (&init_options));
473+ rcl_reset_error ();
474+ }
475+
476+ // Mock rcl_init_options_copy to fail
477+ TEST_F (CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_copy_mocked_fail_fini) {
478+ rcl_init_options_t init_options = rcl_get_zero_initialized_init_options ();
479+ rcl_ret_t ret = rcl_init_options_init (&init_options, rcl_get_default_allocator ());
480+ ASSERT_EQ (RCL_RET_OK, ret) << rcl_get_error_string ().str ;
481+ OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT (
482+ {
483+ EXPECT_EQ (RCL_RET_OK, rcl_init_options_fini (&init_options)) << rcl_get_error_string ().str ;
484+ });
485+ rcl_init_options_t init_options_dst = rcl_get_zero_initialized_init_options ();
486+ auto mock = mocking_utils::inject_on_return (" lib:rcl" , rmw_init_options_fini, RMW_RET_ERROR);
487+ EXPECT_EQ (RCL_RET_ERROR, rcl_init_options_copy (&init_options, &init_options_dst));
488+ rcl_reset_error ();
489+ }
490+
491+ // Mock rcl_init_options_copy to fail
492+ TEST_F (CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_options_copy_fail_rmw_copy) {
493+ rcl_init_options_t init_options = rcl_get_zero_initialized_init_options ();
494+ rcl_ret_t ret = rcl_init_options_init (&init_options, rcl_get_default_allocator ());
495+ ASSERT_EQ (RCL_RET_OK, ret) << rcl_get_error_string ().str ;
496+ OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT (
497+ {
498+ EXPECT_EQ (RCL_RET_OK, rcl_init_options_fini (&init_options)) << rcl_get_error_string ().str ;
499+ });
500+ rcl_init_options_t init_options_dst = rcl_get_zero_initialized_init_options ();
501+ OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT (
502+ {
503+ // dst is in a invalid state after failed copy
504+ EXPECT_EQ (
505+ RCL_RET_INVALID_ARGUMENT,
506+ rcl_init_options_fini (&init_options_dst)) << rcl_get_error_string ().str ;
507+ rcl_reset_error ();
508+ });
509+
510+ // rmw_init_options_copy error is logged
511+ auto mock = mocking_utils::patch_and_return (" lib:rcl" , rmw_init_options_copy, RMW_RET_ERROR);
512+ EXPECT_EQ (RCL_RET_INVALID_ARGUMENT, rcl_init_options_copy (&init_options, &init_options_dst));
513+ rcl_reset_error ();
514+ }
0 commit comments