Skip to content

Commit

Permalink
Bump test coverage.
Browse files Browse the repository at this point in the history
* init/shutdown API
* context fini API
* node init/fini API
* guard condition init/fini API
* security APIs

Signed-off-by: Michel Hidalgo <michel@ekumenlabs.com>
  • Loading branch information
hidmic committed Aug 25, 2020
1 parent 0980f88 commit 2147c7f
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 6 deletions.
8 changes: 4 additions & 4 deletions rcl/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ function(test_target_function)
SRCS rcl/test_context.cpp
ENV ${rmw_implementation_env_var} ${memory_tools_ld_preload_env_var}
APPEND_LIBRARY_DIRS ${extra_lib_dirs}
LIBRARIES ${PROJECT_NAME} osrf_testing_tools_cpp::memory_tools
LIBRARIES ${PROJECT_NAME} mimick osrf_testing_tools_cpp::memory_tools
AMENT_DEPENDENCIES ${rmw_implementation}
)

Expand Down Expand Up @@ -166,7 +166,7 @@ function(test_target_function)
SRCS rcl/test_node.cpp
ENV ${rmw_implementation_env_var} ${memory_tools_ld_preload_env_var}
APPEND_LIBRARY_DIRS ${extra_lib_dirs}
LIBRARIES ${PROJECT_NAME} osrf_testing_tools_cpp::memory_tools
LIBRARIES ${PROJECT_NAME} mimick osrf_testing_tools_cpp::memory_tools
AMENT_DEPENDENCIES ${rmw_implementation} "osrf_testing_tools_cpp"
)

Expand Down Expand Up @@ -201,7 +201,7 @@ function(test_target_function)
SRCS rcl/test_guard_condition.cpp
ENV ${rmw_implementation_env_var} ${memory_tools_ld_preload_env_var}
APPEND_LIBRARY_DIRS ${extra_lib_dirs}
LIBRARIES ${PROJECT_NAME} osrf_testing_tools_cpp::memory_tools
LIBRARIES ${PROJECT_NAME} mimick osrf_testing_tools_cpp::memory_tools
AMENT_DEPENDENCIES ${rmw_implementation} "osrf_testing_tools_cpp"
)

Expand Down Expand Up @@ -392,7 +392,7 @@ rcl_add_custom_gtest(test_expand_topic_name
rcl_add_custom_gtest(test_security
SRCS rcl/test_security.cpp
APPEND_LIBRARY_DIRS ${extra_lib_dirs}
LIBRARIES ${PROJECT_NAME}
LIBRARIES ${PROJECT_NAME} mimick
AMENT_DEPENDENCIES "osrf_testing_tools_cpp"
)

Expand Down
12 changes: 10 additions & 2 deletions rcl/test/rcl/test_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
#include "rcl/error_handling.h"
#include "rcl/init.h"

#include "rmw/rmw.h"

#include "../mocking_utils/patch.hpp"

#ifdef RMW_IMPLEMENTATION
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
# define CLASSNAME(NAME, SUFFIX) CLASSNAME_(NAME, SUFFIX)
Expand Down Expand Up @@ -170,6 +174,10 @@ TEST_F(CLASSNAME(TestContextFixture, RMW_IMPLEMENTATION), bad_fini) {
ret = rcl_shutdown(&context);
EXPECT_EQ(ret, RCL_RET_OK);

ret = rcl_context_fini(&context);
EXPECT_EQ(ret, RCL_RET_OK);
{
auto mock = mocking_utils::inject_on_return(
"lib:rcl", rmw_context_fini, RMW_RET_ERROR);
EXPECT_EQ(RCL_RET_ERROR, rcl_context_fini(&context));
rcl_reset_error();
}
}
24 changes: 24 additions & 0 deletions rcl/test/rcl/test_guard_condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
#include "osrf_testing_tools_cpp/scope_exit.hpp"
#include "rcl/error_handling.h"

#include "rmw/rmw.h"

#include "../mocking_utils/patch.hpp"

#ifdef RMW_IMPLEMENTATION
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
# define CLASSNAME(NAME, SUFFIX) CLASSNAME_(NAME, SUFFIX)
Expand Down Expand Up @@ -188,6 +192,14 @@ TEST_F(
ASSERT_EQ(RCL_RET_BAD_ALLOC, ret) << "Expected RCL_RET_BAD_ALLOC";
ASSERT_TRUE(rcl_error_is_set());
rcl_reset_error();
// Try init but force an internal error.
{
auto mock = mocking_utils::patch_to_fail(
"lib:rcl", rmw_create_guard_condition, "internal error", nullptr);
ret = rcl_guard_condition_init(&guard_condition, &context, default_options);
EXPECT_EQ(RCL_RET_ERROR, ret);
rcl_reset_error();
}

// Try fini with invalid arguments.
ret = rcl_guard_condition_fini(nullptr);
Expand All @@ -202,6 +214,18 @@ TEST_F(
EXPECT_EQ(RCL_RET_OK, ret);
ret = rcl_guard_condition_fini(&guard_condition);
EXPECT_EQ(RCL_RET_OK, ret);
// Try normal init and fini, but force an internal error on first try.
{
auto mock = mocking_utils::inject_on_return(
"lib:rcl", rmw_destroy_guard_condition, RMW_RET_ERROR);
ret = rcl_guard_condition_init(&guard_condition, &context, default_options);
EXPECT_EQ(RCL_RET_OK, ret);
ret = rcl_guard_condition_fini(&guard_condition);
EXPECT_EQ(RCL_RET_ERROR, ret);
rcl_reset_error();
}
ret = rcl_guard_condition_fini(&guard_condition);
EXPECT_EQ(RCL_RET_OK, ret);
// Try repeated init and fini calls.
ret = rcl_guard_condition_init(&guard_condition, &context, default_options);
EXPECT_EQ(RCL_RET_OK, ret);
Expand Down
50 changes: 50 additions & 0 deletions rcl/test/rcl/test_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "rcutils/format_string.h"
#include "rcutils/snprintf.h"

#include "rmw/rmw.h"

#include "./allocator_testing_utils.h"
#include "../mocking_utils/patch.hpp"
#include "../src/rcl/init_options_impl.h"
Expand Down Expand Up @@ -316,6 +318,54 @@ TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_and_shutdown
context = rcl_get_zero_initialized_context();
}

/* Tests rcl_init() deals with internal errors correctly.
*/
TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_init_internal_error) {
rcl_init_options_t init_options = rcl_get_zero_initialized_init_options();
rcl_ret_t ret = rcl_init_options_init(&init_options, rcl_get_default_allocator());
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
{
EXPECT_EQ(RCL_RET_OK, rcl_init_options_fini(&init_options)) << rcl_get_error_string().str;
});
rcl_context_t context = rcl_get_zero_initialized_context();

auto mock = mocking_utils::patch_to_fail(
"lib:rcl", rmw_init, "internal error", RMW_RET_ERROR);

FakeTestArgv test_args;
ret = rcl_init(test_args.argc, test_args.argv, &init_options, &context);
EXPECT_EQ(RCL_RET_ERROR, ret);
rcl_reset_error();
}

/* Tests rcl_shutdown() deals with internal errors correctly.
*/
TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_shutdown_internal_error) {
rcl_init_options_t init_options = rcl_get_zero_initialized_init_options();
rcl_ret_t ret = rcl_init_options_init(&init_options, rcl_get_default_allocator());
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
{
EXPECT_EQ(RCL_RET_OK, rcl_init_options_fini(&init_options)) << rcl_get_error_string().str;
});
rcl_context_t context = rcl_get_zero_initialized_context();

ret = rcl_init(0, nullptr, &init_options, &context);
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
{
EXPECT_EQ(RCL_RET_OK, rcl_shutdown(&context)) << rcl_get_error_string().str;
EXPECT_EQ(RCL_RET_OK, rcl_context_fini(&context)) << rcl_get_error_string().str;
});
EXPECT_TRUE(rcl_context_is_valid(&context));

auto mock = mocking_utils::patch_to_fail(
"lib:rcl", rmw_shutdown, "internal error", RMW_RET_ERROR);
EXPECT_EQ(RCL_RET_ERROR, rcl_shutdown(&context));
rcl_reset_error();
}

/* Tests the rcl_get_instance_id() function.
*/
TEST_F(CLASSNAME(TestRCLFixture, RMW_IMPLEMENTATION), test_rcl_get_instance_id) {
Expand Down
22 changes: 22 additions & 0 deletions rcl/test/rcl/test_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include "rcl/error_handling.h"
#include "rcl/logging_rosout.h"

#include "../mocking_utils/patch.hpp"

#ifdef RMW_IMPLEMENTATION
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
# define CLASSNAME(NAME, SUFFIX) CLASSNAME_(NAME, SUFFIX)
Expand Down Expand Up @@ -410,6 +412,14 @@ TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_life_cycle)
EXPECT_EQ(RCL_RET_BAD_ALLOC, ret) << "Expected RCL_RET_BAD_ALLOC";
ASSERT_TRUE(rcl_error_is_set());
rcl_reset_error();
// Try init but force an internal error.
{
auto mock = mocking_utils::patch_to_fail(
"lib:rcl", rmw_create_node, "internal error", nullptr);
ret = rcl_node_init(&node, name, namespace_, &context, &default_options);
EXPECT_EQ(RCL_RET_ERROR, ret);
rcl_reset_error();
}

