Add coverage tests 94% service.c (#756)
* Add tests for fail init * Add fini tests * Add tests rcl_take_request_with_info * Add tests send_response * Change const strings to constexpr * Improve test descriptions * Remove test Signed-off-by: Jorge Perez <jjperez@ekumenlabs.com>
This commit is contained in:
parent
04210ebdc2
commit
6d95545a9f
3 changed files with 207 additions and 2 deletions
|
@ -111,7 +111,6 @@ rcl_service_init(
|
|||
RCL_SET_ERROR_MSG(rcutils_get_error_string().str);
|
||||
ret = RCL_RET_ERROR;
|
||||
goto cleanup;
|
||||
return RCL_RET_ERROR;
|
||||
}
|
||||
if (ret != RCL_RET_OK) {
|
||||
if (ret == RCL_RET_TOPIC_NAME_INVALID || ret == RCL_RET_UNKNOWN_SUBSTITUTION) {
|
||||
|
|
|
@ -217,7 +217,7 @@ function(test_target_function)
|
|||
SRCS rcl/test_service.cpp rcl/wait_for_entity_helpers.cpp
|
||||
ENV ${rmw_implementation_env_var}
|
||||
APPEND_LIBRARY_DIRS ${extra_lib_dirs}
|
||||
LIBRARIES ${PROJECT_NAME}
|
||||
LIBRARIES ${PROJECT_NAME} mimick
|
||||
AMENT_DEPENDENCIES ${rmw_implementation} "osrf_testing_tools_cpp" "test_msgs"
|
||||
)
|
||||
|
||||
|
|
|
@ -21,8 +21,11 @@
|
|||
|
||||
#include "osrf_testing_tools_cpp/scope_exit.hpp"
|
||||
#include "rcl/error_handling.h"
|
||||
#include "rmw/validate_namespace.h"
|
||||
|
||||
#include "wait_for_entity_helpers.hpp"
|
||||
#include "./allocator_testing_utils.h"
|
||||
#include "../mocking_utils/patch.hpp"
|
||||
|
||||
#ifdef RMW_IMPLEMENTATION
|
||||
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
|
||||
|
@ -420,3 +423,206 @@ TEST_F(CLASSNAME(TestServiceFixture, RMW_IMPLEMENTATION), test_service_fail_name
|
|||
EXPECT_EQ(RCL_RET_SERVICE_NAME_INVALID, ret) << rcl_get_error_string().str;
|
||||
rcl_reset_error();
|
||||
}
|
||||
|
||||
// Define dummy comparison operators for rcutils_allocator_t type for use with the Mimick Library
|
||||
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, ==)
|
||||
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, <)
|
||||
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, >)
|
||||
MOCKING_UTILS_BOOL_OPERATOR_RETURNS_FALSE(rcutils_allocator_t, !=)
|
||||
|
||||
/* Test failed service initialization using mocks
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestServiceFixture, RMW_IMPLEMENTATION), test_fail_ini_mocked) {
|
||||
const rosidl_service_type_support_t * ts = ROSIDL_GET_SRV_TYPE_SUPPORT(
|
||||
test_msgs, srv, BasicTypes);
|
||||
constexpr char topic[] = "topic";
|
||||
rcl_service_t service = rcl_get_zero_initialized_service();
|
||||
rcl_service_options_t service_options = rcl_service_get_default_options();
|
||||
service_options.qos.durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
|
||||
rcl_ret_t ret = RCL_RET_OK;
|
||||
|
||||
{
|
||||
auto mock = mocking_utils::patch_and_return(
|
||||
"lib:rcl", rcutils_string_map_init, RCUTILS_RET_ERROR);
|
||||
ret = rcl_service_init(&service, this->node_ptr, ts, topic, &service_options);
|
||||
EXPECT_EQ(RCL_RET_ERROR, ret);
|
||||
EXPECT_TRUE(rcl_error_is_set());
|
||||
rcl_reset_error();
|
||||
}
|
||||
{
|
||||
// Mocking this function causes rcl_expand_topic_name to return RCL_RET_ERROR
|
||||
auto mock = mocking_utils::patch_and_return(
|
||||
"lib:rcl", rmw_validate_namespace, RMW_RET_ERROR);
|
||||
ret = rcl_service_init(&service, this->node_ptr, ts, topic, &service_options);
|
||||
EXPECT_EQ(RCL_RET_ERROR, ret);
|
||||
EXPECT_TRUE(rcl_error_is_set());
|
||||
rcl_reset_error();
|
||||
}
|
||||
{
|
||||
auto mock = mocking_utils::inject_on_return(
|
||||
"lib:rcl", rcutils_string_map_fini, RCUTILS_RET_ERROR);
|
||||
ret = rcl_service_init(&service, this->node_ptr, ts, topic, &service_options);
|
||||
EXPECT_EQ(RCL_RET_ERROR, ret);
|
||||
}
|
||||
{
|
||||
auto mock = mocking_utils::patch_and_return(
|
||||
"lib:rcl", rmw_validate_full_topic_name, RMW_RET_ERROR);
|
||||
ret = rcl_service_init(&service, this->node_ptr, ts, topic, &service_options);
|
||||
EXPECT_EQ(RCL_RET_ERROR, ret);
|
||||
EXPECT_TRUE(rcl_error_is_set());
|
||||
rcl_reset_error();
|
||||
}
|
||||
{
|
||||
auto mock = mocking_utils::patch(
|
||||
"lib:rcl", rmw_validate_full_topic_name,
|
||||
[](auto, int * result, auto) {
|
||||
*result = RMW_TOPIC_INVALID_IS_EMPTY_STRING;
|
||||
return RMW_RET_OK;
|
||||
});
|
||||
ret = rcl_service_init(&service, this->node_ptr, ts, topic, &service_options);
|
||||
EXPECT_EQ(RCL_RET_SERVICE_NAME_INVALID, ret);
|
||||
EXPECT_TRUE(rcl_error_is_set());
|
||||
rcl_reset_error();
|
||||
}
|
||||
{
|
||||
auto mock = mocking_utils::patch_and_return(
|
||||
"lib:rcl", rmw_create_service, nullptr);
|
||||
ret = rcl_service_init(&service, this->node_ptr, ts, topic, &service_options);
|
||||
EXPECT_EQ(RCL_RET_ERROR, ret);
|
||||
EXPECT_TRUE(rcl_error_is_set());
|
||||
rcl_reset_error();
|
||||
}
|
||||
}
|
||||
|
||||
/* Test failed service finalization using mocks
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestServiceFixture, RMW_IMPLEMENTATION), test_fail_fini_mocked) {
|
||||
const rosidl_service_type_support_t * ts = ROSIDL_GET_SRV_TYPE_SUPPORT(
|
||||
test_msgs, srv, BasicTypes);
|
||||
constexpr char topic[] = "primitives";
|
||||
|
||||
rcl_service_t service = rcl_get_zero_initialized_service();
|
||||
rcl_service_options_t service_options = rcl_service_get_default_options();
|
||||
rcl_ret_t ret = rcl_service_init(&service, this->node_ptr, ts, topic, &service_options);
|
||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
|
||||
rcl_service_t empty_service = rcl_get_zero_initialized_service();
|
||||
ret = rcl_service_fini(&empty_service, this->node_ptr);
|
||||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
|
||||
auto mock = mocking_utils::inject_on_return(
|
||||
"lib:rcl", rmw_destroy_service, RMW_RET_ERROR);
|
||||
ret = rcl_service_fini(&service, this->node_ptr);
|
||||
EXPECT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
|
||||
EXPECT_TRUE(rcl_error_is_set());
|
||||
rcl_reset_error();
|
||||
}
|
||||
|
||||
/* Test failed service take_request_with_info using mocks and nullptrs
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestServiceFixture, RMW_IMPLEMENTATION), test_fail_take_request_with_info) {
|
||||
const rosidl_service_type_support_t * ts = ROSIDL_GET_SRV_TYPE_SUPPORT(
|
||||
test_msgs, srv, BasicTypes);
|
||||
constexpr char topic[] = "primitives";
|
||||
|
||||
rcl_service_t service = rcl_get_zero_initialized_service();
|
||||
rcl_service_options_t service_options = rcl_service_get_default_options();
|
||||
rcl_ret_t ret = rcl_service_init(&service, this->node_ptr, ts, topic, &service_options);
|
||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
|
||||
{
|
||||
rcl_ret_t ret = rcl_service_fini(&service, this->node_ptr);
|
||||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
});
|
||||
|
||||
test_msgs__srv__BasicTypes_Request service_request;
|
||||
test_msgs__srv__BasicTypes_Request__init(&service_request);
|
||||
rmw_service_info_t header;
|
||||
|
||||
ret = rcl_take_request_with_info(nullptr, &header, &service_request);
|
||||
EXPECT_EQ(RCL_RET_SERVICE_INVALID, ret);
|
||||
EXPECT_TRUE(rcl_error_is_set());
|
||||
rcl_reset_error();
|
||||
|
||||
ret = rcl_take_request_with_info(&service, nullptr, &service_request);
|
||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||
EXPECT_TRUE(rcl_error_is_set());
|
||||
rcl_reset_error();
|
||||
|
||||
ret = rcl_take_request_with_info(&service, &header, nullptr);
|
||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||
EXPECT_TRUE(rcl_error_is_set());
|
||||
rcl_reset_error();
|
||||
|
||||
{
|
||||
auto mock = mocking_utils::patch_and_return(
|
||||
"lib:rcl", rmw_take_request, RMW_RET_ERROR);
|
||||
ret = rcl_take_request_with_info(&service, &header, &service_request);
|
||||
EXPECT_EQ(RCL_RET_ERROR, ret);
|
||||
EXPECT_TRUE(rcl_error_is_set());
|
||||
rcl_reset_error();
|
||||
}
|
||||
{
|
||||
auto mock = mocking_utils::patch_and_return(
|
||||
"lib:rcl", rmw_take_request, RMW_RET_BAD_ALLOC);
|
||||
ret = rcl_take_request_with_info(&service, &header, &service_request);
|
||||
EXPECT_EQ(RCL_RET_BAD_ALLOC, ret);
|
||||
EXPECT_TRUE(rcl_error_is_set());
|
||||
rcl_reset_error();
|
||||
}
|
||||
{
|
||||
auto mock = mocking_utils::patch(
|
||||
"lib:rcl", rmw_take_request,
|
||||
[](auto, auto, auto, bool * taken) {
|
||||
*taken = false;
|
||||
return RMW_RET_OK;
|
||||
});
|
||||
ret = rcl_take_request_with_info(&service, &header, &service_request);
|
||||
EXPECT_EQ(RCL_RET_SERVICE_TAKE_FAILED, ret);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test failed service send_response using mocks and nullptrs
|
||||
*/
|
||||
TEST_F(CLASSNAME(TestServiceFixture, RMW_IMPLEMENTATION), test_fail_send_response) {
|
||||
const rosidl_service_type_support_t * ts = ROSIDL_GET_SRV_TYPE_SUPPORT(
|
||||
test_msgs, srv, BasicTypes);
|
||||
constexpr char topic[] = "primitives";
|
||||
|
||||
rcl_service_t service = rcl_get_zero_initialized_service();
|
||||
rcl_service_options_t service_options = rcl_service_get_default_options();
|
||||
rcl_ret_t ret = rcl_service_init(&service, this->node_ptr, ts, topic, &service_options);
|
||||
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
|
||||
{
|
||||
rcl_ret_t ret = rcl_service_fini(&service, this->node_ptr);
|
||||
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
|
||||
});
|
||||
|
||||
// Init dummy response.
|
||||
test_msgs__srv__BasicTypes_Response service_response;
|
||||
test_msgs__srv__BasicTypes_Response__init(&service_response);
|
||||
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
|
||||
{
|
||||
test_msgs__srv__BasicTypes_Response__fini(&service_response);
|
||||
});
|
||||
rmw_service_info_t header;
|
||||
|
||||
ret = rcl_send_response(nullptr, &header.request_id, &service_response);
|
||||
EXPECT_EQ(RCL_RET_SERVICE_INVALID, ret);
|
||||
|
||||
ret = rcl_send_response(&service, nullptr, &service_response);
|
||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||
|
||||
ret = rcl_send_response(&service, &header.request_id, nullptr);
|
||||
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, ret);
|
||||
|
||||
{
|
||||
auto mock = mocking_utils::patch_and_return(
|
||||
"lib:rcl", rmw_send_response, RMW_RET_ERROR);
|
||||
ret = rcl_send_response(&service, &header.request_id, &service_response);
|
||||
EXPECT_EQ(RCL_RET_ERROR, ret);
|
||||
EXPECT_TRUE(rcl_error_is_set());
|
||||
rcl_reset_error();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue