Skip to content

Commit 0427799

Browse files
committed
Add integration test.
Signed-off-by: Jelmer de Wolde <[email protected]>
1 parent 60bb52e commit 0427799

File tree

6 files changed

+66
-12
lines changed

6 files changed

+66
-12
lines changed

.github/workflows/ros-workspace.yml

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,27 @@ on:
1212
jobs:
1313
ros-workspace:
1414
runs-on: ubuntu-latest
15-
container:
15+
container:
1616
image: rcdt/robotics
1717
options: --user root
1818
steps:
1919
- name: checkout
2020
uses: actions/checkout@v4
2121
with:
22-
submodules: 'true'
23-
- name: build
24-
shell: bash -ieo pipefail {0}
22+
submodules: "true"
23+
- name: build workspace
24+
shell: bash -ieo pipefail {0}
2525
run: |
26-
source /home/rcdt/.bashrc
27-
cd ros2_ws
28-
colcon build
26+
source /home/rcdt/.bashrc
27+
cd ros2_ws
28+
colcon build --symlink-install
29+
- name: run tests
30+
shell: bash -ieo pipefail {0}
31+
run: |
32+
source /home/rcdt/.bashrc
33+
GZ_SIM_RESOURCE_PATH="$GZ_SIM_RESOURCE_PATH:/$PWD/ros2_ws/src"
34+
GZ_SIM_RESOURCE_PATH="$GZ_SIM_RESOURCE_PATH:/$PWD/ros2_ws/src/rcdt_gz_worlds/models"
35+
GZ_SIM_RESOURCE_PATH="$GZ_SIM_RESOURCE_PATH:/$PWD/ros2_ws/src/rcdt_gz_worlds/worlds"
36+
cd ros2_ws
37+
source install/setup.bash
38+
pytest-3 src/

dockerfiles/install_scripts/dev_packages.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
set -e
66

7+
# Install pytest-timeout:
8+
pip install pytest-timeout
9+
710
# Specifying numpy range to work with ROS and Ultralytics:
811
pip install "numpy>=1.23.0,<2.0"
912

pyproject.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,10 @@
44

55
[tool.ruff.lint]
66
select = ["I", "F", "E", "W", "B", "N", "A", "C4", "PL", "Q000", "SIM", "ANN", "ARG", "ERA"]
7-
ignore = ["E501", "ANN204"]
7+
ignore = ["E501", "ANN204"]
8+
9+
[tool.pytest.ini_options]
10+
filterwarnings = [
11+
"ignore:invalid escape sequence",
12+
]
13+
timeout = 90
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# SPDX-FileCopyrightText: Alliander N. V.
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import launch_pytest
2+
import pytest
3+
from launch import LaunchDescription
4+
from launch.actions import IncludeLaunchDescription
5+
from rcdt_utilities.launch_utils import assert_for_message, get_file_path
6+
from sensor_msgs.msg import JointState
7+
8+
9+
@launch_pytest.fixture(scope="module")
10+
def launch_description() -> LaunchDescription:
11+
franka = IncludeLaunchDescription(
12+
get_file_path("rcdt_franka", ["launch"], "franka.launch.py")
13+
)
14+
15+
return LaunchDescription(
16+
[
17+
franka,
18+
launch_pytest.actions.ReadyToTest(),
19+
]
20+
)
21+
22+
23+
@pytest.mark.launch(fixture=launch_description)
24+
def test_joint_states_published() -> None:
25+
assert_for_message(JointState, "/joint_states", 10)

ros2_ws/src/rcdt_utilities/rcdt_utilities/launch_utils.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import ast
66
import os
7-
import time
87
from typing import List
98

109
import rclpy
@@ -16,6 +15,7 @@
1615
from launch.event_handlers import OnProcessExit
1716
from launch.events.process import ProcessExited
1817
from launch.substitutions import LaunchConfiguration
18+
from launch_testing_ros.wait_for_topics import WaitForTopics
1919
from rclpy.executors import Executor
2020
from rclpy.logging import get_logger
2121
from rclpy.node import Node
@@ -102,10 +102,17 @@ def on_completion(
102102
if event.returncode == 0:
103103
return complete
104104
else:
105-
while rclpy.ok:
106-
logger.error("Target did not start successfully. Please restart.")
107-
time.sleep(WAIT)
105+
logger.error("Target did not start successfully. Please restart.")
108106

109107
return RegisterEventHandler(
110108
OnProcessExit(target_action=target, on_exit=on_completion)
111109
)
110+
111+
112+
def assert_for_message(message_type: type, topic: str, timeout: int) -> bool:
113+
wait_for_topics = WaitForTopics([(topic, message_type)], timeout)
114+
received = wait_for_topics.wait()
115+
wait_for_topics.shutdown()
116+
assert received, (
117+
f"No message received of type {message_type.__name__} on topic {topic} within {timeout} seconds."
118+
)

0 commit comments

Comments
 (0)