Ask Your Question
0

colcon test "Processes under test stopped before tests completed"

asked 2022-04-09 20:42:09 -0500

AndyZe gravatar image

updated 2022-04-11 13:08:49 -0500

This issue only shows up on our slow CI runners. It doesn't show up locally.

I have a launch_testing test that passes but doesn't generate a result. The test itself is minimal; it just tests this:

EXPECT_TRUE(true);

These were the commands to run it:

colcon test --packages-select task_planning --> finished, looks good

colcon test-result --verbose --> 12 tests, 0 errors, 0 failures, 0 skipped --> all good

The test log in colcon_ws/log/latest_test/task_planning looks fine. It says the test has passed. CI prints this:

 [basic_task_planning_test-1] [  PASSED  ] 1 test.
    [basic_task_planning_test-1] Done shutting down
    [INFO] [basic_task_planning_test-1]: process has finished cleanly [pid 43801]
    ok

    ----------------------------------------------------------------------
    Ran 1 test in 2.376s

    Processes under test stopped before tests completed
    -- run_test.py: return code 1
    -- run_test.py: verify result file '/home/runner/work/harvester/harvester/.work/target_ws/build/task_planning/test_results/task_planning/test_launch_basic_task_planning_test.test.py.xunit.xml'
  >>>
build/task_planning/test_results/task_planning/test_launch_basic_task_planning_test.test.py.xunit.xml: 2 tests, 0 errors, 2 failures, 0 skipped
- task_planning.TestGTestWaitForCompletion test_gtest_run_complete
  <<< failure message
    Exception: Launch stopped before the active tests finished.

And the latest test result in colcon_ws/log/latest_test_result/logger_all.log says this:

20220410-0125/Test.xml': the root tag is neither 'testsuite' nor 'testsuites'

My test launch file:

    # -*- coding: utf-8 -*-
from ament_index_python.packages import get_package_share_directory
import launch
from launch.actions import TimerAction
from launch_ros.actions import Node
import launch_testing
import os
import sys
import unittest


def generate_test_description():

this_package_path = get_package_share_directory("task_planning")

sys.path.append(this_package_path + "/launch/")
from mtc_planning_launch_common import generate_common_launch_description

common_config = generate_common_launch_description()

basic_task_planning_gtest = Node(
    executable=launch.substitutions.PathJoinSubstitution(
        [
            launch.substitutions.LaunchConfiguration("test_binary_dir"),
            "basic_task_planning_test",
        ]
    ),
    output="screen",
    parameters=common_config,
)

return launch.LaunchDescription(
    [
        launch.actions.DeclareLaunchArgument(
            name="test_binary_dir",
            description="Binary directory of package "
            "containing test executables",
        ),
        basic_task_planning_gtest,
        launch_testing.actions.ReadyToTest(),
    ]
), {
    "basic_task_planning_gtest": basic_task_planning_gtest,
}


class TestGTestWaitForCompletion(unittest.TestCase):
    # Waits for test to complete, then waits a bit to make sure result files are generated
    def test_gtest_run_complete(self, basic_task_planning_gtest):
        self.proc_info.assertWaitForShutdown(basic_task_planning_gtest, timeout=4000.0)


@launch_testing.post_shutdown_test()
class TestGTestProcessPostShutdown(unittest.TestCase):
    # Checks if the test has been completed with acceptable exit codes
    def test_gtest_pass(self, proc_info, basic_task_planning_gtest):
        launch_testing.asserts.assertExitCodes(
            proc_info, process=basic_task_planning_gtest
        )
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2022-05-27 12:48:59 -0500

AndyZe gravatar image

I found this code/hack online. Putting it in the cpp of the test file worked:

namespace {

// This is a bit of a hack to make thread sanitizer ignore a race condition
// in the constructor of the rclcpp::Node
#if defined(__has_feature)
#if __has_feature(thread_sanitizer)
__attribute__((no_sanitize("thread")))
#endif
#endif
rclcpp::Node::SharedPtr
make_node(std::string const& name, rclcpp::NodeOptions const& options) {
  return std::make_shared<rclcpp::Node>(name, options);
}
}  // namespace
edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2022-04-09 20:42:09 -0500

Seen: 93 times

Last updated: May 27