From 8311924347d43dc35329190c595c1222987c16ba Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Wed, 29 Jul 2020 18:45:59 -0300 Subject: [PATCH 01/38] Add mimick test for rcl_publisher_get_subscription_count Signed-off-by: Jorge Perez --- rcl/package.xml | 1 + rcl/test/CMakeLists.txt | 4 ++- rcl/test/rcl/test_publisher.cpp | 45 +++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/rcl/package.xml b/rcl/package.xml index 6334f95bb..a28382aff 100644 --- a/rcl/package.xml +++ b/rcl/package.xml @@ -25,6 +25,7 @@ ament_cmake_gtest ament_lint_auto ament_lint_common + mimick_vendor rcpputils rmw rmw_implementation_cmake diff --git a/rcl/test/CMakeLists.txt b/rcl/test/CMakeLists.txt index 9e0d85fdd..c177d2ed2 100644 --- a/rcl/test/CMakeLists.txt +++ b/rcl/test/CMakeLists.txt @@ -3,6 +3,8 @@ find_package(launch_testing_ament_cmake REQUIRED) find_package(test_msgs REQUIRED) +find_package(mimick_vendor REQUIRED) + find_package(rcpputils REQUIRED) find_package(rcutils REQUIRED) find_package(rmw_implementation_cmake REQUIRED) @@ -207,7 +209,7 @@ function(test_target_function) ENV ${rmw_implementation_env_var} APPEND_LIBRARY_DIRS ${extra_lib_dirs} INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../src/rcl/ - LIBRARIES ${PROJECT_NAME} + LIBRARIES ${PROJECT_NAME} mimick AMENT_DEPENDENCIES ${rmw_implementation} "osrf_testing_tools_cpp" "test_msgs" ) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 40cc36c12..9d49fd02d 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -25,6 +25,7 @@ #include "osrf_testing_tools_cpp/scope_exit.hpp" #include "rcl/error_handling.h" +#include "./mimick.h" #include "./publisher_impl.h" #ifdef RMW_IMPLEMENTATION @@ -490,3 +491,47 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish rcl_publish_serialized_message(nullptr, &serialized_msg, nullptr)); rcl_reset_error(); } + +// rmw_publisher_count_matched_subscriptions signature: +// rmw_ret_t rmw_publisher_count_matched_subscriptions ( +// const rmw_publisher_t *publisher, size_t *subscription_count) +mmk_mock_define( + rmw_publisher_count_matched_subscriptions, + rmw_ret_t, + const rmw_publisher_t *, + size_t *); + +// Mocking test example +TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_count) { + mmk_mock( + RCUTILS_STRINGIFY(rmw_publisher_count_matched_subscriptions) "@lib:rmw", + rmw_publisher_count_matched_subscriptions_mock); + + mmk_when( + rmw_publisher_count_matched_subscriptions(mmk_any(const rmw_publisher_t *), mmk_any(size_t *)), + .then_return = mmk_val(rmw_ret_t, RMW_RET_BAD_ALLOC)); + + // Now normal usage of the function rcl_publisher_get_subscription_count returning + // unexpected RMW_RET_BAD_ALLOC + rcl_ret_t ret; + rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); + const rosidl_message_type_support_t * ts = + ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); + const char * topic_name = "chatter"; + const char * expected_topic_name = "/chatter"; + rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( + { + rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + + size_t count_size; + EXPECT_EQ( + RCL_RET_BAD_ALLOC, rcl_publisher_get_subscription_count(&publisher, &count_size)); + rcl_reset_error(); + + mmk_reset(rmw_publisher_count_matched_subscriptions); +} From 3450eb106eacbe50f495559725f7e3cd4406dfc7 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Wed, 29 Jul 2020 18:56:31 -0300 Subject: [PATCH 02/38] Remove const qualifiers Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 9d49fd02d..383e902e9 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -498,7 +498,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish mmk_mock_define( rmw_publisher_count_matched_subscriptions, rmw_ret_t, - const rmw_publisher_t *, + rmw_publisher_t *, size_t *); // Mocking test example @@ -508,7 +508,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_ rmw_publisher_count_matched_subscriptions_mock); mmk_when( - rmw_publisher_count_matched_subscriptions(mmk_any(const rmw_publisher_t *), mmk_any(size_t *)), + rmw_publisher_count_matched_subscriptions(mmk_any(rmw_publisher_t *), mmk_any(size_t *)), .then_return = mmk_val(rmw_ret_t, RMW_RET_BAD_ALLOC)); // Now normal usage of the function rcl_publisher_get_subscription_count returning From 64e1f49b4961f327a9f485ce89081d21d00b63d4 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Wed, 29 Jul 2020 19:08:55 -0300 Subject: [PATCH 03/38] Add missing mock suffix Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 383e902e9..6413af5c3 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -496,7 +496,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish // rmw_ret_t rmw_publisher_count_matched_subscriptions ( // const rmw_publisher_t *publisher, size_t *subscription_count) mmk_mock_define( - rmw_publisher_count_matched_subscriptions, + rmw_publisher_count_matched_subscriptions_mock, rmw_ret_t, rmw_publisher_t *, size_t *); From 2d9d15cae4a5f82f39aaafbf3758f8a4ed7136de Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Wed, 29 Jul 2020 19:20:16 -0300 Subject: [PATCH 04/38] Remove unused variable Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 6413af5c3..2b387c54d 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -518,7 +518,6 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_ const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); const char * topic_name = "chatter"; - const char * expected_topic_name = "/chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; From 298a0c2a3759f9c1a0808e8770e4ec24abd54eef Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Wed, 29 Jul 2020 19:40:26 -0300 Subject: [PATCH 05/38] Fix linter issue Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 2b387c54d..9ce0e0883 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -504,7 +504,8 @@ mmk_mock_define( // Mocking test example TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_count) { mmk_mock( - RCUTILS_STRINGIFY(rmw_publisher_count_matched_subscriptions) "@lib:rmw", + // RCUTILS_STRINGIFY(rmw_publisher_count_matched_subscriptions) "@lib:rmw", + "rmw_publisher_count_ma@lib:rmw", rmw_publisher_count_matched_subscriptions_mock); mmk_when( @@ -528,7 +529,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_ }); size_t count_size; - EXPECT_EQ( + EXPECT_EQ( RCL_RET_BAD_ALLOC, rcl_publisher_get_subscription_count(&publisher, &count_size)); rcl_reset_error(); From e3b5e89b618dcc5decff2ba1bf6bdad72a4e6854 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Wed, 29 Jul 2020 19:55:53 -0300 Subject: [PATCH 06/38] Target lib at rcl instead of rmw Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 9ce0e0883..7d850444a 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -504,8 +504,7 @@ mmk_mock_define( // Mocking test example TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_count) { mmk_mock( - // RCUTILS_STRINGIFY(rmw_publisher_count_matched_subscriptions) "@lib:rmw", - "rmw_publisher_count_ma@lib:rmw", + RCUTILS_STRINGIFY(rmw_publisher_count_matched_subscriptions) "@lib:rcl", rmw_publisher_count_matched_subscriptions_mock); mmk_when( From 1633b609b371a8c2ea9469c1acbb0f5bfd980916 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Mon, 3 Aug 2020 10:52:00 -0300 Subject: [PATCH 07/38] Add proper library file Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 7d850444a..23a28c652 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -25,7 +25,7 @@ #include "osrf_testing_tools_cpp/scope_exit.hpp" #include "rcl/error_handling.h" -#include "./mimick.h" +#include "mimick/mimick.h" #include "./publisher_impl.h" #ifdef RMW_IMPLEMENTATION From 807a93592221632091af6e25b36a5b6723db1803 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Mon, 3 Aug 2020 13:10:29 -0300 Subject: [PATCH 08/38] Improve test description Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 23a28c652..5dec8746b 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -501,7 +501,8 @@ mmk_mock_define( rmw_publisher_t *, size_t *); -// Mocking test example +// Mocking rmw_publisher_count_matched_subscriptions to make +// rcl_publisher_get_subscription_count fail TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_count) { mmk_mock( RCUTILS_STRINGIFY(rmw_publisher_count_matched_subscriptions) "@lib:rcl", From 108b1022140ce8014eb55a877463cd3b26333224 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Mon, 3 Aug 2020 13:37:26 -0300 Subject: [PATCH 09/38] Add mock test for rcl_publisher_assert_liveliness Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 5dec8746b..1e84935f2 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -535,3 +535,45 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_ mmk_reset(rmw_publisher_count_matched_subscriptions); } + +// rmw_publisher_assert_liveliness signature: +// rmw_ret_t rmw_publisher_assert_liveliness(const rmw_publisher_t *publisher) +mmk_mock_define( + rmw_publisher_assert_liveliness_mock, + rmw_ret_t, + rmw_publisher_t *); + +// Mocking rmw_publisher_assert_liveliness to make +// rcl_publisher_assert_liveliness fail +TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_assert_liveliness) { + mmk_mock( + RCUTILS_STRINGIFY(rmw_publisher_assert_liveliness) "@lib:rcl", + rmw_publisher_assert_liveliness_mock); + + mmk_when( + rmw_publisher_assert_liveliness(mmk_any(rmw_publisher_t *)), + .then_return = mmk_val(rmw_ret_t, RMW_RET_ERROR)); + + // Now normal usage of the function rcl_publisher_assert_liveliness returning + // unexpected RMW_RET_ERROR + rcl_ret_t ret; + rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); + const rosidl_message_type_support_t * ts = + ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); + const char * topic_name = "chatter"; + rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( + { + rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + + EXPECT_EQ( + RCL_RET_ERROR, rcl_publisher_assert_liveliness(&publisher)); + EXPECT_TRUE(rcl_error_is_set()); + rcl_reset_error(); + + mmk_reset(rmw_publisher_assert_liveliness); +} From 25e7082327db086640e3a452f8960d6a419dd6db Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Mon, 3 Aug 2020 13:52:38 -0300 Subject: [PATCH 10/38] Add class to init publisher tests Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 60 ++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 1e84935f2..e07efc9a8 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -77,6 +77,34 @@ class CLASSNAME (TestPublisherFixture, RMW_IMPLEMENTATION) : public ::testing::T } }; +class CLASSNAME (TestPublisherFixtureInit, RMW_IMPLEMENTATION) + : public CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION) +{ +public: + const rosidl_message_type_support_t * ts = + ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); + const char * topic_name = "chatter"; + rcl_ret_t ret; + rcl_publisher_t publisher; + rcl_publisher_options_t publisher_options; + + void SetUp() override + { + CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION) ::SetUp(); + publisher = rcl_get_zero_initialized_publisher(); + publisher_options = rcl_publisher_get_default_options(); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + } + + void TearDown() override + { + rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION) ::TearDown(); + } +}; + /* Basic nominal test of a publisher. */ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_publisher_nominal) { @@ -503,7 +531,7 @@ mmk_mock_define( // Mocking rmw_publisher_count_matched_subscriptions to make // rcl_publisher_get_subscription_count fail -TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_count) { +TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publisher_count) { mmk_mock( RCUTILS_STRINGIFY(rmw_publisher_count_matched_subscriptions) "@lib:rcl", rmw_publisher_count_matched_subscriptions_mock); @@ -514,20 +542,6 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_ // Now normal usage of the function rcl_publisher_get_subscription_count returning // unexpected RMW_RET_BAD_ALLOC - rcl_ret_t ret; - rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); - const rosidl_message_type_support_t * ts = - ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); - const char * topic_name = "chatter"; - rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); - ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); - ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( - { - rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - }); - size_t count_size; EXPECT_EQ( RCL_RET_BAD_ALLOC, rcl_publisher_get_subscription_count(&publisher, &count_size)); @@ -545,7 +559,7 @@ mmk_mock_define( // Mocking rmw_publisher_assert_liveliness to make // rcl_publisher_assert_liveliness fail -TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_assert_liveliness) { +TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_assert_liveliness) { mmk_mock( RCUTILS_STRINGIFY(rmw_publisher_assert_liveliness) "@lib:rcl", rmw_publisher_assert_liveliness_mock); @@ -556,20 +570,6 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_assert_liv // Now normal usage of the function rcl_publisher_assert_liveliness returning // unexpected RMW_RET_ERROR - rcl_ret_t ret; - rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); - const rosidl_message_type_support_t * ts = - ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); - const char * topic_name = "chatter"; - rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); - ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); - ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( - { - rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - }); - EXPECT_EQ( RCL_RET_ERROR, rcl_publisher_assert_liveliness(&publisher)); EXPECT_TRUE(rcl_error_is_set()); From 5e4cab5a6a55be1f4b4c0cd4c99fad4c20c53e7e Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Mon, 3 Aug 2020 14:14:01 -0300 Subject: [PATCH 11/38] Add test for mocked rmw_publish Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index e07efc9a8..325c580e6 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -577,3 +577,39 @@ TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_assert mmk_reset(rmw_publisher_assert_liveliness); } + +// rmw_publish signature: +// rmw_ret_t rmw_publish( +// const rmw_publisher_t *publisher, +// const void * ros_message, +// rmw_publisher_allocation_t * allocation) +mmk_mock_define( + rmw_publish_mock, + rmw_ret_t, + rmw_publisher_t *, + void *, + rmw_publisher_allocation_t *); + +// Mocking rmw_publish to make rcl_publish fail +TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publish) { + mmk_mock( + RCUTILS_STRINGIFY(rmw_publish) "@lib:rcl", + rmw_publish_mock); + + mmk_when( + rmw_publish( + mmk_any(rmw_publisher_t *), mmk_any(void *), mmk_any(rmw_publisher_allocation_t *)), + .then_return = mmk_val(rmw_ret_t, RMW_RET_ERROR)); + + // Test normal usage of the function rcl_publish returning unexpected RMW_RET_ERROR + test_msgs__msg__BasicTypes msg; + test_msgs__msg__BasicTypes__init(&msg); + msg.int64_value = 42; + ret = rcl_publish(&publisher, &msg, nullptr); + test_msgs__msg__BasicTypes__fini(&msg); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + EXPECT_TRUE(rcl_error_is_set()); + rcl_reset_error(); + + mmk_reset(rmw_publish); +} From 449e8f8a08f6f49696229d2012c4f1ba65ded301 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Mon, 3 Aug 2020 16:55:58 -0300 Subject: [PATCH 12/38] Add mock test for rcl_publish_serialized Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 66 +++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 325c580e6..ab70ae61e 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -613,3 +613,69 @@ TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publis mmk_reset(rmw_publish); } + +// rmw_publish_serialized_message signature: +// rmw_ret_t rmw_publish_serialized_message( +// const rmw_publisher_t *publisher, +// const rmw_serialized_message_t * ros_message, +// rmw_publisher_allocation_t * allocation) +mmk_mock_define( + rmw_publish_serialized_message_mock, + rmw_ret_t, + rmw_publisher_t *, + rmw_serialized_message_t *, + rmw_publisher_allocation_t *); + +// Mocking rmw_publish_serialized_message to make rcl_publish_serialized_message fail +TEST_F( + CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publish_serialized_message) +{ + mmk_mock( + RCUTILS_STRINGIFY(rmw_publish_serialized_message) "@lib:rcl", + rmw_publish_serialized_message_mock); + + mmk_when( + rmw_publish_serialized_message( + mmk_any(rmw_publisher_t *), + mmk_any(rmw_serialized_message_t *), + mmk_any(rmw_publisher_allocation_t *)), + .then_return = mmk_val(rmw_ret_t, RMW_RET_ERROR)); + + // Test normal usage of the function rcl_publish_serialized_message + // returning unexpected RMW_RET_ERROR + rcl_serialized_message_t serialized_msg = rmw_get_zero_initialized_serialized_message(); + size_t initial_capacity_ser = 0u; + rcl_allocator_t allocator = rcl_get_default_allocator(); + ASSERT_EQ( + RCL_RET_OK, rmw_serialized_message_init( + &serialized_msg, initial_capacity_ser, &allocator)) << rcl_get_error_string().str; + const char * test_string = "testing"; + test_msgs__msg__Strings msg; + test_msgs__msg__Strings__init(&msg); + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( + { + test_msgs__msg__Strings__fini(&msg); + }); + ASSERT_TRUE(rosidl_runtime_c__String__assign(&msg.string_value, test_string)); + ASSERT_STREQ(msg.string_value.data, test_string); + ret = rmw_serialize(&msg, ts, &serialized_msg); + ASSERT_EQ(RMW_RET_OK, ret); + ret = rcl_publish_serialized_message(&publisher, &serialized_msg, nullptr); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + EXPECT_TRUE(rcl_error_is_set()); + rcl_reset_error(); + + // Repeat, but now returning BAD_ALLOC + mmk_when( + rmw_publish_serialized_message( + mmk_any(rmw_publisher_t *), + mmk_any(rmw_serialized_message_t *), + mmk_any(rmw_publisher_allocation_t *)), + .then_return = mmk_val(rmw_ret_t, RMW_RET_BAD_ALLOC)); + ret = rcl_publish_serialized_message(&publisher, &serialized_msg, nullptr); + EXPECT_EQ(RCL_RET_BAD_ALLOC, ret) << rcl_get_error_string().str; + EXPECT_TRUE(rcl_error_is_set()); + rcl_reset_error(); + + mmk_reset(rmw_publish_serialized_message); +} From 6920f503f0658cbacf12898fd5a0e00b70dbe0b1 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Tue, 4 Aug 2020 18:14:18 -0300 Subject: [PATCH 13/38] Mock rcutils_string_map_init to make init fail Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 62 +++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index ab70ae61e..d94cc5bdf 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -679,3 +679,65 @@ TEST_F( mmk_reset(rmw_publish_serialized_message); } + +/* +// rcutils_string_map_init signature: +// rcutils_ret_t rcutils_string_map_init( +// rcutils_string_map_t * string_map, +// size_t initial_capacity, +// rcutils_allocator_t allocator); +mmk_mock_define( + rcutils_string_map_init_mock, + rcutils_ret_t, + rcutils_string_map_t *, + size_t, + rcutils_allocator_t); + +rcutils_ret_t mocked_rcutils_string_map_init( + rcutils_string_map_t * string_map, + size_t initial_capacity, + rcutils_allocator_t allocator) +{ + (void) errnum; + (void) initial_capacity; + string_map = nullptr; + return RCL_RET_OK; +} + +TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rcutils_string_map_init) { + mmk_mock( + RCUTILS_STRINGIFY(rcutils_string_map_init) "@lib:rcl", + rcutils_string_map_init_mock); + + mmk_when( + rcutils_string_map_init( + mmk_any(rcutils_string_map_t *), + mmk_any(size_t), + mmk_any(rcutils_allocator_t)), + .then_return = mmk_val(rmw_ret_t, RCL_RET_ERROR)); + + rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); + const rosidl_message_type_support_t * ts = + ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); + const char * topic_name = "chatter"; + rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); + rcl_ret_t ret = + rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + rcl_reset_error(); + + // Mock the function to return RCL_RET_OK, but actually setting the string map to null + mmk_when( + rcutils_string_map_init( + mmk_any(rcutils_string_map_t *), + mmk_any(size_t), + mmk_any(rcutils_allocator_t)), + .then_call = (mmk_fn) mocked_rcutils_string_map_init) + + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + rcl_reset_error(); + + mmk_reset(rcutils_string_map_init); +} +*/ From 436d5fcec04c9ffa27f7c0ea2e05ad4303b93152 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Tue, 4 Aug 2020 18:51:37 -0300 Subject: [PATCH 14/38] Add mock test making rmw_publisher_get_actual_qos fail Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index d94cc5bdf..9d0c85b1b 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -741,3 +741,40 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rcutils_st mmk_reset(rcutils_string_map_init); } */ + +// rmw_publisher_get_actual_qos signature: +// rmw_ret_t rmw_publisher_get_actual_qos( +// const rmw_publisher_t * publisher, +// rmw_qos_profile_t * qos) + +mmk_mock_define( + rmw_publisher_get_actual_qos_mock, + rmw_ret_t, + rmw_publisher_t *, + rmw_qos_profile_t *); + +TEST_F( + CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rmw_publisher_get_actual_qos) +{ + mmk_mock( + RCUTILS_STRINGIFY(rmw_publisher_get_actual_qos) "@lib:rcl", + rmw_publisher_get_actual_qos_mock); + + mmk_when( + rmw_publisher_get_actual_qos( + mmk_any(rmw_publisher_t *), + mmk_any(rmw_qos_profile_t *)), + .then_return = mmk_val(rmw_ret_t, RMW_RET_ERROR)); + + rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); + const rosidl_message_type_support_t * ts = + ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); + const char * topic_name = "chatter"; + rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); + rcl_ret_t ret = + rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + rcl_reset_error(); + + mmk_reset(rmw_publisher_get_actual_qos); +} From 1c3ed36dbbccd0a575b871a876cab332b969638f Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Wed, 5 Aug 2020 16:37:57 -0300 Subject: [PATCH 15/38] Add class to ease mimick usage Signed-off-by: Jorge Perez --- rcl/test/mocking_utils/patch.hpp | 326 +++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 rcl/test/mocking_utils/patch.hpp diff --git a/rcl/test/mocking_utils/patch.hpp b/rcl/test/mocking_utils/patch.hpp new file mode 100644 index 000000000..4955dbe32 --- /dev/null +++ b/rcl/test/mocking_utils/patch.hpp @@ -0,0 +1,326 @@ +// Copyright 2020 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef MOCKING_UTILS__PATCH_HPP_ +#define MOCKING_UTILS__PATCH_HPP_ + +#include +#include +#include +#include + +#include "mimick/mimick.h" +#include "rcutils/macros.h" + +namespace mocking_utils +{ + +/// Mimick specific traits for each mocking_utils::Patch instance. +/** + * \tparam ID Numerical identifier of the patch. Ought to be unique. + * \tparam SignatureT Type of the symbol to be patched. +*/ +template +struct PatchTraits; + +/// Traits specialization for ReturnT(void) free functions. +/** + * \tparam ID Numerical identifier of the patch. Ought to be unique. + * \tparam ReturnT Return value type. + */ +template +struct PatchTraits +{ + mmk_mock_define(mock_type, ReturnT); +}; + +/// Traits specialization for ReturnT(ArgT0) free functions. +/** + * \tparam ID Numerical identifier of the patch. Ought to be unique. + * \tparam ReturnT Return value type. + * \tparam ArgT0 Argument type. + */ +template +struct PatchTraits +{ + mmk_mock_define(mock_type, ReturnT, ArgT0); +}; + +/// Traits specialization for ReturnT(ArgT0, ArgT1) free functions. +/** + * \tparam ID Numerical identifier of the patch. Ought to be unique. + * \tparam ReturnT Return value type. + * \tparam ArgTx Argument types. + */ +template +struct PatchTraits +{ + mmk_mock_define(mock_type, ReturnT, ArgT0, ArgT1); +}; + +/// Traits specialization for ReturnT(ArgT0, ArgT1, ArgT2) free functions. +/** + * \tparam ID Numerical identifier of the patch. Ought to be unique. + * \tparam ReturnT Return value type. + * \tparam ArgTx Argument types. + */ +template +struct PatchTraits +{ + mmk_mock_define(mock_type, ReturnT, ArgT0, ArgT1, ArgT2); +}; + +/// Traits specialization for ReturnT(ArgT0, ArgT1, ArgT2, ArgT3) free functions. +/** + * \tparam ID Numerical identifier of the patch. Ought to be unique. + * \tparam ReturnT Return value type. + * \tparam ArgTx Argument types. + */ +template +struct PatchTraits +{ + mmk_mock_define(mock_type, ReturnT, ArgT0, ArgT1, ArgT2, ArgT3); +}; + +/// Traits specialization for ReturnT(ArgT0, ArgT1, ArgT2, ArgT3, ArgT4) +/// free functions. +/** + * \tparam ID Numerical identifier of the patch. Ought to be unique. + * \tparam ReturnT Return value type. + * \tparam ArgTx Argument types. + */ +template +struct PatchTraits +{ + mmk_mock_define(mock_type, ReturnT, ArgT0, ArgT1, ArgT2, ArgT3, ArgT4); +}; + +/// Traits specialization for ReturnT(ArgT0, ArgT1, ArgT2, ArgT3, ArgT4, ArgT5) +/// free functions. +/** + * \tparam ID Numerical identifier of the patch. Ought to be unique. + * \tparam ReturnT Return value type. + * \tparam ArgTx Argument types. + */ +template +struct PatchTraits +{ + mmk_mock_define( + mock_type, ReturnT, ArgT0, ArgT1, ArgT2, ArgT3, ArgT4, ArgT5); +}; + +/// Generic trampoline to wrap generalized callables in plain functions. +/** + * \tparam ID Numerical identifier of this trampoline. Ought to be unique. + * \tparam SignatureT Type of the symbol this trampoline replaces. + */ +template +struct Trampoline; + +/// Trampoline specialization for free functions. +template +struct Trampoline +{ + static ReturnT base(ArgTs... args) + { + return target(std::forward(args)...); + } + + static std::function target; +}; + +template +std::function +Trampoline::target; + +/// Setup trampoline with the given @p target. +/** + * \param[in] target Callable that this trampoline will target. + * \return the plain base function of this trampoline. + * + * \tparam ID Numerical identifier of this trampoline. Ought to be unique. + * \tparam SignatureT Type of the symbol this trampoline replaces. + */ +template +auto prepare_trampoline(std::function target) +{ + Trampoline::target = target; + return Trampoline::base; +} + +/// Patch class for binary API mocking +/** + * Built on top of Mimick, to enable symbol mocking on a per dynamically + * linked binary object basis. + * + * \tparam ID Numerical identifier for this patch. Ought to be unique. + * \tparam SignatureT Type of the symbol to be patched. + */ +template +class Patch; + +/// Patch specialization for ReturnT(ArgTs...) free functions. +/** + * \tparam ID Numerical identifier for this patch. Ought to be unique. + * \tparam ReturnT Return value type. + * \tparam ArgTs Argument types. + */ +template +class Patch +{ +public: + using mock_type = typename PatchTraits::mock_type; + + /// Construct a patch. + /** + * \param[in] target Symbol target string, using Mimick syntax + * i.e. "symbol(@scope)?", where scope may be "self" to target the current + * binary, "lib:library_name" to target a given library, "file:path/to/library" + * to target a given file, or "sym:other_symbol" to target the first library + * that defines said symbol. + * \param[in] proxy An indirection to call the target function. + * This indirection must ensure this call goes through the function's + * trampoline, as setup by the dynamic linker. + * \return a mocking_utils::Patch instance. + */ + explicit Patch(const std::string & target, std::function proxy) + : proxy_(proxy) + { + auto MMK_MANGLE(mock_type, create) = + PatchTraits::MMK_MANGLE(mock_type, create); + mock_ = mmk_mock(target.c_str(), mock_type); + } + + // Copy construction and assignment are disabled. + Patch(const Patch &) = delete; + Patch & operator=(const Patch &) = delete; + + Patch(Patch && other) + { + mock_ = other.mock_; + other.mock_ = nullptr; + } + + Patch & operator=(Patch && other) + { + if (mock_) { + mmk_reset(mock_); + } + mock_ = other.mock_; + other.mock_ = nullptr; + } + + ~Patch() + { + if (mock_) { + mmk_reset(mock_); + } + } + + /// Inject a @p replacement for the patched function. + Patch & then_call(std::function replacement) & + { + auto type_erased_trampoline = + reinterpret_cast(prepare_trampoline(replacement)); + mmk_when(proxy_(any()...), .then_call = type_erased_trampoline); + return *this; + } + + /// Inject a @p replacement for the patched function. + Patch && then_call(std::function replacement) && + { + auto type_erased_trampoline = + reinterpret_cast(prepare_trampoline(replacement)); + mmk_when(proxy_(any()...), .then_call = type_erased_trampoline); + return std::move(*this); + } + +private: + // Helper for template parameter pack expansion using `mmk_any` + // macro as pattern. + template + T any() {return mmk_any(T);} + + mock_type mock_; + std::function proxy_; +}; + +/// Make a patch for a `target` function. +/** + * Useful for type deduction during \ref mocking_utils::Patch construction. + * + * \param[in] target Symbol target string, using Mimick syntax. + * \param[in] proxy An indirection to call the target function. + * \return a mocking_utils::Patch instance. + * + * \tparam ID Numerical identifier for this patch. Ought to be unique. + * \tparam SignatureT Type of the function to be patched. + * + * \sa mocking_utils::Patch for further reference. + */ +template +auto make_patch(const std::string & target, std::function proxy) +{ + return Patch(target, proxy); +} + +/// Define a dummy operator `op` for a given `type`. +/** + * Useful to enable patching functions that take arguments whose types + * do not define basic comparison operators, as required by Mimick. + */ +#define MOCKING_UTILS_DEFINE_DUMMY_OPERATOR(type, op) \ + bool operator op(const type &, const type &) { \ + return false; \ + } + +/// Get the exact \ref mocking_utils::Patch type for a given `id` and `function`. +/** + * Useful to avoid ignored attribute warnings when using the \b decltype operator. + */ +#define MOCKING_UTILS_PATCH_TYPE(id, function) \ + decltype(mocking_utils::make_patch("", nullptr)) + +/// A transparent forwarding proxy to a given `function`. +/** + * Useful to ensure a call to `function` goes through its trampoline. + */ +#define MOCKING_UTILS_PATCH_PROXY(function) \ + [] (auto && ... args)->decltype(auto) { \ + return function(std::forward(args)...); \ + } + +/// Compute a Mimick symbol target string based on which `function` is to be patched +/// in which `scope`. +#define MOCKING_UTILS_PATCH_TARGET(scope, function) \ + (std::string(RCUTILS_STRINGIFY(function)) + "@" + (scope)) + +/// Patch a `function` with a used-provided `replacement` in a given `scope`. +#define patch(scope, function, replacement) \ + make_patch<__COUNTER__, decltype(function)>( \ + MOCKING_UTILS_PATCH_TARGET(scope, function), MOCKING_UTILS_PATCH_PROXY(function) \ + ).then_call(replacement) + +} // namespace mocking_utils + +#endif // MOCKING_UTILS__PATCH_HPP_ From 5562953cb1007929978cdd540c17d1852dd62555 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Wed, 5 Aug 2020 17:27:47 -0300 Subject: [PATCH 16/38] Reformat tests to use helper class Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 148 ++++++-------------------------- 1 file changed, 28 insertions(+), 120 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 9d0c85b1b..89fcdbcdc 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -27,6 +27,7 @@ #include "mimick/mimick.h" #include "./publisher_impl.h" +#include "../mocking_utils/patch.hpp" #ifdef RMW_IMPLEMENTATION # define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX @@ -520,25 +521,11 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish rcl_reset_error(); } -// rmw_publisher_count_matched_subscriptions signature: -// rmw_ret_t rmw_publisher_count_matched_subscriptions ( -// const rmw_publisher_t *publisher, size_t *subscription_count) -mmk_mock_define( - rmw_publisher_count_matched_subscriptions_mock, - rmw_ret_t, - rmw_publisher_t *, - size_t *); - // Mocking rmw_publisher_count_matched_subscriptions to make // rcl_publisher_get_subscription_count fail TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publisher_count) { - mmk_mock( - RCUTILS_STRINGIFY(rmw_publisher_count_matched_subscriptions) "@lib:rcl", - rmw_publisher_count_matched_subscriptions_mock); - - mmk_when( - rmw_publisher_count_matched_subscriptions(mmk_any(rmw_publisher_t *), mmk_any(size_t *)), - .then_return = mmk_val(rmw_ret_t, RMW_RET_BAD_ALLOC)); + auto mock = mocking_utils::patch( + "lib:rcl", rmw_publisher_count_matched_subscriptions, [](auto...) {return RMW_RET_BAD_ALLOC;}); // Now normal usage of the function rcl_publisher_get_subscription_count returning // unexpected RMW_RET_BAD_ALLOC @@ -546,27 +533,13 @@ TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publis EXPECT_EQ( RCL_RET_BAD_ALLOC, rcl_publisher_get_subscription_count(&publisher, &count_size)); rcl_reset_error(); - - mmk_reset(rmw_publisher_count_matched_subscriptions); } -// rmw_publisher_assert_liveliness signature: -// rmw_ret_t rmw_publisher_assert_liveliness(const rmw_publisher_t *publisher) -mmk_mock_define( - rmw_publisher_assert_liveliness_mock, - rmw_ret_t, - rmw_publisher_t *); - // Mocking rmw_publisher_assert_liveliness to make // rcl_publisher_assert_liveliness fail TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_assert_liveliness) { - mmk_mock( - RCUTILS_STRINGIFY(rmw_publisher_assert_liveliness) "@lib:rcl", - rmw_publisher_assert_liveliness_mock); - - mmk_when( - rmw_publisher_assert_liveliness(mmk_any(rmw_publisher_t *)), - .then_return = mmk_val(rmw_ret_t, RMW_RET_ERROR)); + auto mock = mocking_utils::patch( + "lib:rcl", rmw_publisher_assert_liveliness, [](auto...) {return RMW_RET_ERROR;}); // Now normal usage of the function rcl_publisher_assert_liveliness returning // unexpected RMW_RET_ERROR @@ -574,32 +547,12 @@ TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_assert RCL_RET_ERROR, rcl_publisher_assert_liveliness(&publisher)); EXPECT_TRUE(rcl_error_is_set()); rcl_reset_error(); - - mmk_reset(rmw_publisher_assert_liveliness); } -// rmw_publish signature: -// rmw_ret_t rmw_publish( -// const rmw_publisher_t *publisher, -// const void * ros_message, -// rmw_publisher_allocation_t * allocation) -mmk_mock_define( - rmw_publish_mock, - rmw_ret_t, - rmw_publisher_t *, - void *, - rmw_publisher_allocation_t *); - // Mocking rmw_publish to make rcl_publish fail TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publish) { - mmk_mock( - RCUTILS_STRINGIFY(rmw_publish) "@lib:rcl", - rmw_publish_mock); - - mmk_when( - rmw_publish( - mmk_any(rmw_publisher_t *), mmk_any(void *), mmk_any(rmw_publisher_allocation_t *)), - .then_return = mmk_val(rmw_ret_t, RMW_RET_ERROR)); + auto mock = mocking_utils::patch( + "lib:rcl", rmw_publish, [](auto...) {return RMW_RET_ERROR;}); // Test normal usage of the function rcl_publish returning unexpected RMW_RET_ERROR test_msgs__msg__BasicTypes msg; @@ -610,39 +563,12 @@ TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publis EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; EXPECT_TRUE(rcl_error_is_set()); rcl_reset_error(); - - mmk_reset(rmw_publish); } -// rmw_publish_serialized_message signature: -// rmw_ret_t rmw_publish_serialized_message( -// const rmw_publisher_t *publisher, -// const rmw_serialized_message_t * ros_message, -// rmw_publisher_allocation_t * allocation) -mmk_mock_define( - rmw_publish_serialized_message_mock, - rmw_ret_t, - rmw_publisher_t *, - rmw_serialized_message_t *, - rmw_publisher_allocation_t *); - // Mocking rmw_publish_serialized_message to make rcl_publish_serialized_message fail TEST_F( CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publish_serialized_message) { - mmk_mock( - RCUTILS_STRINGIFY(rmw_publish_serialized_message) "@lib:rcl", - rmw_publish_serialized_message_mock); - - mmk_when( - rmw_publish_serialized_message( - mmk_any(rmw_publisher_t *), - mmk_any(rmw_serialized_message_t *), - mmk_any(rmw_publisher_allocation_t *)), - .then_return = mmk_val(rmw_ret_t, RMW_RET_ERROR)); - - // Test normal usage of the function rcl_publish_serialized_message - // returning unexpected RMW_RET_ERROR rcl_serialized_message_t serialized_msg = rmw_get_zero_initialized_serialized_message(); size_t initial_capacity_ser = 0u; rcl_allocator_t allocator = rcl_get_default_allocator(); @@ -660,24 +586,26 @@ TEST_F( ASSERT_STREQ(msg.string_value.data, test_string); ret = rmw_serialize(&msg, ts, &serialized_msg); ASSERT_EQ(RMW_RET_OK, ret); - ret = rcl_publish_serialized_message(&publisher, &serialized_msg, nullptr); - EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; - EXPECT_TRUE(rcl_error_is_set()); - rcl_reset_error(); - // Repeat, but now returning BAD_ALLOC - mmk_when( - rmw_publish_serialized_message( - mmk_any(rmw_publisher_t *), - mmk_any(rmw_serialized_message_t *), - mmk_any(rmw_publisher_allocation_t *)), - .then_return = mmk_val(rmw_ret_t, RMW_RET_BAD_ALLOC)); - ret = rcl_publish_serialized_message(&publisher, &serialized_msg, nullptr); - EXPECT_EQ(RCL_RET_BAD_ALLOC, ret) << rcl_get_error_string().str; - EXPECT_TRUE(rcl_error_is_set()); - rcl_reset_error(); - - mmk_reset(rmw_publish_serialized_message); + { + // Test normal usage of the function rcl_publish_serialized_message + // returning unexpected RMW_RET_ERROR + auto mock = mocking_utils::patch( + "lib:rcl", rmw_publish_serialized_message, [](auto...) {return RMW_RET_ERROR;}); + ret = rcl_publish_serialized_message(&publisher, &serialized_msg, nullptr); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + EXPECT_TRUE(rcl_error_is_set()); + rcl_reset_error(); + } + { + // Repeat, but now returning BAD_ALLOC + auto mock = mocking_utils::patch( + "lib:rcl", rmw_publish_serialized_message, [](auto...) {return RMW_RET_BAD_ALLOC;}); + ret = rcl_publish_serialized_message(&publisher, &serialized_msg, nullptr); + EXPECT_EQ(RCL_RET_BAD_ALLOC, ret) << rcl_get_error_string().str; + EXPECT_TRUE(rcl_error_is_set()); + rcl_reset_error(); + } } /* @@ -742,29 +670,11 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rcutils_st } */ -// rmw_publisher_get_actual_qos signature: -// rmw_ret_t rmw_publisher_get_actual_qos( -// const rmw_publisher_t * publisher, -// rmw_qos_profile_t * qos) - -mmk_mock_define( - rmw_publisher_get_actual_qos_mock, - rmw_ret_t, - rmw_publisher_t *, - rmw_qos_profile_t *); - TEST_F( CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rmw_publisher_get_actual_qos) { - mmk_mock( - RCUTILS_STRINGIFY(rmw_publisher_get_actual_qos) "@lib:rcl", - rmw_publisher_get_actual_qos_mock); - - mmk_when( - rmw_publisher_get_actual_qos( - mmk_any(rmw_publisher_t *), - mmk_any(rmw_qos_profile_t *)), - .then_return = mmk_val(rmw_ret_t, RMW_RET_ERROR)); + auto mock = mocking_utils::patch( + "lib:rcl", rmw_publisher_get_actual_qos, [](auto...) {return RMW_RET_ERROR;}); rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = @@ -775,6 +685,4 @@ TEST_F( rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; rcl_reset_error(); - - mmk_reset(rmw_publisher_get_actual_qos); } From e8094bdb68e0c8037e747d9c705ebc9ffdd87339 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Wed, 5 Aug 2020 18:17:13 -0300 Subject: [PATCH 17/38] Add mocked rcutils_string_map_init to make init fail Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 56 +++++---------------------------- 1 file changed, 7 insertions(+), 49 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 89fcdbcdc..4f0bf2252 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -608,67 +608,25 @@ TEST_F( } } -/* -// rcutils_string_map_init signature: -// rcutils_ret_t rcutils_string_map_init( -// rcutils_string_map_t * string_map, -// size_t initial_capacity, -// rcutils_allocator_t allocator); -mmk_mock_define( - rcutils_string_map_init_mock, - rcutils_ret_t, - rcutils_string_map_t *, - size_t, - rcutils_allocator_t); - -rcutils_ret_t mocked_rcutils_string_map_init( - rcutils_string_map_t * string_map, - size_t initial_capacity, - rcutils_allocator_t allocator) -{ - (void) errnum; - (void) initial_capacity; - string_map = nullptr; - return RCL_RET_OK; -} +MOCKING_UTILS_DEFINE_DUMMY_OPERATOR(rcutils_allocator_t, ==) +MOCKING_UTILS_DEFINE_DUMMY_OPERATOR(rcutils_allocator_t, <) +MOCKING_UTILS_DEFINE_DUMMY_OPERATOR(rcutils_allocator_t, >) +MOCKING_UTILS_DEFINE_DUMMY_OPERATOR(rcutils_allocator_t, !=) TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rcutils_string_map_init) { - mmk_mock( - RCUTILS_STRINGIFY(rcutils_string_map_init) "@lib:rcl", - rcutils_string_map_init_mock); - - mmk_when( - rcutils_string_map_init( - mmk_any(rcutils_string_map_t *), - mmk_any(size_t), - mmk_any(rcutils_allocator_t)), - .then_return = mmk_val(rmw_ret_t, RCL_RET_ERROR)); - rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); const char * topic_name = "chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); - rcl_ret_t ret = - rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); - EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; - rcl_reset_error(); - - // Mock the function to return RCL_RET_OK, but actually setting the string map to null - mmk_when( - rcutils_string_map_init( - mmk_any(rcutils_string_map_t *), - mmk_any(size_t), - mmk_any(rcutils_allocator_t)), - .then_call = (mmk_fn) mocked_rcutils_string_map_init) + rcl_ret_t ret = RCL_RET_OK; + auto mock = mocking_utils::patch( + "lib:rcl", rcutils_string_map_init, [](auto...) {return RCUTILS_RET_ERROR;}); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; rcl_reset_error(); - - mmk_reset(rcutils_string_map_init); } -*/ TEST_F( CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rmw_publisher_get_actual_qos) From 4591a9e38e8b9a33885c5f1fb6ccd0a4855ab182 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Thu, 6 Aug 2020 09:30:20 -0300 Subject: [PATCH 18/38] Add tests mocking loaned functions Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 80 +++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 4f0bf2252..fe30ed6ce 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -644,3 +644,83 @@ TEST_F( EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; rcl_reset_error(); } + +// Tests for loaned msgs functions. Mocked as the rmw tier1 vendors don't support it +TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_loaned_functions) { + rcl_ret_t ret; + rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); + rcl_publisher_t not_init_publisher = rcl_get_zero_initialized_publisher(); + const rosidl_message_type_support_t * ts = + ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); + const char * topic_name = "chatter"; + const char * expected_topic_name = "/chatter"; + rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( + { + rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + EXPECT_EQ(strcmp(rcl_publisher_get_topic_name(&publisher), expected_topic_name), 0); + test_msgs__msg__BasicTypes msg; + test_msgs__msg__BasicTypes__init(&msg); + msg.int64_value = 42; + void * msg_pointer = &msg; + + { + // mocked, publish nominal usage + auto mock = mocking_utils::patch( + "lib:rcl", rmw_publish_loaned_message, [](auto...) {return RMW_RET_OK;}); + EXPECT_EQ(RCL_RET_OK, rcl_publish_loaned_message(&publisher, &msg, nullptr)); + } + { + // bad params publish + EXPECT_EQ( + RCL_RET_PUBLISHER_INVALID, rcl_publish_loaned_message(nullptr, &msg, nullptr)); + EXPECT_EQ( + RCL_RET_PUBLISHER_INVALID, rcl_publish_loaned_message(¬_init_publisher, &msg, nullptr)); + EXPECT_EQ( + RCL_RET_INVALID_ARGUMENT, rcl_publish_loaned_message(&publisher, nullptr, nullptr)); + } + { + // mocked, failure publish + // NOTE: open a PR to convert rmw_loaned function returns from rmw_ret to rcl_ret type + auto mock = mocking_utils::patch( + "lib:rcl", rmw_publish_loaned_message, [](auto...) {return RMW_RET_ERROR;}); + EXPECT_EQ(RCL_RET_ERROR, rcl_publish_loaned_message(&publisher, &msg, nullptr)); + } + { + // mocked, borrow loaned nominal usage + auto mock = mocking_utils::patch( + "lib:rcl", rmw_borrow_loaned_message, [](auto...) {return RMW_RET_OK;}); + EXPECT_EQ(RCL_RET_OK, rcl_borrow_loaned_message(&publisher, ts, &msg_pointer)); + } + { + // bad params borrow loaned + EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_borrow_loaned_message(nullptr, ts, &msg_pointer)); + EXPECT_EQ( + RCL_RET_PUBLISHER_INVALID, rcl_borrow_loaned_message(¬_init_publisher, ts, &msg_pointer)); + } + { + // mocked, nominal return loaned message + auto mock = mocking_utils::patch( + "lib:rcl", rmw_return_loaned_message_from_publisher, [](auto...) {return RMW_RET_OK;}); + EXPECT_EQ(RCL_RET_OK, rcl_return_loaned_message_from_publisher(&publisher, &msg)); + } + { + // bad params return loaned message + EXPECT_EQ( + RCL_RET_PUBLISHER_INVALID, + rcl_return_loaned_message_from_publisher(nullptr, &msg)); + EXPECT_EQ( + RCL_RET_PUBLISHER_INVALID, + rcl_return_loaned_message_from_publisher(¬_init_publisher, &msg)); + EXPECT_EQ( + RCL_RET_INVALID_ARGUMENT, + rcl_return_loaned_message_from_publisher(&publisher, nullptr)); + } + + test_msgs__msg__BasicTypes__fini(&msg); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; +} From bbd023d60e765cfad45a75baa53fe8124de0dc03 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Thu, 6 Aug 2020 10:36:04 -0300 Subject: [PATCH 19/38] Add mock fail tests for publisher_init Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 85 ++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index fe30ed6ce..65a092d43 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -21,11 +21,13 @@ #include "test_msgs/msg/strings.h" #include "rosidl_runtime_c/string_functions.h" -#include "./failing_allocator_functions.hpp" +#include "mimick/mimick.h" #include "osrf_testing_tools_cpp/scope_exit.hpp" #include "rcl/error_handling.h" +#include "rmw/validate_full_topic_name.h" +#include "rmw/validate_node_name.h" -#include "mimick/mimick.h" +#include "./failing_allocator_functions.hpp" #include "./publisher_impl.h" #include "../mocking_utils/patch.hpp" @@ -724,3 +726,82 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_loaned_f test_msgs__msg__BasicTypes__fini(&msg); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; } + +TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_init) { + rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); + const rosidl_message_type_support_t * ts = + ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); + const char * topic_name = "chatter"; + rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); + rcl_ret_t ret = RCL_RET_OK; + + { + auto mock = mocking_utils::patch( + "lib:rcl", rmw_validate_node_name, [](auto...) {return RMW_RET_ERROR;}); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + rcl_reset_error(); + } + { + auto mock = mocking_utils::patch( + "lib:rcl", rmw_validate_node_name, [](auto...) {return RMW_RET_INVALID_ARGUMENT;}); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + rcl_reset_error(); + } + /* + { + auto mock = mocking_utils::patch( + "lib:rcl", rcutils_string_map_getn, [](auto...) {return NULL;}); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + EXPECT_EQ(RCL_RET_TOPIC_NAME_INVALID, ret) << rcl_get_error_string().str; + rcl_reset_error(); + } + */ + { + auto mock = mocking_utils::patch( + "lib:rcl", rcutils_string_map_fini, [](auto...) {return RCUTILS_RET_ERROR;}); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + rcl_reset_error(); + } + { + auto mock = mocking_utils::patch( + "lib:rcl", rcutils_string_map_init, [](auto...) { + static int counter = 1; + if(counter==1) { + counter++; + return RCUTILS_RET_OK; + } + // This makes rcl_remap_topic_name fail + else {return RCUTILS_RET_ERROR;} + }); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + rcl_reset_error(); + } + { + auto mock = mocking_utils::patch( + "lib:rcl", rmw_validate_full_topic_name, [](auto...) {return RMW_RET_ERROR;}); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + rcl_reset_error(); + } + { + auto mock = mocking_utils::patch( + "lib:rcl", rmw_validate_full_topic_name, [](auto...) {return RMW_RET_ERROR;}); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + rcl_reset_error(); + } + { + auto mock = mocking_utils::patch( + "lib:rcl", rmw_validate_full_topic_name, [](auto, int * result, auto) { + *result = RMW_TOPIC_INVALID_NOT_ABSOLUTE; + return RMW_RET_OK; + }); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + EXPECT_EQ(RCL_RET_TOPIC_NAME_INVALID, ret) << rcl_get_error_string().str; + rcl_reset_error(); + } +} From 145e05056368d4b368322989382a08d207e989c9 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Thu, 6 Aug 2020 10:36:43 -0300 Subject: [PATCH 20/38] Remove not working test Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 65a092d43..419215e83 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -749,15 +749,6 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_init EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; rcl_reset_error(); } - /* - { - auto mock = mocking_utils::patch( - "lib:rcl", rcutils_string_map_getn, [](auto...) {return NULL;}); - ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); - EXPECT_EQ(RCL_RET_TOPIC_NAME_INVALID, ret) << rcl_get_error_string().str; - rcl_reset_error(); - } - */ { auto mock = mocking_utils::patch( "lib:rcl", rcutils_string_map_fini, [](auto...) {return RCUTILS_RET_ERROR;}); From 5889cd4aeefc35e54ca659619bb250064a74931c Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Thu, 6 Aug 2020 11:07:04 -0300 Subject: [PATCH 21/38] Add publisher fini fail mock tests Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 43 ++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 419215e83..e647a812e 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -759,13 +759,14 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_init { auto mock = mocking_utils::patch( "lib:rcl", rcutils_string_map_init, [](auto...) { - static int counter = 1; - if(counter==1) { - counter++; - return RCUTILS_RET_OK; - } - // This makes rcl_remap_topic_name fail - else {return RCUTILS_RET_ERROR;} + static int counter = 1; + if (counter == 1) { + counter++; + return RCUTILS_RET_OK; + } else { + // This makes rcl_remap_topic_name fail + return RCUTILS_RET_ERROR; + } }); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; @@ -788,11 +789,35 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_init { auto mock = mocking_utils::patch( "lib:rcl", rmw_validate_full_topic_name, [](auto, int * result, auto) { - *result = RMW_TOPIC_INVALID_NOT_ABSOLUTE; - return RMW_RET_OK; + *result = RMW_TOPIC_INVALID_NOT_ABSOLUTE; + return RMW_RET_OK; }); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); EXPECT_EQ(RCL_RET_TOPIC_NAME_INVALID, ret) << rcl_get_error_string().str; rcl_reset_error(); } } + +// Test mocked fail fini publisher +TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_fail_publisher) { + rcl_ret_t ret; + rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); + const rosidl_message_type_support_t * ts = + ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); + const char * topic_name = "chatter"; + rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + // Leaving the scope finishing the publisher should work + OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( + { + rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + }); + { + auto mock = mocking_utils::patch( + "lib:rcl", rmw_destroy_publisher, [](auto...) {return RMW_RET_ERROR;}); + rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; + } +} From 48e64eb529d26caae5eddebb087498ce9c9e3700 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Thu, 6 Aug 2020 13:33:19 -0300 Subject: [PATCH 22/38] Add fini mocked tests, commented, failing Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index e647a812e..67d06c96f 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -808,16 +808,15 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_fail_pub rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - // Leaving the scope finishing the publisher should work - OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( - { - rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - }); + /* { auto mock = mocking_utils::patch( "lib:rcl", rmw_destroy_publisher, [](auto...) {return RMW_RET_ERROR;}); rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; } + */ + // Leaving the scope finishing the publisher should work + ret = rcl_publisher_fini(&publisher, this->node_ptr); + EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; } From 5f5c3051c1cfa36789fa266b2d41b042c4901149 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Thu, 6 Aug 2020 13:50:37 -0300 Subject: [PATCH 23/38] Add nullptr tests Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 67d06c96f..b11cc29d6 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -248,6 +248,11 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_publisher_init_ EXPECT_EQ(RCL_RET_NODE_INVALID, ret) << rcl_get_error_string().str; rcl_reset_error(); + // Pass nullptr publisher to fini + ret = rcl_publisher_fini(nullptr, this->node_ptr); + EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, ret) << rcl_get_error_string().str; + rcl_reset_error(); + // Try passing null for publisher in init. ret = rcl_publisher_init(nullptr, this->node_ptr, ts, topic_name, &default_publisher_options); EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret) << rcl_get_error_string().str; @@ -431,6 +436,14 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish rcl_reset_error(); publisher.impl->context = saved_context; + // nullptr arguments + EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_publish(&publisher, nullptr, nullptr)); + rcl_reset_error(); + EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_publish_serialized_message(&publisher, nullptr, nullptr)); + rcl_reset_error(); + EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_publisher_get_subscription_count(&publisher, nullptr)); + rcl_reset_error(); + // Change internal rmw_handle to nullptr publisher.impl->rmw_handle = nullptr; EXPECT_FALSE(rcl_publisher_is_valid_except_context(&publisher)); From 80b862107eaafbebf384a34e20a0241b1823460b Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Thu, 6 Aug 2020 13:54:58 -0300 Subject: [PATCH 24/38] Re enable failing test Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index b11cc29d6..f841496b3 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -821,14 +821,12 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_fail_pub rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - /* { auto mock = mocking_utils::patch( "lib:rcl", rmw_destroy_publisher, [](auto...) {return RMW_RET_ERROR;}); rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; } - */ // Leaving the scope finishing the publisher should work ret = rcl_publisher_fini(&publisher, this->node_ptr); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; From e0fb32d51ce69f92fe6b272e2838c33b09e7c344 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Thu, 6 Aug 2020 15:56:40 -0300 Subject: [PATCH 25/38] Update mocking utilities Signed-off-by: Jorge Perez --- rcl/test/mocking_utils/patch.hpp | 28 +++++++++++++++++++++++++--- rcl/test/rcl/test_publisher.cpp | 19 +++++++------------ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/rcl/test/mocking_utils/patch.hpp b/rcl/test/mocking_utils/patch.hpp index 4955dbe32..37442d061 100644 --- a/rcl/test/mocking_utils/patch.hpp +++ b/rcl/test/mocking_utils/patch.hpp @@ -15,6 +15,18 @@ #ifndef MOCKING_UTILS__PATCH_HPP_ #define MOCKING_UTILS__PATCH_HPP_ +#define MOCKING_UTILS_SUPPORT_VA_LIST +#if (defined(__aarch64__) || defined(__arm__) || defined(_M_ARM) || defined(__thumb__)) +// In ARM machines, va_list does not define comparison operators +// nor the compiler allows defining them via operator overloads. +// Thus, Mimick argument matching code will not compile. +#undef MOCKING_UTILS_SUPPORT_VA_LIST +#endif + +#ifdef MOCKING_UTILS_SUPPORT_VA_LIST +#include +#endif + #include #include #include @@ -288,9 +300,11 @@ auto make_patch(const std::string & target, std::function proxy) /** * Useful to enable patching functions that take arguments whose types * do not define basic comparison operators, as required by Mimick. - */ -#define MOCKING_UTILS_DEFINE_DUMMY_OPERATOR(type, op) \ - bool operator op(const type &, const type &) { \ +*/ +#define MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(type_, op) \ + template \ + typename std::enable_if::value, bool>::type \ + operator op(const T &, const T &) { \ return false; \ } @@ -323,4 +337,12 @@ auto make_patch(const std::string & target, std::function proxy) } // namespace mocking_utils +#ifdef MOCKING_UTILS_SUPPORT_VA_LIST +// Define dummy comparison operators for C standard va_list type +MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(va_list, ==) +MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(va_list, !=) +MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(va_list, <) +MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(va_list, >) +#endif + #endif // MOCKING_UTILS__PATCH_HPP_ diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index f841496b3..293afc15f 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -623,10 +623,10 @@ TEST_F( } } -MOCKING_UTILS_DEFINE_DUMMY_OPERATOR(rcutils_allocator_t, ==) -MOCKING_UTILS_DEFINE_DUMMY_OPERATOR(rcutils_allocator_t, <) -MOCKING_UTILS_DEFINE_DUMMY_OPERATOR(rcutils_allocator_t, >) -MOCKING_UTILS_DEFINE_DUMMY_OPERATOR(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, >) +MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, !=) TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rcutils_string_map_init) { rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); @@ -821,13 +821,8 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_fail_pub rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - { - auto mock = mocking_utils::patch( - "lib:rcl", rmw_destroy_publisher, [](auto...) {return RMW_RET_ERROR;}); - rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); - EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; - } - // Leaving the scope finishing the publisher should work + auto mock = mocking_utils::patch( + "lib:rcl", rmw_destroy_publisher, [](auto...) {return RMW_RET_ERROR;}); ret = rcl_publisher_fini(&publisher, this->node_ptr); - EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; } From c7de0f10e280386900e52a047505823c1739fb89 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Fri, 7 Aug 2020 10:00:49 -0300 Subject: [PATCH 26/38] Rename variable Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 293afc15f..d22ac9f1c 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -585,11 +585,11 @@ TEST_F( CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publish_serialized_message) { rcl_serialized_message_t serialized_msg = rmw_get_zero_initialized_serialized_message(); - size_t initial_capacity_ser = 0u; + size_t initial_size_serialized = 0u; rcl_allocator_t allocator = rcl_get_default_allocator(); ASSERT_EQ( RCL_RET_OK, rmw_serialized_message_init( - &serialized_msg, initial_capacity_ser, &allocator)) << rcl_get_error_string().str; + &serialized_msg, initial_size_serialized, &allocator)) << rcl_get_error_string().str; const char * test_string = "testing"; test_msgs__msg__Strings msg; test_msgs__msg__Strings__init(&msg); From d4228e45b2590faa56b971b2f50ed1a8cf2ad446 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Fri, 7 Aug 2020 10:56:18 -0300 Subject: [PATCH 27/38] Reformat with macro utility Signed-off-by: Jorge Perez --- rcl/test/mocking_utils/patch.hpp | 4 ++ rcl/test/rcl/test_publisher.cpp | 64 +++++++++++++++----------------- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/rcl/test/mocking_utils/patch.hpp b/rcl/test/mocking_utils/patch.hpp index 37442d061..2a769f402 100644 --- a/rcl/test/mocking_utils/patch.hpp +++ b/rcl/test/mocking_utils/patch.hpp @@ -335,6 +335,10 @@ auto make_patch(const std::string & target, std::function proxy) MOCKING_UTILS_PATCH_TARGET(scope, function), MOCKING_UTILS_PATCH_PROXY(function) \ ).then_call(replacement) +/// Patch a function with a function that only returns a value +#define patch_and_return(scope, function, return_value) \ + patch(scope, function, [&](auto && ...) {return return_value;}) + } // namespace mocking_utils #ifdef MOCKING_UTILS_SUPPORT_VA_LIST diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index d22ac9f1c..7b07dd92a 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -539,8 +539,8 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish // Mocking rmw_publisher_count_matched_subscriptions to make // rcl_publisher_get_subscription_count fail TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publisher_count) { - auto mock = mocking_utils::patch( - "lib:rcl", rmw_publisher_count_matched_subscriptions, [](auto...) {return RMW_RET_BAD_ALLOC;}); + auto mock = mocking_utils::patch_and_return( + "lib:rcl", rmw_publisher_count_matched_subscriptions, RMW_RET_BAD_ALLOC); // Now normal usage of the function rcl_publisher_get_subscription_count returning // unexpected RMW_RET_BAD_ALLOC @@ -553,8 +553,8 @@ TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publis // Mocking rmw_publisher_assert_liveliness to make // rcl_publisher_assert_liveliness fail TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_assert_liveliness) { - auto mock = mocking_utils::patch( - "lib:rcl", rmw_publisher_assert_liveliness, [](auto...) {return RMW_RET_ERROR;}); + auto mock = mocking_utils::patch_and_return( + "lib:rcl", rmw_publisher_assert_liveliness, RMW_RET_ERROR); // Now normal usage of the function rcl_publisher_assert_liveliness returning // unexpected RMW_RET_ERROR @@ -566,8 +566,7 @@ TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_assert // Mocking rmw_publish to make rcl_publish fail TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publish) { - auto mock = mocking_utils::patch( - "lib:rcl", rmw_publish, [](auto...) {return RMW_RET_ERROR;}); + auto mock = mocking_utils::patch_and_return("lib:rcl", rmw_publish, RMW_RET_ERROR); // Test normal usage of the function rcl_publish returning unexpected RMW_RET_ERROR test_msgs__msg__BasicTypes msg; @@ -601,12 +600,12 @@ TEST_F( ASSERT_STREQ(msg.string_value.data, test_string); ret = rmw_serialize(&msg, ts, &serialized_msg); ASSERT_EQ(RMW_RET_OK, ret); - + rmw_ret_t rmw_publish_serialized_return = RMW_RET_ERROR; + auto mock = mocking_utils::patch_and_return( + "lib:rcl", rmw_publish_serialized_message, rmw_publish_serialized_return); { // Test normal usage of the function rcl_publish_serialized_message // returning unexpected RMW_RET_ERROR - auto mock = mocking_utils::patch( - "lib:rcl", rmw_publish_serialized_message, [](auto...) {return RMW_RET_ERROR;}); ret = rcl_publish_serialized_message(&publisher, &serialized_msg, nullptr); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; EXPECT_TRUE(rcl_error_is_set()); @@ -614,8 +613,7 @@ TEST_F( } { // Repeat, but now returning BAD_ALLOC - auto mock = mocking_utils::patch( - "lib:rcl", rmw_publish_serialized_message, [](auto...) {return RMW_RET_BAD_ALLOC;}); + rmw_publish_serialized_return = RMW_RET_BAD_ALLOC; ret = rcl_publish_serialized_message(&publisher, &serialized_msg, nullptr); EXPECT_EQ(RCL_RET_BAD_ALLOC, ret) << rcl_get_error_string().str; EXPECT_TRUE(rcl_error_is_set()); @@ -636,8 +634,8 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rcutils_st rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); rcl_ret_t ret = RCL_RET_OK; - auto mock = mocking_utils::patch( - "lib:rcl", rcutils_string_map_init, [](auto...) {return RCUTILS_RET_ERROR;}); + auto mock = mocking_utils::patch_and_return( + "lib:rcl", rcutils_string_map_init, RCUTILS_RET_ERROR); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; rcl_reset_error(); @@ -646,8 +644,8 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rcutils_st TEST_F( CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rmw_publisher_get_actual_qos) { - auto mock = mocking_utils::patch( - "lib:rcl", rmw_publisher_get_actual_qos, [](auto...) {return RMW_RET_ERROR;}); + auto mock = mocking_utils::patch_and_return( + "lib:rcl", rmw_publisher_get_actual_qos, RMW_RET_ERROR); rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = @@ -685,8 +683,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_loaned_f { // mocked, publish nominal usage - auto mock = mocking_utils::patch( - "lib:rcl", rmw_publish_loaned_message, [](auto...) {return RMW_RET_OK;}); + auto mock = mocking_utils::patch_and_return("lib:rcl", rmw_publish_loaned_message, RMW_RET_OK); EXPECT_EQ(RCL_RET_OK, rcl_publish_loaned_message(&publisher, &msg, nullptr)); } { @@ -701,14 +698,13 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_loaned_f { // mocked, failure publish // NOTE: open a PR to convert rmw_loaned function returns from rmw_ret to rcl_ret type - auto mock = mocking_utils::patch( - "lib:rcl", rmw_publish_loaned_message, [](auto...) {return RMW_RET_ERROR;}); + auto mock = mocking_utils::patch_and_return( + "lib:rcl", rmw_publish_loaned_message, RMW_RET_ERROR); EXPECT_EQ(RCL_RET_ERROR, rcl_publish_loaned_message(&publisher, &msg, nullptr)); } { // mocked, borrow loaned nominal usage - auto mock = mocking_utils::patch( - "lib:rcl", rmw_borrow_loaned_message, [](auto...) {return RMW_RET_OK;}); + auto mock = mocking_utils::patch_and_return("lib:rcl", rmw_borrow_loaned_message, RMW_RET_OK); EXPECT_EQ(RCL_RET_OK, rcl_borrow_loaned_message(&publisher, ts, &msg_pointer)); } { @@ -719,8 +715,8 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_loaned_f } { // mocked, nominal return loaned message - auto mock = mocking_utils::patch( - "lib:rcl", rmw_return_loaned_message_from_publisher, [](auto...) {return RMW_RET_OK;}); + auto mock = mocking_utils::patch_and_return( + "lib:rcl", rmw_return_loaned_message_from_publisher, RMW_RET_OK); EXPECT_EQ(RCL_RET_OK, rcl_return_loaned_message_from_publisher(&publisher, &msg)); } { @@ -749,22 +745,21 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_init rcl_ret_t ret = RCL_RET_OK; { - auto mock = mocking_utils::patch( - "lib:rcl", rmw_validate_node_name, [](auto...) {return RMW_RET_ERROR;}); + auto mock = mocking_utils::patch_and_return("lib:rcl", rmw_validate_node_name, RMW_RET_ERROR); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; rcl_reset_error(); } { - auto mock = mocking_utils::patch( - "lib:rcl", rmw_validate_node_name, [](auto...) {return RMW_RET_INVALID_ARGUMENT;}); + auto mock = mocking_utils::patch_and_return( + "lib:rcl", rmw_validate_node_name, RMW_RET_INVALID_ARGUMENT); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; rcl_reset_error(); } { - auto mock = mocking_utils::patch( - "lib:rcl", rcutils_string_map_fini, [](auto...) {return RCUTILS_RET_ERROR;}); + auto mock = mocking_utils::patch_and_return( + "lib:rcl", rcutils_string_map_fini, RCUTILS_RET_ERROR); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; rcl_reset_error(); @@ -786,15 +781,15 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_init rcl_reset_error(); } { - auto mock = mocking_utils::patch( - "lib:rcl", rmw_validate_full_topic_name, [](auto...) {return RMW_RET_ERROR;}); + auto mock = mocking_utils::patch_and_return( + "lib:rcl", rmw_validate_full_topic_name, RMW_RET_ERROR); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; rcl_reset_error(); } { - auto mock = mocking_utils::patch( - "lib:rcl", rmw_validate_full_topic_name, [](auto...) {return RMW_RET_ERROR;}); + auto mock = mocking_utils::patch_and_return( + "lib:rcl", rmw_validate_full_topic_name, RMW_RET_ERROR); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; rcl_reset_error(); @@ -821,8 +816,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_fail_pub rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; - auto mock = mocking_utils::patch( - "lib:rcl", rmw_destroy_publisher, [](auto...) {return RMW_RET_ERROR;}); + auto mock = mocking_utils::patch_and_return("lib:rcl", rmw_destroy_publisher, RMW_RET_ERROR); ret = rcl_publisher_fini(&publisher, this->node_ptr); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; } From 24a0941b9d9bde64b66e5b1df1eb75e24c0e1cad Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Fri, 7 Aug 2020 11:24:52 -0300 Subject: [PATCH 28/38] Reformat test names Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 7b07dd92a..223ef131d 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -538,7 +538,10 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish // Mocking rmw_publisher_count_matched_subscriptions to make // rcl_publisher_get_subscription_count fail -TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publisher_count) { +TEST_F( + CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), + test_mock_publisher_get_subscription_count) +{ auto mock = mocking_utils::patch_and_return( "lib:rcl", rmw_publisher_count_matched_subscriptions, RMW_RET_BAD_ALLOC); @@ -626,7 +629,7 @@ 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, !=) -TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rcutils_string_map_init) { +TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_init) { rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); @@ -642,7 +645,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rcutils_st } TEST_F( - CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_rmw_publisher_get_actual_qos) + CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_init_fail_qos) { auto mock = mocking_utils::patch_and_return( "lib:rcl", rmw_publisher_get_actual_qos, RMW_RET_ERROR); @@ -659,7 +662,7 @@ TEST_F( } // Tests for loaned msgs functions. Mocked as the rmw tier1 vendors don't support it -TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_loaned_functions) { +TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_loaned_functions) { rcl_ret_t ret; rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); rcl_publisher_t not_init_publisher = rcl_get_zero_initialized_publisher(); @@ -736,7 +739,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_loaned_f ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; } -TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_init) { +TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_publisher_init) { rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); @@ -807,7 +810,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_init } // Test mocked fail fini publisher -TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocked_fail_publisher) { +TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_fini_fail) { rcl_ret_t ret; rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = From dafbc0fb24adb594eecc5dbd967424fa9e29e346 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Fri, 7 Aug 2020 17:26:43 -0300 Subject: [PATCH 29/38] Add comments for mocked tests Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 223ef131d..1431e2186 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -739,6 +739,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_loaned_fun ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; } +// Tests mocking ini/fini functions for specific failures TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_publisher_init) { rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = @@ -748,12 +749,14 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_publ rcl_ret_t ret = RCL_RET_OK; { + // Internal rmw failure validating node name auto mock = mocking_utils::patch_and_return("lib:rcl", rmw_validate_node_name, RMW_RET_ERROR); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; rcl_reset_error(); } { + // Internal rmw failure validating node name auto mock = mocking_utils::patch_and_return( "lib:rcl", rmw_validate_node_name, RMW_RET_INVALID_ARGUMENT); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); @@ -761,6 +764,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_publ rcl_reset_error(); } { + // Internal failure when fini rcutils_string_map returns error, targets substitution_map fini auto mock = mocking_utils::patch_and_return( "lib:rcl", rcutils_string_map_fini, RCUTILS_RET_ERROR); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); @@ -768,6 +772,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_publ rcl_reset_error(); } { + // Internal failure when fini rcutils_string_map returns error, targets rcl_remap_topic_name auto mock = mocking_utils::patch( "lib:rcl", rcutils_string_map_init, [](auto...) { static int counter = 1; @@ -784,6 +789,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_publ rcl_reset_error(); } { + // Internal rmw failure validating topic name auto mock = mocking_utils::patch_and_return( "lib:rcl", rmw_validate_full_topic_name, RMW_RET_ERROR); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); @@ -791,13 +797,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_publ rcl_reset_error(); } { - auto mock = mocking_utils::patch_and_return( - "lib:rcl", rmw_validate_full_topic_name, RMW_RET_ERROR); - ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); - EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; - rcl_reset_error(); - } - { + // Internal rmw failure validating node name, returns OK but the result is set to error auto mock = mocking_utils::patch( "lib:rcl", rmw_validate_full_topic_name, [](auto, int * result, auto) { *result = RMW_TOPIC_INVALID_NOT_ABSOLUTE; @@ -819,6 +819,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_ rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + // Internal rmw failure destroying publisher auto mock = mocking_utils::patch_and_return("lib:rcl", rmw_destroy_publisher, RMW_RET_ERROR); ret = rcl_publisher_fini(&publisher, this->node_ptr); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; From 98defc119eecf1e0424417347884b5f9fdbee772 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Fri, 7 Aug 2020 17:30:21 -0300 Subject: [PATCH 30/38] Add newlines to help code reading Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 1431e2186..c8a1a49eb 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -599,10 +599,12 @@ TEST_F( { test_msgs__msg__Strings__fini(&msg); }); + ASSERT_TRUE(rosidl_runtime_c__String__assign(&msg.string_value, test_string)); ASSERT_STREQ(msg.string_value.data, test_string); ret = rmw_serialize(&msg, ts, &serialized_msg); ASSERT_EQ(RMW_RET_OK, ret); + rmw_ret_t rmw_publish_serialized_return = RMW_RET_ERROR; auto mock = mocking_utils::patch_and_return( "lib:rcl", rmw_publish_serialized_message, rmw_publish_serialized_return); @@ -655,6 +657,7 @@ TEST_F( ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); const char * topic_name = "chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); + rcl_ret_t ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; @@ -671,6 +674,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_loaned_fun const char * topic_name = "chatter"; const char * expected_topic_name = "/chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); + ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( @@ -678,6 +682,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_loaned_fun rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; }); + EXPECT_EQ(strcmp(rcl_publisher_get_topic_name(&publisher), expected_topic_name), 0); test_msgs__msg__BasicTypes msg; test_msgs__msg__BasicTypes__init(&msg); @@ -819,6 +824,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_ rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; + // Internal rmw failure destroying publisher auto mock = mocking_utils::patch_and_return("lib:rcl", rmw_destroy_publisher, RMW_RET_ERROR); ret = rcl_publisher_fini(&publisher, this->node_ptr); From 06caaca3a2aaf1f754ba33911e016dcf8d908225 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Fri, 7 Aug 2020 17:50:20 -0300 Subject: [PATCH 31/38] Remove extra ret variable Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index c8a1a49eb..5ca32ae0d 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -87,7 +87,6 @@ class CLASSNAME (TestPublisherFixtureInit, RMW_IMPLEMENTATION) const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); const char * topic_name = "chatter"; - rcl_ret_t ret; rcl_publisher_t publisher; rcl_publisher_options_t publisher_options; @@ -96,7 +95,8 @@ class CLASSNAME (TestPublisherFixtureInit, RMW_IMPLEMENTATION) CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION) ::SetUp(); publisher = rcl_get_zero_initialized_publisher(); publisher_options = rcl_publisher_get_default_options(); - ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + rcl_ret_t ret = rcl_publisher_init( + &publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; } @@ -575,7 +575,7 @@ TEST_F(CLASSNAME(TestPublisherFixtureInit, RMW_IMPLEMENTATION), test_mock_publis test_msgs__msg__BasicTypes msg; test_msgs__msg__BasicTypes__init(&msg); msg.int64_value = 42; - ret = rcl_publish(&publisher, &msg, nullptr); + rcl_ret_t ret = rcl_publish(&publisher, &msg, nullptr); test_msgs__msg__BasicTypes__fini(&msg); EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str; EXPECT_TRUE(rcl_error_is_set()); @@ -602,7 +602,7 @@ TEST_F( ASSERT_TRUE(rosidl_runtime_c__String__assign(&msg.string_value, test_string)); ASSERT_STREQ(msg.string_value.data, test_string); - ret = rmw_serialize(&msg, ts, &serialized_msg); + rcl_ret_t ret = rmw_serialize(&msg, ts, &serialized_msg); ASSERT_EQ(RMW_RET_OK, ret); rmw_ret_t rmw_publish_serialized_return = RMW_RET_ERROR; @@ -666,7 +666,6 @@ TEST_F( // Tests for loaned msgs functions. Mocked as the rmw tier1 vendors don't support it TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_loaned_functions) { - rcl_ret_t ret; rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); rcl_publisher_t not_init_publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = @@ -675,11 +674,12 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_loaned_fun const char * expected_topic_name = "/chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); - ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + rcl_ret_t ret = rcl_publisher_init( + &publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( { - rcl_ret_t ret = rcl_publisher_fini(&publisher, this->node_ptr); + ret = rcl_publisher_fini(&publisher, this->node_ptr); EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; }); @@ -816,13 +816,13 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_publ // Test mocked fail fini publisher TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_fini_fail) { - rcl_ret_t ret; rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); const char * topic_name = "chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); - ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); + rcl_ret_t ret = rcl_publisher_init( + &publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; // Internal rmw failure destroying publisher From 5ed77be18ca1db062d0b1724d21c015118322626 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Fri, 7 Aug 2020 17:54:03 -0300 Subject: [PATCH 32/38] Check count_size value after test Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 5ca32ae0d..a6f00d5eb 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -547,9 +547,10 @@ TEST_F( // Now normal usage of the function rcl_publisher_get_subscription_count returning // unexpected RMW_RET_BAD_ALLOC - size_t count_size; + size_t count_size = 2u; EXPECT_EQ( RCL_RET_BAD_ALLOC, rcl_publisher_get_subscription_count(&publisher, &count_size)); + EXPECT_EQ(2u, count_size); rcl_reset_error(); } From 5df381f4b39cd2e41d43ffb609d0a91f4e181679 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Fri, 7 Aug 2020 18:17:37 -0300 Subject: [PATCH 33/38] Reformat to use constexpr where possible Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index a6f00d5eb..3497d60b6 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -61,7 +61,7 @@ class CLASSNAME (TestPublisherFixture, RMW_IMPLEMENTATION) : public ::testing::T } this->node_ptr = new rcl_node_t; *this->node_ptr = rcl_get_zero_initialized_node(); - const char * name = "test_publisher_node"; + constexpr char name[] = "test_publisher_node"; rcl_node_options_t node_options = rcl_node_get_default_options(); ret = rcl_node_init(this->node_ptr, name, "", this->context_ptr, &node_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; @@ -115,8 +115,8 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_publisher_nomin rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); - const char * topic_name = "chatter"; - const char * expected_topic_name = "/chatter"; + constexpr char topic_name[] = "chatter"; + constexpr char expected_topic_name[] = "/chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; @@ -141,7 +141,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_publisher_nomin rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); - const char * topic_name = "chatter"; + constexpr char topic_name[] = "chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; @@ -219,7 +219,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_publisher_init_ rcl_publisher_t publisher; const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); - const char * topic_name = "chatter"; + constexpr char topic_name[] = "chatter"; rcl_publisher_options_t default_publisher_options = rcl_publisher_get_default_options(); // Check if null publisher is valid @@ -342,7 +342,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_publisher_loan) rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); - const char * topic_name = "chatter"; + constexpr char topic_name[] = "chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); rcl_ret_t ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); @@ -374,7 +374,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); - const char * topic_name = "chatter"; + constexpr char topic_name[] = "chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); rcl_ret_t ret = rcl_publisher_init(&publisher, this->node_ptr, ts, topic_name, &publisher_options); @@ -593,7 +593,7 @@ TEST_F( ASSERT_EQ( RCL_RET_OK, rmw_serialized_message_init( &serialized_msg, initial_size_serialized, &allocator)) << rcl_get_error_string().str; - const char * test_string = "testing"; + constexpr char test_string[] = "testing"; test_msgs__msg__Strings msg; test_msgs__msg__Strings__init(&msg); OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT( @@ -636,7 +636,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_ rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); - const char * topic_name = "chatter"; + constexpr char topic_name[] = "chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); rcl_ret_t ret = RCL_RET_OK; @@ -656,7 +656,7 @@ TEST_F( rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); - const char * topic_name = "chatter"; + constexpr char topic_name[] = "chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); rcl_ret_t ret = @@ -671,8 +671,8 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_loaned_fun rcl_publisher_t not_init_publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); - const char * topic_name = "chatter"; - const char * expected_topic_name = "/chatter"; + constexpr char topic_name[] = "chatter"; + constexpr char expected_topic_name[] = "/chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); rcl_ret_t ret = rcl_publisher_init( @@ -750,7 +750,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mocks_fail_publ rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, Strings); - const char * topic_name = "chatter"; + constexpr char topic_name[] = "chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); rcl_ret_t ret = RCL_RET_OK; @@ -820,7 +820,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_publisher_ rcl_publisher_t publisher = rcl_get_zero_initialized_publisher(); const rosidl_message_type_support_t * ts = ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes); - const char * topic_name = "chatter"; + constexpr char topic_name[] = "chatter"; rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options(); rcl_ret_t ret = rcl_publisher_init( &publisher, this->node_ptr, ts, topic_name, &publisher_options); From 641da425aeaaac932cb2b87d02e3e95eefef888e Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Fri, 7 Aug 2020 18:22:29 -0300 Subject: [PATCH 34/38] Add comment explain dummy operators Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 3497d60b6..73f2cccee 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -627,6 +627,8 @@ TEST_F( } } +// Define dummy comparison operators for rcutils_allocator_t type to be able of being +// used with 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, >) From ac2f6a1173679771fd02210cbac369ace17f00a3 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Fri, 7 Aug 2020 18:33:06 -0300 Subject: [PATCH 35/38] Add variable making clear bad param test Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 34 ++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 73f2cccee..290d01166 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -408,6 +408,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish rcl_publisher_impl_t * saved_impl = publisher.impl; rcl_context_t * saved_context = publisher.impl->context; rmw_publisher_t * saved_rmw_handle = publisher.impl->rmw_handle; + rmw_publisher_allocation_t * null_allocation_is_valid_arg = nullptr; // Change internal context to nullptr publisher.impl->context = nullptr; @@ -428,18 +429,21 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish rcl_reset_error(); EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_publisher_assert_liveliness(&publisher)); rcl_reset_error(); - EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_publish(&publisher, &msg, nullptr)); + EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_publish(&publisher, &msg, null_allocation_is_valid_arg)); rcl_reset_error(); EXPECT_EQ( RCL_RET_PUBLISHER_INVALID, - rcl_publish_serialized_message(&publisher, &serialized_msg, nullptr)); + rcl_publish_serialized_message(&publisher, &serialized_msg, null_allocation_is_valid_arg)); rcl_reset_error(); publisher.impl->context = saved_context; // nullptr arguments - EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_publish(&publisher, nullptr, nullptr)); + EXPECT_EQ( + RCL_RET_INVALID_ARGUMENT, rcl_publish(&publisher, nullptr, null_allocation_is_valid_arg)); rcl_reset_error(); - EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_publish_serialized_message(&publisher, nullptr, nullptr)); + EXPECT_EQ( + RCL_RET_INVALID_ARGUMENT, + rcl_publish_serialized_message(&publisher, nullptr, null_allocation_is_valid_arg)); rcl_reset_error(); EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_publisher_get_subscription_count(&publisher, nullptr)); rcl_reset_error(); @@ -467,11 +471,11 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish rcl_reset_error(); EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_publisher_assert_liveliness(&publisher)); rcl_reset_error(); - EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_publish(&publisher, &msg, nullptr)); + EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_publish(&publisher, &msg, null_allocation_is_valid_arg)); rcl_reset_error(); EXPECT_EQ( RCL_RET_PUBLISHER_INVALID, - rcl_publish_serialized_message(&publisher, &serialized_msg, nullptr)); + rcl_publish_serialized_message(&publisher, &serialized_msg, null_allocation_is_valid_arg)); rcl_reset_error(); publisher.impl->rmw_handle = saved_rmw_handle; @@ -498,11 +502,11 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish rcl_reset_error(); EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_publisher_assert_liveliness(&publisher)); rcl_reset_error(); - EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_publish(&publisher, &msg, nullptr)); + EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_publish(&publisher, &msg, null_allocation_is_valid_arg)); rcl_reset_error(); EXPECT_EQ( RCL_RET_PUBLISHER_INVALID, - rcl_publish_serialized_message(&publisher, &serialized_msg, nullptr)); + rcl_publish_serialized_message(&publisher, &serialized_msg, null_allocation_is_valid_arg)); rcl_reset_error(); publisher.impl = saved_impl; @@ -528,11 +532,11 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_invalid_publish rcl_reset_error(); EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_publisher_assert_liveliness(nullptr)); rcl_reset_error(); - EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_publish(nullptr, &msg, nullptr)); + EXPECT_EQ(RCL_RET_PUBLISHER_INVALID, rcl_publish(nullptr, &msg, null_allocation_is_valid_arg)); rcl_reset_error(); EXPECT_EQ( RCL_RET_PUBLISHER_INVALID, - rcl_publish_serialized_message(nullptr, &serialized_msg, nullptr)); + rcl_publish_serialized_message(nullptr, &serialized_msg, null_allocation_is_valid_arg)); rcl_reset_error(); } @@ -691,6 +695,7 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_loaned_fun test_msgs__msg__BasicTypes__init(&msg); msg.int64_value = 42; void * msg_pointer = &msg; + rmw_publisher_allocation_t * null_allocation_is_valid_arg = nullptr; { // mocked, publish nominal usage @@ -700,11 +705,14 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_loaned_fun { // bad params publish EXPECT_EQ( - RCL_RET_PUBLISHER_INVALID, rcl_publish_loaned_message(nullptr, &msg, nullptr)); + RCL_RET_PUBLISHER_INVALID, + rcl_publish_loaned_message(nullptr, &msg, null_allocation_is_valid_arg)); EXPECT_EQ( - RCL_RET_PUBLISHER_INVALID, rcl_publish_loaned_message(¬_init_publisher, &msg, nullptr)); + RCL_RET_PUBLISHER_INVALID, + rcl_publish_loaned_message(¬_init_publisher, &msg, null_allocation_is_valid_arg)); EXPECT_EQ( - RCL_RET_INVALID_ARGUMENT, rcl_publish_loaned_message(&publisher, nullptr, nullptr)); + RCL_RET_INVALID_ARGUMENT, + rcl_publish_loaned_message(&publisher, nullptr, null_allocation_is_valid_arg)); } { // mocked, failure publish From 0f3c6a4da710a0e6085032fc6cfa6415935953af Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Fri, 7 Aug 2020 18:38:55 -0300 Subject: [PATCH 36/38] Remove NOTE, tracked by #735 Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 290d01166..6cc3415e5 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -716,7 +716,6 @@ TEST_F(CLASSNAME(TestPublisherFixture, RMW_IMPLEMENTATION), test_mock_loaned_fun } { // mocked, failure publish - // NOTE: open a PR to convert rmw_loaned function returns from rmw_ret to rcl_ret type auto mock = mocking_utils::patch_and_return( "lib:rcl", rmw_publish_loaned_message, RMW_RET_ERROR); EXPECT_EQ(RCL_RET_ERROR, rcl_publish_loaned_message(&publisher, &msg, nullptr)); From 8f4c91ac27653ed36a9f87d5877b3b9b735e5dbc Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Mon, 10 Aug 2020 09:39:33 -0300 Subject: [PATCH 37/38] Reword comment Signed-off-by: Jorge Perez --- rcl/test/rcl/test_publisher.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rcl/test/rcl/test_publisher.cpp b/rcl/test/rcl/test_publisher.cpp index 6cc3415e5..c536f9242 100644 --- a/rcl/test/rcl/test_publisher.cpp +++ b/rcl/test/rcl/test_publisher.cpp @@ -631,8 +631,7 @@ TEST_F( } } -// Define dummy comparison operators for rcutils_allocator_t type to be able of being -// used with Mimick library +// 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, >) From 0e986e36624fb0958701da4820d26fabc3bf94e2 Mon Sep 17 00:00:00 2001 From: Jorge Perez Date: Mon, 10 Aug 2020 09:51:06 -0300 Subject: [PATCH 38/38] Add link to original file to help tracking changes Signed-off-by: Jorge Perez --- rcl/test/mocking_utils/patch.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rcl/test/mocking_utils/patch.hpp b/rcl/test/mocking_utils/patch.hpp index 2a769f402..544dec27a 100644 --- a/rcl/test/mocking_utils/patch.hpp +++ b/rcl/test/mocking_utils/patch.hpp @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Original file taken from: +// https://github.com/ros2/rcutils/blob/master/test/mocking_utils/patch.hpp + #ifndef MOCKING_UTILS__PATCH_HPP_ #define MOCKING_UTILS__PATCH_HPP_