diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 8829ee50..e6242318 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -16,24 +16,21 @@ jobs:
strategy:
fail-fast: false
matrix:
- include:
- # Rolling (source)
- - ROS_DISTRO: rolling
- BUILD_TYPE: source
- # Jazzy (binary)
- - ROS_DISTRO: jazzy
- BUILD_TYPE: binary
- # Iron (binary)
- - ROS_DISTRO: iron
- BUILD_TYPE: binary
+ ROS_DISTRO: [rolling, jazzy, iron]
+ BUILD_TYPE: [source, binary]
+ exclude:
+ - BUILD_TYPE: ${{ github.event_name != 'schedule' && 'source' || '' }}
env:
ROS2_REPOS_FILE_URL: 'https://raw.githubusercontent.com/ros2/ros2/${{ matrix.ROS_DISTRO }}/ros2.repos'
+ RMW_MIDDLEWARE_TEST_PACKAGES: 'test_rclcpp test_communication rcl'
runs-on: ubuntu-latest
container:
image: ${{ matrix.BUILD_TYPE == 'binary' && format('ros:{0}-ros-base', matrix.ROS_DISTRO) || 'ubuntu:noble' }}
steps:
- uses: ros-tooling/setup-ros@v0.7
if: ${{ matrix.BUILD_TYPE == 'source' }}
+ with:
+ use-ros2-testing: true
- name: Install Coverage Tools
if: ${{ matrix.BUILD_TYPE == 'binary' }}
run: sudo apt update && sudo apt install -y python3-colcon-coveragepy-result python3-colcon-lcov-result lcov
@@ -42,7 +39,28 @@ jobs:
uses: ros-tooling/action-ros-ci@v0.3
with:
package-name: |
+ ${{ matrix.BUILD_TYPE == 'source' && env.RMW_MIDDLEWARE_TEST_PACKAGES || '' }}
rmw_zenoh_cpp
zenoh_c_vendor
+ colcon-defaults: |
+ {
+ "build": {
+ "cmake-args": [
+ "-DSKIP_MULTI_RMW_TESTS=ON"
+ ]
+ }
+ }
target-ros2-distro: ${{ matrix.ROS_DISTRO }}
vcs-repo-file-url: ${{ matrix.BUILD_TYPE == 'source' && env.ROS2_REPOS_FILE_URL || '' }}
+ skip-tests: true
+ - name: Run system_tests
+ if: ${{ matrix.BUILD_TYPE == 'source' }}
+ run: |
+ cd ${{ steps.action-ros-ci.outputs.ros-workspace-directory-name }}
+ . install/setup.sh
+ launch_test install/rmw_zenoh_cpp/test/rmw_zenoh_integration.test.py 'selected_system_tests:=${{ env.RMW_MIDDLEWARE_TEST_PACKAGES }}'
+ - uses: actions/upload-artifact@v3
+ if: ${{ matrix.BUILD_TYPE == 'source' }}
+ with:
+ name: colcon-logs-${{ matrix.ROS_DISTRO }}-latest
+ path: ${{ steps.action-ros-ci.outputs.ros-workspace-directory-name }}/log
diff --git a/rmw_zenoh_cpp/CMakeLists.txt b/rmw_zenoh_cpp/CMakeLists.txt
index 4ecfe360..73731e98 100644
--- a/rmw_zenoh_cpp/CMakeLists.txt
+++ b/rmw_zenoh_cpp/CMakeLists.txt
@@ -97,6 +97,9 @@ if(BUILD_TESTING)
ament_lint_cmake()
ament_uncrustify(EXCLUDE ${_linter_excludes})
ament_xmllint()
+
+ install(FILES test/rmw_zenoh_integration.test.py
+ DESTINATION test)
endif()
install(
diff --git a/rmw_zenoh_cpp/package.xml b/rmw_zenoh_cpp/package.xml
index 3da4920d..3c8e1404 100644
--- a/rmw_zenoh_cpp/package.xml
+++ b/rmw_zenoh_cpp/package.xml
@@ -25,6 +25,7 @@
rosidl_typesupport_fastrtps_cpp
rmw
+ ament_index_python
ament_lint_auto
ament_lint_common
diff --git a/rmw_zenoh_cpp/test/rmw_zenoh_integration.test.py b/rmw_zenoh_cpp/test/rmw_zenoh_integration.test.py
new file mode 100644
index 00000000..e7577160
--- /dev/null
+++ b/rmw_zenoh_cpp/test/rmw_zenoh_integration.test.py
@@ -0,0 +1,84 @@
+# Copyright 2024 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.
+
+import os
+import sys
+import signal
+import subprocess
+import time
+import unittest
+
+import launch
+import launch.actions
+import launch.substitutions
+import launch_ros.actions
+import launch_testing.actions
+import launch_testing.markers
+import pytest
+
+
+proc_env = os.environ.copy()
+proc_env['RMW_IMPLEMENTATION'] = 'rmw_zenoh_cpp'
+
+@pytest.mark.launch_test
+@launch_testing.markers.keep_alive
+def generate_test_description():
+
+ selected_system_tests = launch.substitutions.LaunchConfiguration('selected_system_tests')
+ selected_system_tests_arg = launch.actions.DeclareLaunchArgument(
+ 'selected_system_tests',
+ default_value="test_rclcpp test_communication")
+
+ zenoh_router = launch_ros.actions.Node(
+ package="rmw_zenoh_cpp",
+ executable="rmw_zenohd",
+ output="both",
+ env=proc_env
+ )
+
+ dut_process = launch.actions.ExecuteProcess(
+ cmd=[
+ 'colcon',
+ 'test',
+ '--packages-select',
+ selected_system_tests,
+ '--retest-until-pass',
+ '2',
+ ],
+ shell=True,
+ env=proc_env,
+ )
+
+ return launch.LaunchDescription([
+ selected_system_tests_arg,
+ zenoh_router,
+ dut_process,
+ # In tests where all of the procs under tests terminate themselves, it's necessary
+ # to add a dummy process not under test to keep the launch alive. launch_test
+ # provides a simple launch action that does this:
+ launch_testing.util.KeepAliveProc(),
+ launch_testing.actions.ReadyToTest()
+ ]) , {'dut_process': dut_process}
+
+class TestTerminatingProcessStops(unittest.TestCase):
+ def test_proc_terminates(self, proc_info, dut_process):
+ proc_info.assertWaitForShutdown(process=dut_process, timeout=400000)
+
+# These tests are run after the processes in generate_test_description() have shutdown.
+@launch_testing.post_shutdown_test()
+class TestShutdown(unittest.TestCase):
+
+ def test_exit_codes(self, proc_info):
+ """Check if the processes exited normally."""
+ launch_testing.asserts.assertExitCodes(proc_info)