// Try fini with invalid arguments.
ret = rcl_node_fini(nullptr);
Expand All @@ -424,6 +434,18 @@ TEST_F(CLASSNAME(TestNodeFixture, RMW_IMPLEMENTATION), test_rcl_node_life_cycle)
EXPECT_EQ(RCL_RET_OK, ret);
ret = rcl_node_fini(&node);
EXPECT_EQ(RCL_RET_OK, ret);
// Try normal init and fini, but force an internal error on first try.
{
ret = rcl_node_init(&node, name, namespace_, &context, &default_options);
EXPECT_EQ(RCL_RET_OK, ret);
auto mock = mocking_utils::inject_on_return(
"lib:rcl", rmw_destroy_node, RMW_RET_ERROR);
ret = rcl_node_fini(&node);
EXPECT_EQ(RCL_RET_ERROR, ret);
rcl_reset_error();
}
ret = rcl_node_fini(&node);
EXPECT_EQ(RCL_RET_OK, ret);
// Try repeated init and fini calls.
ret = rcl_node_init(&node, name, namespace_, &context, &default_options);
EXPECT_EQ(RCL_RET_OK, ret);
Expand Down
161 changes: 161 additions & 0 deletions rcl/test/rcl/test_security.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@
#include "rcl/error_handling.h"

#include "rcutils/filesystem.h"
#include "rcutils/get_env.h"

#include "rmw/error_handling.h"
#include "rmw/rmw.h"

#include "osrf_testing_tools_cpp/scope_exit.hpp"

#include "./allocator_testing_utils.h"
#include "../mocking_utils/patch.hpp"

#define TEST_SECURITY_DIRECTORY_RESOURCES_DIR_NAME "/test_security_directory"
#define TEST_ENCLAVE "dummy_enclave"
Expand Down Expand Up @@ -253,3 +257,160 @@ TEST_F(TestGetSecureRoot, test_get_security_options) {
PATH_SEPARATOR "enclaves" PATH_SEPARATOR TEST_ENCLAVE,
options.security_root_path);
}

TEST_F(TestGetSecureRoot, test_rcl_security_enabled) {
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_security_enabled(nullptr));
rcl_reset_error();

{
bool use_security;
auto mock = mocking_utils::patch_and_return(
"lib:rcl", rcutils_get_env, "internal error");
EXPECT_EQ(RCL_RET_ERROR, rcl_security_enabled(&use_security));
rcl_reset_error();
}

{
bool use_security = false;
putenv_wrapper(ROS_SECURITY_ENABLE_VAR_NAME "=true");
EXPECT_EQ(RCL_RET_OK, rcl_security_enabled(&use_security));
EXPECT_TRUE(use_security);
unsetenv_wrapper(ROS_SECURITY_ENABLE_VAR_NAME);
}

{
bool use_security = true;
putenv_wrapper(ROS_SECURITY_ENABLE_VAR_NAME "=false");
EXPECT_EQ(RCL_RET_OK, rcl_security_enabled(&use_security));
EXPECT_FALSE(use_security);
unsetenv_wrapper(ROS_SECURITY_ENABLE_VAR_NAME);
}

{
bool use_security = true;
putenv_wrapper(ROS_SECURITY_ENABLE_VAR_NAME "=foo");
EXPECT_EQ(RCL_RET_OK, rcl_security_enabled(&use_security));
EXPECT_FALSE(use_security);
unsetenv_wrapper(ROS_SECURITY_ENABLE_VAR_NAME);
}

{
bool use_security = true;
EXPECT_EQ(RCL_RET_OK, rcl_security_enabled(&use_security));
EXPECT_FALSE(use_security);
}
}

