From f3a7318dda412e5cf170b9803051401b21a6ccd9 Mon Sep 17 00:00:00 2001 From: Chen Lihui Date: Tue, 15 Sep 2020 22:28:10 +0800 Subject: [PATCH] Fix memory leak because of mock test (#800) * Fix memory leak because of mock test Signed-off-by: Chen Lihui Co-authored-by: Chris Lalancette --- rcl/test/rcl/test_init.cpp | 70 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/rcl/test/rcl/test_init.cpp b/rcl/test/rcl/test_init.cpp index 6ecce73d4..2abf6f748 100644 --- a/rcl/test/rcl/test_init.cpp +++ b/rcl/test/rcl/test_init.cpp @@ -458,3 +458,73 @@ TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_options_acce EXPECT_EQ(RCL_RET_ALREADY_INIT, rcl_init_options_copy(&init_options, &init_options_dst)); EXPECT_EQ(RCL_RET_OK, rcl_init_options_fini(&init_options_dst)); } + +// Define dummy comparison operators for rcutils_allocator_t type for use with the Mimick Library +MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, ==) +MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, <) +MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, >) +MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, !=) + +// Tests rcl_init_options_init() mocked to fail +TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_mocked_rcl_init_options_ini) { + rcl_init_options_t init_options = rcl_get_zero_initialized_init_options(); + auto mock = mocking_utils::patch_and_return("lib:rcl", rmw_init_options_init, RMW_RET_ERROR); + EXPECT_EQ(RCL_RET_ERROR, rcl_init_options_init(&init_options, rcl_get_default_allocator())); + rcl_reset_error(); +} + +// Tests rcl_init_options_fini() mocked to fail +TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_mocked_rcl_init_options_fini) { + rcl_init_options_t init_options = rcl_get_zero_initialized_init_options(); + rcl_ret_t ret = rcl_init_options_init(&init_options, rcl_get_default_allocator()); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + auto mock = mocking_utils::inject_on_return("lib:rcl", rmw_init_options_fini, RMW_RET_ERROR); + EXPECT_EQ(RCL_RET_ERROR, rcl_init_options_fini(&init_options)); + rcl_reset_error(); + auto mock_ok = mocking_utils::inject_on_return("lib:rcl", rmw_init_options_fini, RMW_RET_OK); + EXPECT_EQ(RCL_RET_OK, rcl_init_options_fini(&init_options)); +} + +// Mock rcl_init_options_copy to fail +TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_copy_mocked_fail_fini) { + rcl_init_options_t init_options = rcl_get_zero_initialized_init_options(); + rcl_ret_t ret = rcl_init_options_init(&init_options, rcl_get_default_allocator()); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( + { + EXPECT_EQ(RCL_RET_OK, rcl_init_options_fini(&init_options)) << rcl_get_error_string().str; + }); + rcl_init_options_t init_options_dst = rcl_get_zero_initialized_init_options(); + auto mock = mocking_utils::inject_on_return("lib:rcl", rmw_init_options_fini, RMW_RET_ERROR); + EXPECT_EQ(RCL_RET_ERROR, rcl_init_options_copy(&init_options, &init_options_dst)); + rcl_reset_error(); + auto mock_ok = mocking_utils::inject_on_return("lib:rcl", rmw_init_options_fini, RMW_RET_OK); + EXPECT_EQ(RCL_RET_OK, rcl_init_options_fini(&init_options_dst)); +} + +// Mock rcl_init_options_copy to fail +TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_options_copy_fail_rmw_copy) { + rcl_init_options_t init_options = rcl_get_zero_initialized_init_options(); + rcl_ret_t ret = rcl_init_options_init(&init_options, rcl_get_default_allocator()); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( + { + EXPECT_EQ(RCL_RET_OK, rcl_init_options_fini(&init_options)) << rcl_get_error_string().str; + }); + rcl_init_options_t init_options_dst = rcl_get_zero_initialized_init_options(); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( + { + // dst is in a invalid state after failed copy + EXPECT_EQ( + RCL_RET_INVALID_ARGUMENT, + rcl_init_options_fini(&init_options_dst)) << rcl_get_error_string().str; + rcl_reset_error(); + auto mock_ok = mocking_utils::patch_and_return("lib:rcl", rmw_init_options_fini, RMW_RET_OK); + EXPECT_EQ(RCL_RET_OK, rcl_init_options_fini(&init_options_dst)) << rcl_get_error_string().str; + }); + + // rmw_init_options_copy error is logged + auto mock = mocking_utils::patch_and_return("lib:rcl", rmw_init_options_copy, RMW_RET_ERROR); + EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_init_options_copy(&init_options, &init_options_dst)); + rcl_reset_error(); +}