Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update test_security and test_rclcpp after one Participant per Context change #406

Merged
merged 2 commits into from
Apr 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions test_rclcpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,29 @@ if(BUILD_TESTING)
else()
set(target_suffix "__${rmw_implementation1}__${rmw_implementation2}")
endif()
# TODO(hidmic): enable tests once FastRTPS <=> (Opensplice|Connext) interoperation
# issues are resolved (see https://github.com/ros2/rmw_fastrtps/issues/246).
custom_launch_test_two_executables(test_node_name
node_with_name node_name_list
ARGS1 "${rmw_implementation1}" ARGS2 "node_with_name_${rmw_implementation1}"
RMW1 ${rmw_implementation1} RMW2 ${rmw_implementation2}
TIMEOUT 15
${SKIP_TEST})

set(rmw_implementation1_is_fastrtps FALSE)
set(rmw_implementation2_is_fastrtps FALSE)
if(rmw_implementation1 MATCHES "(.*)fastrtps(.*)")
set(rmw_implementation1_is_fastrtps TRUE)
endif()
if(rmw_implementation2 MATCHES "(.*)fastrtps(.*)")
set(rmw_implementation2_is_fastrtps TRUE)
endif()

# Skipped tests between fastrtps and others, as the node names are communicated with a different mechanism.
# TODO(ivanpauno): Reenable this tests after the other implementations also use one Participant per Context.
if(
(NOT rmw_implementation1_is_fastrtps AND NOT rmw_implementation2_is_fastrtps) OR
(rmw_implementation1_is_fastrtps AND rmw_implementation2_is_fastrtps)
)
custom_launch_test_two_executables(test_node_name
node_with_name node_name_list
ARGS1 "${rmw_implementation1}" ARGS2 "node_with_name_${rmw_implementation1}"
RMW1 ${rmw_implementation1} RMW2 ${rmw_implementation2}
TIMEOUT 15
${SKIP_TEST})
mikaelarguedas marked this conversation as resolved.
Show resolved Hide resolved
endif()
endmacro()

macro(targets)
Expand Down
8 changes: 5 additions & 3 deletions test_security/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ if(BUILD_TESTING)
ament_lint_auto_find_test_dependencies()

find_package(launch_testing_ament_cmake REQUIRED)
find_package(osrf_testing_tools_cpp REQUIRED)