TEST_F(TestGetSecureRoot, test_rcl_get_enforcement_policy) {
EXPECT_EQ(RCL_RET_INVALID_ARGUMENT, rcl_get_enforcement_policy(nullptr));
rcl_reset_error();

{
rmw_security_enforcement_policy_t policy;
auto mock = mocking_utils::patch_and_return(
"lib:rcl", rcutils_get_env, "internal error");
EXPECT_EQ(RCL_RET_ERROR, rcl_get_enforcement_policy(&policy));
rcl_reset_error();
}

{
rmw_security_enforcement_policy_t policy = RMW_SECURITY_ENFORCEMENT_PERMISSIVE;
putenv_wrapper(ROS_SECURITY_STRATEGY_VAR_NAME "=Enforce");
EXPECT_EQ(RCL_RET_OK, rcl_get_enforcement_policy(&policy));
EXPECT_EQ(RMW_SECURITY_ENFORCEMENT_ENFORCE, policy);
unsetenv_wrapper(ROS_SECURITY_STRATEGY_VAR_NAME);
}

{
rmw_security_enforcement_policy_t policy = RMW_SECURITY_ENFORCEMENT_ENFORCE;
EXPECT_EQ(RCL_RET_OK, rcl_get_enforcement_policy(&policy));
EXPECT_EQ(RMW_SECURITY_ENFORCEMENT_PERMISSIVE, policy);
}

{
rmw_security_enforcement_policy_t policy = RMW_SECURITY_ENFORCEMENT_ENFORCE;
putenv_wrapper(ROS_SECURITY_STRATEGY_VAR_NAME "=foo");
EXPECT_EQ(RCL_RET_OK, rcl_get_enforcement_policy(&policy));
EXPECT_EQ(RMW_SECURITY_ENFORCEMENT_PERMISSIVE, policy);
unsetenv_wrapper(ROS_SECURITY_STRATEGY_VAR_NAME);
}

{
rmw_security_enforcement_policy_t policy = RMW_SECURITY_ENFORCEMENT_ENFORCE;
putenv_wrapper(ROS_SECURITY_STRATEGY_VAR_NAME "=ENFORCE");
EXPECT_EQ(RCL_RET_OK, rcl_get_enforcement_policy(&policy));
EXPECT_EQ(RMW_SECURITY_ENFORCEMENT_PERMISSIVE, policy);
unsetenv_wrapper(ROS_SECURITY_STRATEGY_VAR_NAME);
}
}

TEST_F(TestGetSecureRoot, test_rcl_get_secure_root_with_bad_arguments) {
rcl_allocator_t allocator = rcl_get_default_allocator();
EXPECT_EQ(nullptr, rcl_get_secure_root(nullptr, &allocator));
EXPECT_TRUE(rcl_error_is_set());
rcl_reset_error();

EXPECT_EQ(nullptr, rcl_get_secure_root("test", nullptr));
EXPECT_TRUE(rcl_error_is_set());
rcl_reset_error();

rcl_allocator_t invalid_allocator = rcutils_get_zero_initialized_allocator();
EXPECT_EQ(nullptr, rcl_get_secure_root("test", &invalid_allocator));
EXPECT_TRUE(rcl_error_is_set());
rcl_reset_error();
}

TEST_F(TestGetSecureRoot, test_rcl_get_secure_root_with_internal_errors) {
{
auto mock = mocking_utils::patch(
"lib:rcl", rcutils_get_env,
[&](const char * name, const char ** value) -> const char * {
if (strcmp(ROS_SECURITY_ENCLAVE_OVERRIDE, name) == 0) {
return "internal error";
}
*value = "";
return nullptr;
});
rcl_allocator_t allocator = rcl_get_default_allocator();
EXPECT_EQ(nullptr, rcl_get_secure_root("test", &allocator));
EXPECT_TRUE(rcl_error_is_set());
rcl_reset_error();
}

{
putenv_wrapper(
ROS_SECURITY_ENCLAVE_OVERRIDE "=" TEST_ENCLAVE_ABSOLUTE);
rcl_allocator_t allocator = get_failing_allocator();
EXPECT_EQ(nullptr, rcl_get_secure_root("test", &allocator));
EXPECT_TRUE(rcl_error_is_set());
rcl_reset_error();
unsetenv_wrapper(ROS_SECURITY_ENCLAVE_OVERRIDE);
}

{
auto mock = mocking_utils::patch(
"lib:rcl", rcutils_get_env,
[&](const char * name, const char ** value) -> const char * {
if (strcmp(ROS_SECURITY_KEYSTORE_VAR_NAME, name) == 0) {
return "internal error";
}
*value = "";
return nullptr;
});
rcl_allocator_t allocator = rcl_get_default_allocator();
EXPECT_EQ(nullptr, rcl_get_secure_root("test", &allocator));
EXPECT_TRUE(rcl_error_is_set());
rcl_reset_error();
}

{
putenv_wrapper(
ROS_SECURITY_KEYSTORE_VAR_NAME "="
TEST_RESOURCES_DIRECTORY TEST_SECURITY_DIRECTORY_RESOURCES_DIR_NAME);
rcl_allocator_t allocator = get_failing_allocator();
EXPECT_EQ(nullptr, rcl_get_secure_root("test", &allocator));
EXPECT_TRUE(rcl_error_is_set());
rcl_reset_error();
unsetenv_wrapper(ROS_SECURITY_KEYSTORE_VAR_NAME);
}
}

0 comments on commit 2147c7f

Please sign in to comment.