diff --git a/test_rclcpp/CMakeLists.txt b/test_rclcpp/CMakeLists.txt index a943c878..5a5502d8 100644 --- a/test_rclcpp/CMakeLists.txt +++ b/test_rclcpp/CMakeLists.txt @@ -72,11 +72,16 @@ if(BUILD_TESTING) endfunction() macro(custom_launch_test_two_executables test_name executable1 executable2) + cmake_parse_arguments(_ARG "" "ARGS1;ARGS2;RMW1;RMW2" "" ${ARGN}) set(TEST_NAME "${test_name}") set(TEST_EXECUTABLE1 "$") + set(TEST_EXECUTABLE1_ARGS "${_ARG_ARGS1}") set(TEST_EXECUTABLE1_NAME "${executable1}") + set(TEST_RMW_IMPLEMENTATION1 "${_ARG_RMW1}") set(TEST_EXECUTABLE2 "$") + set(TEST_EXECUTABLE2_ARGS "${_ARG_ARGS2}") set(TEST_EXECUTABLE2_NAME "${executable2}") + set(TEST_RMW_IMPLEMENTATION2 "${_ARG_RMW2}") configure_file( test/test_two_executables.py.in ${test_name}${target_suffix}.py.configure @@ -88,11 +93,8 @@ if(BUILD_TESTING) ) ament_add_pytest_test(${test_name}${target_suffix} "${CMAKE_CURRENT_BINARY_DIR}/${test_name}${target_suffix}_$.py" - ${ARGN} APPEND_LIBRARY_DIRS "${append_library_dirs}" - ENV - RCL_ASSERT_RMW_ID_MATCHES=${rmw_implementation} - RMW_IMPLEMENTATION=${rmw_implementation} + ${_ARG_UNPARSED_ARGUMENTS} ) if(TEST ${test_name}${target_suffix}) set_tests_properties(${test_name}${target_suffix} @@ -136,6 +138,20 @@ if(BUILD_TESTING) endif() endmacro() + macro(cross_rmw_tests) + # test node names cross rmw + if(rmw_implementation1 STREQUAL rmw_implementation2) + set(target_suffix "__${rmw_implementation1}") + else() + set(target_suffix "__${rmw_implementation1}__${rmw_implementation2}") + endif() + 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) + endmacro() + macro(targets) custom_gtest(gtest_publisher "test/test_publisher.cpp" @@ -183,19 +199,31 @@ if(BUILD_TESTING) # Parameter tests single implementation custom_launch_test_two_executables(test_parameter_server_cpp test_parameters_server_cpp test_remote_parameters_cpp + ENV + RCL_ASSERT_RMW_ID_MATCHES=${rmw_implementation} + RMW_IMPLEMENTATION=${rmw_implementation} TIMEOUT 60) # Service tests single implementation custom_launch_test_two_executables(test_services_cpp test_services_server_cpp test_services_client_cpp + ENV + RCL_ASSERT_RMW_ID_MATCHES=${rmw_implementation} + RMW_IMPLEMENTATION=${rmw_implementation} TIMEOUT 60) custom_launch_test_two_executables(test_client_scope_cpp test_client_scope_server_cpp test_client_scope_client_cpp + ENV + RCL_ASSERT_RMW_ID_MATCHES=${rmw_implementation} + RMW_IMPLEMENTATION=${rmw_implementation} TIMEOUT 60) custom_launch_test_two_executables(test_client_scope_consistency_cpp test_client_scope_consistency_server_cpp test_client_scope_consistency_client_cpp + ENV + RCL_ASSERT_RMW_ID_MATCHES=${rmw_implementation} + RMW_IMPLEMENTATION=${rmw_implementation} TIMEOUT 60) # Note (dhood): signal handler tests will be skipped on Windows because there is no opportunity @@ -217,6 +245,12 @@ if(BUILD_TESTING) test_signal_handler TIMEOUT 30 ${SKIP_TEST}) + + # Test node names + set(rmw_implementation1 "${rmw_implementation}") + foreach(rmw_implementation2 ${rmw_implementations}) + cross_rmw_tests() + endforeach() endmacro() set(append_library_dirs "${CMAKE_CURRENT_BINARY_DIR}") @@ -224,6 +258,14 @@ if(BUILD_TESTING) set(append_library_dirs "${append_library_dirs}/$") endif() + # Test node names + add_executable(node_with_name "test/node_with_name.cpp") + ament_target_dependencies(node_with_name + "rclcpp") + add_executable(node_name_list "test/node_name_list.cpp") + ament_target_dependencies(node_name_list + "rclcpp") + call_for_each_rmw_implementation(targets) custom_executable(test_signal_handler "test/test_signal_handler.cpp") diff --git a/test_rclcpp/test/node_name_list.cpp b/test_rclcpp/test/node_name_list.cpp new file mode 100644 index 00000000..38055b48 --- /dev/null +++ b/test_rclcpp/test/node_name_list.cpp @@ -0,0 +1,65 @@ +// Copyright 2018 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. + +#include + +#include "rclcpp/rclcpp.hpp" + +using namespace std::chrono_literals; + +int main(int argc, char ** argv) +{ + rclcpp::init(argc, argv); + + if (argc < 2) { + fprintf( + stderr, "Must pass at least one argument with the expected node name\n"); + return 1; + } + printf("Waiting for node with name: %s\n", argv[1]); + std::cout.flush(); + + auto node_name = std::string("node_name_list"); + auto node = rclcpp::Node::make_shared(node_name); + + rclcpp::executors::SingleThreadedExecutor exec; + exec.add_node(node); + + int rc = 1; + const std::chrono::steady_clock::time_point max_runtime = + std::chrono::steady_clock::now() + 10s; + while (rc && rclcpp::ok()) { + printf("\n"); + auto names = node->get_node_graph_interface()->get_node_names(); + for (auto it : names) { + printf("%s\n", it.c_str()); + if (argc >= 2 && it == argv[1]) { + printf(" found expected node name\n"); + rc = 0; + } + } + std::cout.flush(); + if (std::chrono::steady_clock::now() >= max_runtime) { + break; + } + exec.spin_once(250ms); + } + + exec.remove_node(node); + rclcpp::shutdown(); + if (rc) { + fprintf(stderr, "not found expected node name\n"); + } + return rc; +} diff --git a/test_rclcpp/test/node_with_name.cpp b/test_rclcpp/test/node_with_name.cpp new file mode 100644 index 00000000..6906def9 --- /dev/null +++ b/test_rclcpp/test/node_with_name.cpp @@ -0,0 +1,35 @@ +// Copyright 2018 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. + +#include + +#include "rclcpp/rclcpp.hpp" + +int main(int argc, char ** argv) +{ + rclcpp::init(argc, argv); + + auto node_name = std::string("node_with_name"); + if (argc >= 2) { + node_name += "_"; + node_name += argv[1]; + } + printf("Starting node with name: %s\n", node_name.c_str()); + std::cout.flush(); + + auto node = rclcpp::Node::make_shared(node_name); + rclcpp::spin(node); + rclcpp::shutdown(); + return 0; +} diff --git a/test_rclcpp/test/test_two_executables.py.in b/test_rclcpp/test/test_two_executables.py.in index 424b50aa..8b2e7560 100644 --- a/test_rclcpp/test/test_two_executables.py.in +++ b/test_rclcpp/test/test_two_executables.py.in @@ -1,5 +1,7 @@ # generated from test_rclcpp/test/test_two_executables.py.in +import os + from launch import LaunchDescriptor from launch.exit_handler import primary_exit_handler from launch.launcher import DefaultLauncher @@ -8,14 +10,30 @@ from launch.launcher import DefaultLauncher def @TEST_NAME@(): ld = LaunchDescriptor() + cmd = ['@TEST_EXECUTABLE1@'] + if '@TEST_EXECUTABLE1_ARGS@': + cmd += '@TEST_EXECUTABLE1_ARGS@'.split(' ') + env = None + if '@TEST_RMW_IMPLEMENTATION1@': + env = dict(os.environ) + env['RMW_IMPLEMENTATION'] = '@TEST_RMW_IMPLEMENTATION1@' ld.add_process( - cmd=['@TEST_EXECUTABLE1@'], + cmd=cmd, name='@TEST_EXECUTABLE1_NAME@', + env=env, ) + cmd = ['@TEST_EXECUTABLE2@'] + if '@TEST_EXECUTABLE2_ARGS@': + cmd += '@TEST_EXECUTABLE2_ARGS@'.split(' ') + env = None + if '@TEST_RMW_IMPLEMENTATION2@': + env = dict(os.environ) + env['RMW_IMPLEMENTATION'] = '@TEST_RMW_IMPLEMENTATION2@' ld.add_process( - cmd=['@TEST_EXECUTABLE2@', '@TEST_EXECUTABLE1_NAME@'], + cmd=cmd, name='@TEST_EXECUTABLE2_NAME@', + env=env, exit_handler=primary_exit_handler, )