From e2d4823c338ed998c00cec2b42b93464f6fa7561 Mon Sep 17 00:00:00 2001 From: Robert Kwan Date: Sun, 26 Oct 2025 22:04:37 -0700 Subject: [PATCH 1/3] Merge back from jazzy branch - add tests for launch_utils of controller manager (#2147) --- .../test/test_ros2_control_node_launch.py | 64 ++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/controller_manager/test/test_ros2_control_node_launch.py b/controller_manager/test/test_ros2_control_node_launch.py index 9c9f8892ed..cca3c7ad8d 100644 --- a/controller_manager/test/test_ros2_control_node_launch.py +++ b/controller_manager/test/test_ros2_control_node_launch.py @@ -43,8 +43,11 @@ check_controllers_running, check_node_running, ) -from controller_manager.launch_utils import generate_controllers_spawner_launch_description - +from controller_manager.launch_utils import ( + generate_controllers_spawner_launch_description, + generate_controllers_spawner_launch_description_from_dict, + generate_load_controller_launch_description, +) # Executes the given launch file and checks if all nodes can be started @pytest.mark.launch_test @@ -102,6 +105,63 @@ def setUp(self): def tearDown(self): self.node.destroy_node() + # ------------------------------------------------------------------ + # Helper methods + # ------------------------------------------------------------------ + def _extract_actions(self, result): + """Return a list of launch actions, regardless of type.""" + if isinstance(result, list): + return result + elif hasattr(result, "entities"): # LaunchDescription in newer ROS2 + return list(result.entities) + else: + return [result] + + def _assert_launch_result(self, result, min_len=0): + """Verify that result is list- or LaunchDescription-like.""" + self.assertTrue( + isinstance(result, (list, LaunchDescription)), + f"Unexpected result type: {type(result)}", + ) + actions = self._extract_actions(result) + self.assertGreaterEqual(len(actions), min_len) + for act in actions: + self.assertTrue( + hasattr(act, "execute") or hasattr(act, "visit"), + f"Invalid action type: {type(act)}", + ) + return actions + + # ------------------------------------------------------------------ + # Launch utility tests + # ------------------------------------------------------------------ + def test_generate_controllers_spawner_from_list(self): + controllers = ["test_controller_1", "test_controller_2"] + result = generate_controllers_spawner_launch_description(controllers) + actions = self._assert_launch_result(result, min_len=1) + self.assertTrue(actions is not None and len(actions) > 0) + + def test_generate_controllers_spawner_from_dict(self): + """Ensure dict-based API works with string param files (old-style).""" + controllers = { + "ctrl_A": ["/tmp/dummy.yaml"], + "ctrl_B": ["/tmp/dummy.yaml"], + } + result = generate_controllers_spawner_launch_description_from_dict(controllers) + actions = self._extract_actions(result) + self.assertIsInstance(result, LaunchDescription) + self.assertEqual(len(actions), 3) + self.assertIsInstance(actions[-1], Node) + + def test_generate_load_controller_launch_description(self): + """Test load controller description with valid single string params.""" + controllers = ["test_controller_load"] + result = generate_load_controller_launch_description(controllers) + actions = self._extract_actions(result) + self.assertIsInstance(result, LaunchDescription) + self.assertEqual(len(actions), 3) + self.assertIsInstance(actions[-1], Node) + def test_node_start(self): check_node_running(self.node, "controller_manager") From ffd206518bd9f2915b3e4c409c7f392539b5eca5 Mon Sep 17 00:00:00 2001 From: Robert Kwan Date: Mon, 27 Oct 2025 22:27:48 -0700 Subject: [PATCH 2/3] Fix missing line to Add tests for launch_utils of controller manager (#2147) --- controller_manager/test/test_ros2_control_node_launch.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/controller_manager/test/test_ros2_control_node_launch.py b/controller_manager/test/test_ros2_control_node_launch.py index cca3c7ad8d..46a4f813c0 100644 --- a/controller_manager/test/test_ros2_control_node_launch.py +++ b/controller_manager/test/test_ros2_control_node_launch.py @@ -37,6 +37,7 @@ from launch_testing.actions import ReadyToTest import launch_testing.markers import launch_ros.actions +from launch_ros.actions import Node import rclpy from controller_manager.test_utils import ( @@ -49,6 +50,7 @@ generate_load_controller_launch_description, ) + # Executes the given launch file and checks if all nodes can be started @pytest.mark.launch_test def generate_test_description(): @@ -133,7 +135,7 @@ def _assert_launch_result(self, result, min_len=0): return actions # ------------------------------------------------------------------ - # Launch utility tests + # Launch utility tests # ------------------------------------------------------------------ def test_generate_controllers_spawner_from_list(self): controllers = ["test_controller_1", "test_controller_2"] From 4ffc6750a097918eaaa08b2451ac5da754e91383 Mon Sep 17 00:00:00 2001 From: robkwan <28550109+robkwan@users.noreply.github.com> Date: Sat, 1 Nov 2025 00:50:37 +0000 Subject: [PATCH 3/3] Bump version of pre-commit hooks --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 47a28bbf00..78866ca277 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: # Python hooks - repo: https://github.com/asottile/pyupgrade - rev: v3.20.0 + rev: v3.21.0 hooks: - id: pyupgrade args: [--py36-plus] @@ -133,7 +133,7 @@ repos: exclude: CHANGELOG\.rst|\.(svg|pyc|drawio)$ - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.34.0 + rev: 0.34.1 hooks: - id: check-github-workflows args: ["--verbose"]