# get the rmw implementations ahead of time
find_package(rmw_implementation_cmake REQUIRED)
Expand Down Expand Up @@ -80,7 +81,7 @@ if(BUILD_TESTING)
${_AMENT_EXPORT_ABSOLUTE_LIBRARIES}
${_AMENT_EXPORT_LIBRARY_TARGETS})
ament_target_dependencies(${target}${target_suffix}
"rcl")
"rcl" "osrf_testing_tools_cpp")
set_tests_properties(
${target}${target_suffix}
PROPERTIES REQUIRED_FILES "$<TARGET_FILE:${target}${target_suffix}>"
Expand Down Expand Up @@ -329,13 +330,14 @@ if(BUILD_TESTING)
# prevents finding it repeatedly in each local scope
ament_find_gtest()

set(VALID_ROS_SECURITY_ROOT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/test_security_files")
set(KEYSTORE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/test_security_files")
set(VALID_ROS_SECURITY_ROOT_DIRECTORY "${KEYSTORE_DIRECTORY}/contexts")

# generate security artifacts using sros2
find_program(PROGRAM ros2)

set(node_names_list "/publisher;/subscriber;/publisher_missing_key;/publisher_invalid_cert")
set(generate_artifacts_command ${PROGRAM} security generate_artifacts -k ${VALID_ROS_SECURITY_ROOT_DIRECTORY} -n ${node_names_list})
set(generate_artifacts_command ${PROGRAM} security generate_artifacts -k ${KEYSTORE_DIRECTORY} -c ${node_names_list})
execute_process(
COMMAND ${generate_artifacts_command}
RESULT_VARIABLE GENERATE_ARTIFACTS_RESULT
Expand Down
1 change: 1 addition & 0 deletions test_security/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<test_depend>launch</test_depend>
<test_depend>launch_testing</test_depend>
<test_depend>launch_testing_ament_cmake</test_depend>
<test_depend>osrf_testing_tools_cpp</test_depend>
<test_depend>rcl</test_depend>
<test_depend>rclcpp</test_depend>
<!--test_depend>rclpy</test_depend--> <!-- test security tests only C++ nodes ATM -->
Expand Down
204 changes: 117 additions & 87 deletions test_security/test/test_invalid_secure_node_creation_c.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2016-2017 Open Source Robotics Foundation, Inc.
// Copyright 2016-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.
Expand All @@ -21,31 +21,22 @@
#include <limits>
#include <memory>
#include <string>
#include <vector>

#include "osrf_testing_tools_cpp/scope_exit.hpp"

#include "rcl/rcl.h"
#include "rcl/error_handling.h"
#include "rcutils/get_env.h"

#ifndef SCOPE_EXIT_HPP_
#define SCOPE_EXIT_HPP_

template<typename Callable>
struct ScopeExit
{
explicit ScopeExit(Callable callable)
: callable_(callable) {}
~ScopeExit() {callable_();}

private:
Callable callable_;
};
#include "rcutils/get_env.h"
#include "rcutils/strdup.h"

template<typename Callable>
ScopeExit<Callable>
make_scope_exit(Callable callable)
{
return ScopeExit<Callable>(callable);
}
#ifdef RMW_IMPLEMENTATION
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
# define CLASSNAME(NAME, SUFFIX) CLASSNAME_(NAME, SUFFIX)
#else
# define CLASSNAME(NAME, SUFFIX) NAME
#endif

void custom_putenv(const char * name, const char * value)
{
Expand All @@ -56,92 +47,131 @@ void custom_putenv(const char * name, const char * value)
#endif // _WIN32
}

#define SCOPE_EXIT(code) make_scope_exit([&]() {code;})

#endif // SCOPE_EXIT_HPP_

struct TestConfig
{
const char * ROS_SECURITY_ROOT_DIRECTORY;
const char * ROS_SECURITY_ENABLE;
const char * ROS_SECURITY_STRATEGY;
const char * context_name;
bool should_fail_context_creation;
bool should_fail_node_creation;
const char * test_description;
};

#ifdef RMW_IMPLEMENTATION
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
# define CLASSNAME(NAME, SUFFIX) CLASSNAME_(NAME, SUFFIX)
#else
# define CLASSNAME(NAME, SUFFIX) NAME
#endif
std::ostream & operator<<(
std::ostream & out,
const TestConfig & config)
{
out << config.test_description;
return out;
}

class CLASSNAME (TestInvalidSecureNode, RMW_IMPLEMENTATION) : public ::testing::Test
class CLASSNAME (TestSecureNodes, RMW_IMPLEMENTATION)
: public ::testing::TestWithParam<TestConfig>
{
public:
rcl_context_t context;
rcl_node_t * node_ptr;
const char * previous_root_dir;
rcl_node_t node;
char * previous_root_dir;
rcutils_allocator_t allocator = rcutils_get_default_allocator();

void SetUp()
{
ASSERT_EQ(NULL, rcutils_get_env("ROS_SECURITY_ROOT_DIRECTORY", &previous_root_dir));
const char * root_dir = nullptr;
ASSERT_EQ(nullptr, rcutils_get_env("ROS_SECURITY_ROOT_DIRECTORY", &root_dir));
previous_root_dir = rcutils_strdup(root_dir, allocator);
ASSERT_NE(nullptr, previous_root_dir);
}

void TearDown()
{
rcl_ret_t ret = rcl_node_fini(this->node_ptr);
delete this->node_ptr;
ret = rcl_shutdown(&context);
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
custom_putenv("ROS_SECURITY_ROOT_DIRECTORY", previous_root_dir);
allocator.deallocate(previous_root_dir, allocator.state);
}
};

using TestSecureNodes = CLASSNAME(TestSecureNodes, RMW_IMPLEMENTATION);

void test_node_creation(
const char * ROS_SECURITY_ROOT_DIRECTORY, const char * ROS_SECURITY_ENABLE,
const char * ROS_SECURITY_STRATEGY,
const char * node_name, bool should_fail_participant_creation)
TEST_P(TestSecureNodes, test_invalid_keystore) {
ivanpauno marked this conversation as resolved.
Show resolved Hide resolved
const auto & test_config = GetParam();
if (test_config.ROS_SECURITY_ROOT_DIRECTORY != NULL) {
custom_putenv("ROS_SECURITY_ROOT_DIRECTORY", test_config.ROS_SECURITY_ROOT_DIRECTORY);
}
custom_putenv("ROS_SECURITY_ENABLE", test_config.ROS_SECURITY_ENABLE);
custom_putenv("ROS_SECURITY_STRATEGY", test_config.ROS_SECURITY_STRATEGY);
rcl_ret_t ret;
rcl_init_options_t init_options = rcl_get_zero_initialized_init_options();
ret = rcl_init_options_init(&init_options, rcl_get_default_allocator());
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
context = rcl_get_zero_initialized_context();
const char * argv[] = {"--ros-args", "--security-context", test_config.context_name};
ret = rcl_init(sizeof(argv) / sizeof(char *), argv, &init_options, &context);
if (test_config.should_fail_context_creation) {
ASSERT_EQ(RCL_RET_ERROR, ret);
rcl_reset_error();
return;
}
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
{
if (ROS_SECURITY_ROOT_DIRECTORY != NULL) {
custom_putenv("ROS_SECURITY_ROOT_DIRECTORY", ROS_SECURITY_ROOT_DIRECTORY);
}
custom_putenv("ROS_SECURITY_ENABLE", ROS_SECURITY_ENABLE);
custom_putenv("ROS_SECURITY_STRATEGY", ROS_SECURITY_STRATEGY);
rcl_ret_t ret;
rcl_init_options_t init_options = rcl_get_zero_initialized_init_options();
ret = rcl_init_options_init(&init_options, rcl_get_default_allocator());
ret = rcl_shutdown(&context);
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
});
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
this->node = rcl_get_zero_initialized_node();
rcl_node_options_t node_options = rcl_node_get_default_options();
ret = rcl_node_init(
&this->node, "test_invalid_secure_node_creation_c", "", &context, &node_options);
if (test_config.should_fail_node_creation) {
ASSERT_EQ(RCL_RET_ERROR, ret);
rcl_reset_error();
} else {
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
context = rcl_get_zero_initialized_context();
ret = rcl_init(0, nullptr, &init_options, &context);
ret = rcl_node_fini(&this->node);
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
this->node_ptr = new rcl_node_t;
*this->node_ptr = rcl_get_zero_initialized_node();
// const char * name = "node_name";
rcl_node_options_t node_options = rcl_node_get_default_options();
ret = rcl_node_init(this->node_ptr, node_name, "", &context, &node_options);
if (should_fail_participant_creation) {
ASSERT_EQ(RCL_RET_ERROR, ret) << rcl_get_error_string().str;
} else {
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
}
}
};

TEST_F(CLASSNAME(TestInvalidSecureNode, RMW_IMPLEMENTATION), test_invalid_keystore) {
test_node_creation(
"garbage",
"true", "Enforce",
"publisher", true);
}

TEST_F(CLASSNAME(TestInvalidSecureNode, RMW_IMPLEMENTATION), test_unknown_identity) {
test_node_creation(
std::vector<TestConfig> test_configs {
{
"garbage",
"true",
"Enforce",
"/publisher",
true,
true,
"test_invalid_keystore",
},
{
NULL,
"true", "Enforce",
"publisher2", true);
}

TEST_F(CLASSNAME(TestInvalidSecureNode, RMW_IMPLEMENTATION), test_invalid_cert) {
test_node_creation(
"true",
"Enforce",
"/publisher2",
true,
true,
"test_unknown_identity",
},
{
NULL,
"true", "Enforce",
"publisher_invalid_cert", true);
}

TEST_F(CLASSNAME(TestInvalidSecureNode, RMW_IMPLEMENTATION), test_missing_key) {
test_node_creation(
"true",
"Enforce",
"/publisher_invalid_cert",
false,
true,
"test_invalid_cert",
},
{
NULL,
"true", "Enforce",
"publisher_missing_key", true);
}
"true",
"Enforce",
"/publisher_missing_key",
false,
true,
"test_missing_key",
},
};

INSTANTIATE_TEST_CASE_P(
TestInitializationFails,
TestSecureNodes,
::testing::ValuesIn(test_configs),
::testing::PrintToStringParamName());
5 changes: 3 additions & 2 deletions test_security/test/test_secure_publisher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,11 @@ int main(int argc, char ** argv)
"pass a message type\n");
return 1;
}
rclcpp::init(argc, argv);
const char * args[] = {"--ros-args", "--security-context", "/publisher"};
rclcpp::init(sizeof(args) / sizeof(char *), args);
std::string message = argv[1];
std::string namespace_ = argv[2];
std::string node_name = "publisher";
std::string node_name = "test_secure_publisher";
std::string topic_name = "chatter";
std::shared_ptr<rclcpp::Node> node = nullptr;
try {
Expand Down
5 changes: 3 additions & 2 deletions test_security/test/test_secure_subscriber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,13 @@ int main(int argc, char ** argv)
}
std::string message = argv[1];
std::string namespace_ = argv[3];
std::string node_name = "subscriber";
std::string node_name = "test_secure_subscriber";
std::string topic_name = "chatter";
bool should_timeout =
((0 == strcmp(argv[2], "false")) || (0 == strcmp(argv[2], "0"))) ? false : true;

rclcpp::init(argc, argv);
const char * args[] = {"--ros-args", "--security-context", "/subscriber"};
rclcpp::init(sizeof(args) / sizeof(char *), args);
std::shared_ptr<rclcpp::Node> node = nullptr;
try {
node = rclcpp::Node::make_shared(node_name, namespace_);
Expand Down