[ROS2] Get rid of unnecessary info with launch_test

asked 2022-07-27 04:21:04 -0600

ravijoshi gravatar image

Hi, I am performing integration testing of a service. Below is the output of launch_test command:

$ launch_test src/minimal_service/test/test_service_member_function.py
[INFO] [launch]: All log files can be found below /home/ravi/.ros/log/2022-07-27-18-02-53-325657-dell-60021
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [service_member_function-1]: process started with pid [60024]
test_add_two_ints (test_service_member_function.TestMinimalService) ... [service_member_function-1] [INFO] [1658912573.644021537] [minimal_service]: Incoming request
[service_member_function-1] a: 10 b: 20
ok

----------------------------------------------------------------------
Ran 1 test in 0.320s

OK
[INFO] [service_member_function-1]: sending signal 'SIGINT' to process[service_member_function-1]
[service_member_function-1] Traceback (most recent call last):
[service_member_function-1]   File "/home/ravi/ros_ws/install/examples_rclpy_minimal_service/lib/examples_rclpy_minimal_service/service_member_function", line 33, in <module>
[service_member_function-1]     sys.exit(load_entry_point('examples-rclpy-minimal-service==0.9.4', 'console_scripts', 'service_member_function')())
[service_member_function-1]   File "/home/ravi/ros_ws/install/examples_rclpy_minimal_service/lib/python3.8/site-packages/examples_rclpy_minimal_service/service_member_function.py", line 39, in main
[service_member_function-1]     rclpy.spin(minimal_service)
[service_member_function-1]   File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/__init__.py", line 191, in spin
[service_member_function-1]     executor.spin_once()
[service_member_function-1]   File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/executors.py", line 706, in spin_once
[service_member_function-1]     handler, entity, node = self.wait_for_ready_callbacks(timeout_sec=timeout_sec)
[service_member_function-1]   File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/executors.py", line 692, in wait_for_ready_callbacks
[service_member_function-1]     return next(self._cb_iter)
[service_member_function-1]   File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/executors.py", line 589, in _wait_for_ready_callbacks
[service_member_function-1]     _rclpy.rclpy_wait(wait_set, timeout_nsec)
[service_member_function-1] KeyboardInterrupt
[ERROR] [service_member_function-1]: process has died [pid 60024, exit code -2, cmd '/home/ravi/ros_ws/install/examples_rclpy_minimal_service/lib/examples_rclpy_minimal_service/service_member_function --ros-args -r __ns:=/'].

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

Question

The unnecessary info from "sending signal 'SIGINT'" to "process has died" is confusing. It made me think that my service node died in between while testing. How to get rid of this information? Instead, I would like to have a summary report on test cases that passed/failed.

Additional Info

Below is the workspace structure:

.
├── build
├── install
├── log
└── src
    └── minimal_service
        ├── CHANGELOG.rst
        ├── examples_rclpy_minimal_service
        │   ├── __init__.py
        │   └── service_member_function.py
        ├── package.xml
        ├── README.md
        ├── resource
        │   └── examples_rclpy_minimal_service
        ├── setup.cfg
        ├── setup.py
        └── test
            ├── test_copyright.py
            ├── test_flake8.py
            ├── test_pep257.py
            └── test_service_member_function.py  <- This is the newly added file

The package is taken from ros2/examples. Below is the content of test_service_member_function.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from threading import Thread
import unittest

from example_interfaces.srv import AddTwoInts
import launch
import launch_ros
import launch_ros.actions
import launch_testing.actions
import pytest
import rclpy


@pytest.mark.rostest
def generate_test_description():
    node = launch_ros.actions.Node(
        package='examples_rclpy_minimal_service',
        namespace='',
        executable='service_member_function',
    )
    return (
        launch.LaunchDescription(
            [
                node,
                launch_testing.actions.ReadyToTest(),
            ]
        ),
        {
            'minimal_service': node,
        },
    )


class TestMinimalService(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        rclpy.init()

    @classmethod
    def tearDownClass(cls):
        rclpy.shutdown()

    def setUp(self):
        self.node = rclpy.create_node('test_minimal_service')

        self.client_add_two_ints = self.node.create_client(AddTwoInts, '/add_two_ints')
        self.assertTrue(self.client_add_two_ints.wait_for_service(timeout_sec=10.0))

        self.spin_thread = Thread(target=rclpy.spin, args=(self.node,))
        self.spin_thread.start()

    def tearDown(self):
        self.node.destroy_node()

    def test_add_two_ints(self):
        req = AddTwoInts.Request(a=10, b=20)
        res = self.client_add_two_ints.call(req)
        self.assertEqual(res.sum, 30)
edit retag flag offensive close merge delete