From a3724106a1145fb9e4551ba690c8b4e1c1510436 Mon Sep 17 00:00:00 2001 From: Victor Lopez Date: Fri, 22 Oct 2021 12:50:09 +0200 Subject: [PATCH 1/2] First simple test --- pmb2_gazebo/CMakeLists.txt | 15 +++++- pmb2_gazebo/package.xml | 5 ++ pmb2_gazebo/test/test_gazebo.launch.py | 63 ++++++++++++++++++++++++++ pmb2_gazebo/test/test_pmb2_gazebo.cpp | 62 +++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 pmb2_gazebo/test/test_gazebo.launch.py create mode 100644 pmb2_gazebo/test/test_pmb2_gazebo.cpp diff --git a/pmb2_gazebo/CMakeLists.txt b/pmb2_gazebo/CMakeLists.txt index 990c493..b51ec7d 100644 --- a/pmb2_gazebo/CMakeLists.txt +++ b/pmb2_gazebo/CMakeLists.txt @@ -10,7 +10,20 @@ if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) ament_lint_auto_find_test_dependencies() + + ament_add_gtest_executable(test_pmb2_gazebo + test/test_pmb2_gazebo.cpp) + + ament_target_dependencies(test_pmb2_gazebo + control_msgs + rclcpp + ) +add_launch_test( + test/test_gazebo.launch.py + TARGET "test_pmb2_gazebo" + ARGS "test_dir:=${CMAKE_CURRENT_BINARY_DIR}" +) + endif() -# Media commented out ament_auto_package(INSTALL_TO_SHARE launch models worlds) diff --git a/pmb2_gazebo/package.xml b/pmb2_gazebo/package.xml index 09925ed..9c5aa1a 100644 --- a/pmb2_gazebo/package.xml +++ b/pmb2_gazebo/package.xml @@ -24,8 +24,13 @@ simple_models_gazebo --> + ament_cmake_gtest ament_lint_auto ament_lint_common + control_msgs + launch_testing_ament_cmake + rclcpp + std_msgs ament_cmake diff --git a/pmb2_gazebo/test/test_gazebo.launch.py b/pmb2_gazebo/test/test_gazebo.launch.py new file mode 100644 index 0000000..1413f99 --- /dev/null +++ b/pmb2_gazebo/test/test_gazebo.launch.py @@ -0,0 +1,63 @@ +# Copyright (c) 2021 PAL Robotics S.L. +# +# 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. + +import launch_testing +import unittest +import os + +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.substitutions import PathJoinSubstitution, LaunchConfiguration +from launch_ros.actions import Node +from launch_pal.include_utils import include_launch_py_description + + +def generate_test_description(): + # This is necessary to get unbuffered output from the process under test + proc_env = os.environ.copy() + proc_env['PYTHONUNBUFFERED'] = '1' + + test_dir = DeclareLaunchArgument('test_dir') + + # dut = device under test, aka the actual test + dut_process = launch_testing.actions.GTest( + path=PathJoinSubstitution( + [LaunchConfiguration('test_dir'), 'test_pmb2_gazebo']), + output="both") + + pmb2_gazebo_launch = include_launch_py_description('pmb2_gazebo', + ['launch', 'pmb2_gazebo.launch.py']) + + return LaunchDescription([ + test_dir, + pmb2_gazebo_launch, + dut_process, + + launch_testing.actions.ReadyToTest(), + ]), {'dut_process': dut_process} + + +class TestDescriptionPublished(unittest.TestCase): + + def test_wait_for_end(self, proc_output, proc_info, dut_process): + # Wait until process ends + proc_info.assertWaitForShutdown(process=dut_process, timeout=10) + + +@ launch_testing.post_shutdown_test() +class TestSuccessfulExit(unittest.TestCase): + + def test_exit_code(self, proc_info, dut_process): + # Check that dut_process finishes with code 0 + launch_testing.asserts.assertExitCodes(proc_info, process=dut_process) diff --git a/pmb2_gazebo/test/test_pmb2_gazebo.cpp b/pmb2_gazebo/test/test_pmb2_gazebo.cpp new file mode 100644 index 0000000..023caa7 --- /dev/null +++ b/pmb2_gazebo/test/test_pmb2_gazebo.cpp @@ -0,0 +1,62 @@ +// Copyright 2021 PAL Robotics SL. +// +// 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 +#include + + +TEST(TestGazeboPMB2, test_topics) +{ + + std::shared_ptr executor = + std::make_shared(); + + auto test_node = std::make_shared("test_pmb2_gazebo"); + + std_msgs::msg::String::SharedPtr robot_description; + + std::string topic_name = "robot_description"; + auto robot_description_sub = test_node->create_subscription( + topic_name, 1, [&robot_description](const std_msgs::msg::String::SharedPtr msg) + { + robot_description = msg; + }); + + rclcpp::WaitSet wait_set; + wait_set.add_subscription(robot_description_sub); + auto ret = wait_set.wait(std::chrono::seconds(10)); + EXPECT_EQ(ret.kind(), rclcpp::WaitResultKind::Ready) << "Did not receive any message on " << topic_name; + if (ret.kind() == rclcpp::WaitResultKind::Ready) + { + std_msgs::msg::String msg; + rclcpp::MessageInfo info; + auto ret_take = robot_description_sub->take(msg, info); + EXPECT_TRUE(ret_take) << "Error retrieving message"; + } + else + { + RCLCPP_INFO_STREAM(test_node->get_logger(), "Got " << topic_name); + } +} + +int main(int argc, char ** argv) +{ + rclcpp::init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + auto res = RUN_ALL_TESTS(); + rclcpp::shutdown(); + return res; +} + From 72322ecdd41ac92a2362dd4696650ae162e5cfb1 Mon Sep 17 00:00:00 2001 From: Victor Lopez Date: Wed, 27 Oct 2021 09:06:00 +0000 Subject: [PATCH 2/2] Work in progress tests, blocked by https://github.com/ros2/launch/issues/545 --- pmb2_gazebo/package.xml | 1 + pmb2_gazebo/test/test_gazebo.launch.py | 6 ++- pmb2_gazebo/test/test_pmb2_gazebo.cpp | 56 ++++++++++++++------------ 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/pmb2_gazebo/package.xml b/pmb2_gazebo/package.xml index 9c5aa1a..47f272f 100644 --- a/pmb2_gazebo/package.xml +++ b/pmb2_gazebo/package.xml @@ -28,6 +28,7 @@ ament_lint_auto ament_lint_common control_msgs + sensor_msgs launch_testing_ament_cmake rclcpp std_msgs diff --git a/pmb2_gazebo/test/test_gazebo.launch.py b/pmb2_gazebo/test/test_gazebo.launch.py index 1413f99..4070ac2 100644 --- a/pmb2_gazebo/test/test_gazebo.launch.py +++ b/pmb2_gazebo/test/test_gazebo.launch.py @@ -28,9 +28,13 @@ def generate_test_description(): proc_env = os.environ.copy() proc_env['PYTHONUNBUFFERED'] = '1' - test_dir = DeclareLaunchArgument('test_dir') + test_dir = DeclareLaunchArgument('test_dir', + description='Path to test dir, where the gtest ' + 'executable is located') # dut = device under test, aka the actual test + # The compiled gtest executable is not installed, wee need to pass the test_dir + # to get the path to the executable dut_process = launch_testing.actions.GTest( path=PathJoinSubstitution( [LaunchConfiguration('test_dir'), 'test_pmb2_gazebo']), diff --git a/pmb2_gazebo/test/test_pmb2_gazebo.cpp b/pmb2_gazebo/test/test_pmb2_gazebo.cpp index 023caa7..0de735a 100644 --- a/pmb2_gazebo/test/test_pmb2_gazebo.cpp +++ b/pmb2_gazebo/test/test_pmb2_gazebo.cpp @@ -15,40 +15,45 @@ #include #include #include +#include +template +void waitForMessage( + const rclcpp::Node::SharedPtr & node, const std::string & topic_name, + const std::chrono::milliseconds & timeout) +{ + typename MsgType::SharedPtr msg; + + auto sub = node->create_subscription( + topic_name, 1, [&msg](const typename MsgType::SharedPtr recv_msg) + {}); + + rclcpp::WaitSet wait_set; + wait_set.add_subscription(sub); + auto ret = wait_set.wait(timeout); + EXPECT_EQ( + ret.kind(), + rclcpp::WaitResultKind::Ready) << "Did not receive any message on " << topic_name; + if (ret.kind() == rclcpp::WaitResultKind::Ready) { + MsgType msg; + rclcpp::MessageInfo info; + auto ret_take = sub->take(msg, info); + EXPECT_TRUE(ret_take) << "Error retrieving message"; + } else { + RCLCPP_INFO_STREAM(node->get_logger(), "Got " << topic_name); + } +} TEST(TestGazeboPMB2, test_topics) { - std::shared_ptr executor = std::make_shared(); auto test_node = std::make_shared("test_pmb2_gazebo"); - std_msgs::msg::String::SharedPtr robot_description; - - std::string topic_name = "robot_description"; - auto robot_description_sub = test_node->create_subscription( - topic_name, 1, [&robot_description](const std_msgs::msg::String::SharedPtr msg) - { - robot_description = msg; - }); - - rclcpp::WaitSet wait_set; - wait_set.add_subscription(robot_description_sub); - auto ret = wait_set.wait(std::chrono::seconds(10)); - EXPECT_EQ(ret.kind(), rclcpp::WaitResultKind::Ready) << "Did not receive any message on " << topic_name; - if (ret.kind() == rclcpp::WaitResultKind::Ready) - { - std_msgs::msg::String msg; - rclcpp::MessageInfo info; - auto ret_take = robot_description_sub->take(msg, info); - EXPECT_TRUE(ret_take) << "Error retrieving message"; - } - else - { - RCLCPP_INFO_STREAM(test_node->get_logger(), "Got " << topic_name); - } + waitForMessage(test_node, "robot_description", std::chrono::seconds(10)); +// test_node->get_clock()-> + rclcpp::sleep_for(std::chrono::seconds(20)); } int main(int argc, char ** argv) @@ -59,4 +64,3 @@ int main(int argc, char ** argv) rclcpp::shutdown(); return res; } -