diff --git a/MODULE.bazel b/MODULE.bazel index 87828d09dd..ab09bef82d 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -175,10 +175,6 @@ pip.parse( use_repo(pip, "score_lifecycle_pip") bazel_dep(name = "score_itf", version = "0.5.0", dev_dependency = True) -single_version_override( - module_name = "score_itf", - patches = ["//patches:itf.patch"], -) oci = use_extension("@rules_oci//oci:extensions.bzl", "oci", dev_dependency = True) oci.pull( diff --git a/patches/itf.patch b/patches/itf.patch deleted file mode 100644 index f00a6e869b..0000000000 --- a/patches/itf.patch +++ /dev/null @@ -1,15 +0,0 @@ -# https://github.com/eclipse-score/itf/pull/127 - ---- score/itf/plugins/qemu/qemu_target.py -+++ score/itf/plugins/qemu/qemu_target.py -@@ -173,9 +173,7 @@ def execute_async(self, binary_path, args=None, cwd="/", **kwargs) -> QemuAsyncP - transport = ssh_ctx.get_paramiko_client().get_transport() - channel = transport.open_session() - channel.set_combine_stderr(True) -- inner = ( -- f"[ -r /etc/profile ] && . /etc/profile >/dev/null 2>&1; echo $$; cd {shlex.quote(cwd)} && {command}" -- ) -+ inner = f"[ -r /etc/profile ] && . /etc/profile >/dev/null 2>&1; echo $$; cd {shlex.quote(cwd)} && exec {command}" - channel.exec_command(f"sh -lc {shlex.quote(inner)}") - - # Read the PID from the first line of output. diff --git a/tests/integration/complex_monitoring/complex_monitoring.py b/tests/integration/complex_monitoring/complex_monitoring.py index c09131d63d..c802218e89 100644 --- a/tests/integration/complex_monitoring/complex_monitoring.py +++ b/tests/integration/complex_monitoring/complex_monitoring.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -32,16 +31,12 @@ def test_complex_monitoring(target, setup_test, assert_test_results, remote_test Expected Behaviour: Health monitor detects the missed heartbeats and triggers a recovery action, activating the fallback run target. """ - config_path = str(remote_test_dir / "etc/complex_monitoring.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/complex_monitoring.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=4.0, ) + assert process.wait() == 0 assert_test_results( {"component_complex_monitoring.xml", "control_client_test_driver.xml"} diff --git a/tests/integration/complex_monitoring/control_client_test_driver.cpp b/tests/integration/complex_monitoring/control_client_test_driver.cpp index 30eaad5da0..f742cef2cc 100644 --- a/tests/integration/complex_monitoring/control_client_test_driver.cpp +++ b/tests/integration/complex_monitoring/control_client_test_driver.cpp @@ -21,7 +21,7 @@ TEST(ComplexMonitoring, ControlClientTestDriver) { score::mw::lifecycle::ControlClient client; - ASSERT_TRUE(check_clean({test_end_location, fallback_file})); + ASSERT_TRUE(check_clean({fallback_file})); TEST_STEP("Report running") { diff --git a/tests/integration/crash_ignores_dependents/crash_ignores_dependents.py b/tests/integration/crash_ignores_dependents/crash_ignores_dependents.py index 0c55c3d56c..ed6fe3b47e 100644 --- a/tests/integration/crash_ignores_dependents/crash_ignores_dependents.py +++ b/tests/integration/crash_ignores_dependents/crash_ignores_dependents.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -31,15 +30,11 @@ def test_crash_ignores_dependents( Expected Behaviour: The process that depends on it is not interrupted or restarted. """ - new_config_path = str(remote_test_dir / "etc/crash_ignores_dependents.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/crash_ignores_dependents.bin")], cwd=str(remote_test_dir), - args=["-c", new_config_path], - timeout_s=6.0, ) + assert process.wait() == 0 assert_test_results({"test_process.xml", "process_crashing_once.xml"}) diff --git a/tests/integration/crash_ignores_dependents/test_process.cpp b/tests/integration/crash_ignores_dependents/test_process.cpp index 57a276c13a..e988091d53 100644 --- a/tests/integration/crash_ignores_dependents/test_process.cpp +++ b/tests/integration/crash_ignores_dependents/test_process.cpp @@ -25,8 +25,7 @@ TEST(CrashIgnoresDependents, TestProcess) TEST_STEP("Check this is the first start") { - ASSERT_TRUE(check_clean({test_end_location, started_file, crash_file})) - << "Process was started more than once!"; + ASSERT_TRUE(check_clean({started_file, crash_file})) << "Process was started more than once!"; ASSERT_TRUE(touch_file(started_file)) << "Failed to deploy file!"; } diff --git a/tests/integration/crash_on_startup/control_client_test_driver.cpp b/tests/integration/crash_on_startup/control_client_test_driver.cpp index 495a5f596a..7c05214e64 100644 --- a/tests/integration/crash_on_startup/control_client_test_driver.cpp +++ b/tests/integration/crash_on_startup/control_client_test_driver.cpp @@ -21,8 +21,7 @@ TEST(CrashOnStartup, ControlClientTestDriver) { score::mw::lifecycle::ControlClient client; - ASSERT_TRUE( - check_clean({crashCountPath(1), crashCountPath(2), crashCountPath(3), test_end_location, fallback_file})); + ASSERT_TRUE(check_clean({crashCountPath(1), crashCountPath(2), crashCountPath(3), fallback_file})); TEST_STEP("Report running") { diff --git a/tests/integration/crash_on_startup/crash_on_startup.py b/tests/integration/crash_on_startup/crash_on_startup.py index 7e2bada2fa..242fd0ff24 100644 --- a/tests/integration/crash_on_startup/crash_on_startup.py +++ b/tests/integration/crash_on_startup/crash_on_startup.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import ( assert_test_results, @@ -44,16 +43,12 @@ def test_crash_on_startup( Expected Behaviour: Process startup fails and therefore run target activation fails. Launch manager executes recovery action which switches to fallback run target. """ - config_path = str(remote_test_dir / "etc/crash_on_startup.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/crash_on_startup.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=10.0, ) + assert process.wait() == 0 # Each crashing process writes its own report file named after the number of times it crashes, so the # reports of the different run targets no longer overwrite each other. The process crashing once is not diff --git a/tests/integration/fallback_to_same_target_restarts/control_client_test_driver.cpp b/tests/integration/fallback_to_same_target_restarts/control_client_test_driver.cpp index 5fc6d6339b..2acad50df1 100644 --- a/tests/integration/fallback_to_same_target_restarts/control_client_test_driver.cpp +++ b/tests/integration/fallback_to_same_target_restarts/control_client_test_driver.cpp @@ -30,7 +30,7 @@ TEST(FallbackToSameTargetRestarts, ControlClientTestDriver) const std::string_view process_file = "process_started_normally"; - ASSERT_TRUE(check_clean({test_end_location, process_file})); + ASSERT_TRUE(check_clean({process_file})); // Establish communication with launch manager TEST_STEP("Report running") { diff --git a/tests/integration/fallback_to_same_target_restarts/fallback_to_same_target_restarts.py b/tests/integration/fallback_to_same_target_restarts/fallback_to_same_target_restarts.py index 8c22d97c99..de864f05ca 100644 --- a/tests/integration/fallback_to_same_target_restarts/fallback_to_same_target_restarts.py +++ b/tests/integration/fallback_to_same_target_restarts/fallback_to_same_target_restarts.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -31,15 +30,11 @@ def test_fallback_to_same_target_restarts( Expected Behaviour: The process is relaunched and completes normally. """ - new_config_path = str(remote_test_dir / "etc/fallback_to_same_target_restarts.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/fallback_to_same_target_restarts.bin")], cwd=str(remote_test_dir), - args=["-c", new_config_path], - timeout_s=4.0, ) + assert process.wait() == 0 assert_test_results({"control_client_test_driver.xml", "process_crashing_once.xml"}) diff --git a/tests/integration/incorrect_config_non_reporting/test_incorrect_config_non_reporting.py b/tests/integration/incorrect_config_non_reporting/test_incorrect_config_non_reporting.py index 6ef7069af7..b9a048323f 100644 --- a/tests/integration/incorrect_config_non_reporting/test_incorrect_config_non_reporting.py +++ b/tests/integration/incorrect_config_non_reporting/test_incorrect_config_non_reporting.py @@ -10,8 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -import logging -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -31,15 +29,11 @@ def test_incorrect_config_non_reporting( Expected Outcome: Process does not crash. """ - config_path = str(remote_test_dir / "etc/non_reporting_config.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/non_reporting_config.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=2.0, ) + assert process.wait() == 0 assert_test_results({"non_reporting_process.xml"}) diff --git a/tests/integration/lm_shutdown_during_rt_switch/control_client_test_driver.cpp b/tests/integration/lm_shutdown_during_rt_switch/control_client_test_driver.cpp index e3c2b8207d..0117badf65 100644 --- a/tests/integration/lm_shutdown_during_rt_switch/control_client_test_driver.cpp +++ b/tests/integration/lm_shutdown_during_rt_switch/control_client_test_driver.cpp @@ -33,7 +33,7 @@ TEST(LmShutdownDuringRtSwitch, ControlClient) { score::mw::lifecycle::ControlClient client{}; - ASSERT_TRUE(check_clean({test_end_location, a_started, a_terminating, c_started})); + ASSERT_TRUE(check_clean({a_started, a_terminating, c_started})); TEST_STEP("Report running") { diff --git a/tests/integration/lm_shutdown_during_rt_switch/lm_shutdown_during_rt_switch.py b/tests/integration/lm_shutdown_during_rt_switch/lm_shutdown_during_rt_switch.py index 52cd0141db..a72074d9a0 100644 --- a/tests/integration/lm_shutdown_during_rt_switch/lm_shutdown_during_rt_switch.py +++ b/tests/integration/lm_shutdown_during_rt_switch/lm_shutdown_during_rt_switch.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -42,19 +41,12 @@ def test_lm_shutdown(target, setup_test, assert_test_results, remote_test_dir): processes it owns, and exits cleanly. """ - new_config_path = str(remote_test_dir / "etc/lm_shutdown_during_rt_switch.bin") - a_terminating = remote_test_dir / "component_a_terminating" - - # Run until `component_a_terminating` is deployed so we can request shutdown during - # the transition to run target c - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=a_terminating, + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/lm_shutdown_during_rt_switch.bin")], cwd=str(remote_test_dir), - args=["-c", new_config_path], - timeout_s=10.0, ) + assert process.wait() == 0 # component_c never runs (the pending switch was cancelled), so it produces no XML # result; component_a and the control client shut down gracefully. The control diff --git a/tests/integration/lm_shutdown_during_switch_to_off/control_client_test_driver.cpp b/tests/integration/lm_shutdown_during_switch_to_off/control_client_test_driver.cpp index 9a8187e62b..d96d5f3432 100644 --- a/tests/integration/lm_shutdown_during_switch_to_off/control_client_test_driver.cpp +++ b/tests/integration/lm_shutdown_during_switch_to_off/control_client_test_driver.cpp @@ -36,7 +36,7 @@ TEST(LmShutdownDuringSwitchToOff, ControlClient) { score::mw::lifecycle::ControlClient client{}; - ASSERT_TRUE(check_clean({test_end_location, a_started, a_terminating})); + ASSERT_TRUE(check_clean({a_started, a_terminating})); const auto pid = getpid(); const std::string step_msg = "Report running with pid == " + std::to_string(pid); diff --git a/tests/integration/lm_shutdown_during_switch_to_off/lm_shutdown_during_switch_to_off.py b/tests/integration/lm_shutdown_during_switch_to_off/lm_shutdown_during_switch_to_off.py index a356415339..8b337b43ad 100644 --- a/tests/integration/lm_shutdown_during_switch_to_off/lm_shutdown_during_switch_to_off.py +++ b/tests/integration/lm_shutdown_during_switch_to_off/lm_shutdown_during_switch_to_off.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -43,19 +42,12 @@ def test_lm_shutdown(target, setup_test, assert_test_results, remote_test_dir): force-terminated. """ - new_config_path = str(remote_test_dir / "etc/lm_shutdown_during_switch_to_off.bin") - a_terminating = remote_test_dir / "component_a_terminating" - - # Run until `component_a_terminating` is deployed so we can send SIGTERM - # to launch manager during the transition to Off - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=a_terminating, + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/lm_shutdown_during_switch_to_off.bin")], cwd=str(remote_test_dir), - args=["-c", new_config_path], - timeout_s=10.0, ) + assert process.wait() == 0 # Both processes are stopped gracefully as part of the switch to Off and produce # their XML results: the control client is terminated when the switch to Off diff --git a/tests/integration/parallel_launch/control_client_test_driver.cpp b/tests/integration/parallel_launch/control_client_test_driver.cpp index c1f21204ae..376fd1e4b0 100644 --- a/tests/integration/parallel_launch/control_client_test_driver.cpp +++ b/tests/integration/parallel_launch/control_client_test_driver.cpp @@ -45,8 +45,6 @@ TEST(ParallelLaunch, ControlClientTestDriver) { score::mw::lifecycle::ControlClient client; - ASSERT_TRUE(check_clean({test_end_location})); - for (const auto id : kComponentIds) { ASSERT_TRUE(check_clean({"start_" + std::string{id}, "running_" + std::string{id}})); diff --git a/tests/integration/parallel_launch/parallel_launch.py b/tests/integration/parallel_launch/parallel_launch.py index b2664c6d3e..d43f7ef7bf 100644 --- a/tests/integration/parallel_launch/parallel_launch.py +++ b/tests/integration/parallel_launch/parallel_launch.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -33,16 +32,12 @@ def test_parallel_launch(target, setup_test, assert_test_results, remote_test_di Expected Behaviour: The latest start timestamp precedes the earliest running timestamp. """ - config_path = str(remote_test_dir / "etc/parallel_launch.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/parallel_launch.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=8.0, ) + assert process.wait() == 0 assert_test_results( { diff --git a/tests/integration/process_complex_rep_failure/control_client_test_driver.cpp b/tests/integration/process_complex_rep_failure/control_client_test_driver.cpp index 07c210dfd1..df4efbea26 100644 --- a/tests/integration/process_complex_rep_failure/control_client_test_driver.cpp +++ b/tests/integration/process_complex_rep_failure/control_client_test_driver.cpp @@ -30,7 +30,7 @@ TEST(RecoveryActionComplexRepFailure, ControlClientTestDriver) { score::mw::lifecycle::ControlClient client; - ASSERT_TRUE(check_clean({test_end_location, fallback_file})); + ASSERT_TRUE(check_clean({fallback_file})); // Establish communication with launch manager TEST_STEP("Report running from ControlClientTestDriver") diff --git a/tests/integration/process_complex_rep_failure/process_complex_rep_failure.py b/tests/integration/process_complex_rep_failure/process_complex_rep_failure.py index 1ec7055955..ca5ff0a709 100644 --- a/tests/integration/process_complex_rep_failure/process_complex_rep_failure.py +++ b/tests/integration/process_complex_rep_failure/process_complex_rep_failure.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -41,16 +40,12 @@ def test_recovery_action_complex_rep_failure( The recovery action switches to the fallback run target, the activation of the fallback run target is verified in the test. """ - config_path = str(remote_test_dir / "etc/process_complex_rep_failure.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/process_complex_rep_failure.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=10.0, ) + assert process.wait() == 0 assert_test_results( {"control_client_test_driver.xml", "complex_reporting_process.xml"} diff --git a/tests/integration/process_crash_monitoring/control_client_test_driver.cpp b/tests/integration/process_crash_monitoring/control_client_test_driver.cpp index b6ff3c3a4d..5d9a0a1aa7 100644 --- a/tests/integration/process_crash_monitoring/control_client_test_driver.cpp +++ b/tests/integration/process_crash_monitoring/control_client_test_driver.cpp @@ -28,7 +28,7 @@ TEST(ProcessCrashMonitoring, ControlClientTestDriver) { score::mw::lifecycle::ControlClient client; - ASSERT_TRUE(check_clean({test_end_location, fallback_file})); + ASSERT_TRUE(check_clean({fallback_file})); // Establish communication with launch manager TEST_STEP("Report running") { diff --git a/tests/integration/process_crash_monitoring/process_crash_monitoring.py b/tests/integration/process_crash_monitoring/process_crash_monitoring.py index 72f6a30411..6de0bfff83 100644 --- a/tests/integration/process_crash_monitoring/process_crash_monitoring.py +++ b/tests/integration/process_crash_monitoring/process_crash_monitoring.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -31,16 +30,12 @@ def test_process_crash_monitoring( Expected Behaviour: Launch manager detects the crash and activates the fallback run target. """ - config_path = str(remote_test_dir / "etc/process_crash_monitoring.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/process_crash_monitoring.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=10.0, ) + assert process.wait() == 0 assert_test_results( {"control_client_test_driver.xml", "process_crashing_on_runtime.xml"} diff --git a/tests/integration/process_fd_leak/control_client_test_driver.cpp b/tests/integration/process_fd_leak/control_client_test_driver.cpp index ec80122a92..80611473e3 100644 --- a/tests/integration/process_fd_leak/control_client_test_driver.cpp +++ b/tests/integration/process_fd_leak/control_client_test_driver.cpp @@ -69,8 +69,7 @@ TEST(ControlClientFDs, FindOpenFDs) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); } - - ASSERT_TRUE(touch_file(test_end_location)); + EXPECT_EQ(kill(getppid(), SIGTERM), 0); } } @@ -79,7 +78,7 @@ int main(int argc, char** argv) g_argc = argc; g_argv = argv; - // test end file is made in the test so that we block to wait for other + // test end is signalled in the test so that we block to wait for other // procs to finish TestRunner runner{__FILE__, TerminationBehavior::kWait, TerminationNotification::kNone}; diff --git a/tests/integration/process_fd_leak/process_fd_leak.py b/tests/integration/process_fd_leak/process_fd_leak.py index 2f524521c8..bab5c2359c 100644 --- a/tests/integration/process_fd_leak/process_fd_leak.py +++ b/tests/integration/process_fd_leak/process_fd_leak.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -25,16 +24,12 @@ def test_process_fd_leak(target, setup_test, assert_test_results, remote_test_di """Tests the inherited file descriptors from LCM for Native, Reporting and State_Manager application types.""" - config_path = str(remote_test_dir / "etc/process_fd_leak.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/process_fd_leak.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=2.0, ) + assert process.wait() == 0 # That the process is started and an XML file is produced verifies feat_req__lifecycle__launch_support assert_test_results( diff --git a/tests/integration/process_launch_args/process_initial.cpp b/tests/integration/process_launch_args/process_initial.cpp index b552cf6d5e..b4f4b168d5 100644 --- a/tests/integration/process_launch_args/process_initial.cpp +++ b/tests/integration/process_launch_args/process_initial.cpp @@ -27,7 +27,6 @@ char** g_argv; TEST(ProcessLaunchArgs, ProcessInitial) { - ASSERT_TRUE(check_clean({test_end_location})); // Then, the process is started and: TEST_STEP("Report running") { diff --git a/tests/integration/process_launch_args/process_launch_args.py b/tests/integration/process_launch_args/process_launch_args.py index 2311894a0b..625fae7450 100644 --- a/tests/integration/process_launch_args/process_launch_args.py +++ b/tests/integration/process_launch_args/process_launch_args.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -34,16 +33,12 @@ def test_process_launch_args(target, setup_test, assert_test_results, remote_tes Expected Behaviour: Process starts successfully, reports running, and receives the configured argument value. """ - config_path = str(remote_test_dir / "etc/process_launch_args.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/process_launch_args.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=2.0, ) + assert process.wait() == 0 # That the process is started and an XML file is produced verifies feat_req__lifecycle__launch_support assert_test_results({"process_initial.xml"}) diff --git a/tests/integration/process_simple_rep_failure/control_client_test_driver.cpp b/tests/integration/process_simple_rep_failure/control_client_test_driver.cpp index 642a8091b9..26ab7820b3 100644 --- a/tests/integration/process_simple_rep_failure/control_client_test_driver.cpp +++ b/tests/integration/process_simple_rep_failure/control_client_test_driver.cpp @@ -30,7 +30,7 @@ TEST(RecoveryActionSimpleRepFailure, ControlClientTestDriver) { score::mw::lifecycle::ControlClient client; - ASSERT_TRUE(check_clean({test_end_location, fallback_file})); + ASSERT_TRUE(check_clean({fallback_file})); // Establish communication with launch manager TEST_STEP("Report running from ControlClientTestDriver") diff --git a/tests/integration/process_simple_rep_failure/process_simple_rep_failure.py b/tests/integration/process_simple_rep_failure/process_simple_rep_failure.py index 7fda53b829..41cffc93dd 100644 --- a/tests/integration/process_simple_rep_failure/process_simple_rep_failure.py +++ b/tests/integration/process_simple_rep_failure/process_simple_rep_failure.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -41,16 +40,12 @@ def test_recovery_action_simple_rep_failure( The recovery action switches to the fallback run target, the activation of the fallback run target is verified in the test. """ - config_path = str(remote_test_dir / "etc/process_simple_rep_failure.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/process_simple_rep_failure.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=10.0, ) + assert process.wait() == 0 assert_test_results( {"control_client_test_driver.xml", "process_simple_reporting.xml"} diff --git a/tests/integration/process_wrong_binary_failure/control_client_test_driver.cpp b/tests/integration/process_wrong_binary_failure/control_client_test_driver.cpp index 77ec43b2b8..805fffd38b 100644 --- a/tests/integration/process_wrong_binary_failure/control_client_test_driver.cpp +++ b/tests/integration/process_wrong_binary_failure/control_client_test_driver.cpp @@ -20,7 +20,7 @@ TEST(MissingBinaryFailure, ControlClientTestDriver) { score::mw::lifecycle::ControlClient client; - ASSERT_TRUE(check_clean({test_end_location, fallback_file})); + ASSERT_TRUE(check_clean({fallback_file})); TEST_STEP("Report kRunning from ControlClientTestDriver") { diff --git a/tests/integration/process_wrong_binary_failure/process_wrong_binary_failure.py b/tests/integration/process_wrong_binary_failure/process_wrong_binary_failure.py index 35ee446b93..3e141de0ae 100644 --- a/tests/integration/process_wrong_binary_failure/process_wrong_binary_failure.py +++ b/tests/integration/process_wrong_binary_failure/process_wrong_binary_failure.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -29,15 +28,11 @@ def test_process_wrong_binary_failure( results in a failure and triggers the configured recovery action (switch to fallback run target). """ - config_path = str(remote_test_dir / "etc/process_wrong_binary_failure.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/process_wrong_binary_failure.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=6, ) + assert process.wait() == 0 assert_test_results({"control_client_test_driver.xml"}) diff --git a/tests/integration/rt_running_when_process_exits/control_client_test_driver.cpp b/tests/integration/rt_running_when_process_exits/control_client_test_driver.cpp index 13f95d27c0..2e08a24909 100644 --- a/tests/integration/rt_running_when_process_exits/control_client_test_driver.cpp +++ b/tests/integration/rt_running_when_process_exits/control_client_test_driver.cpp @@ -45,7 +45,7 @@ TEST(RtRunningWhenProcessExits, ControlClientTestDriver) // kSlowSetupOutput is checked too: its later presence must be a reliable signal that // the slow setup component terminated during *this* run, not leftover from a previous one. - ASSERT_TRUE(check_clean({test_end_location, kSlowSetupOutput})); + ASSERT_TRUE(check_clean({kSlowSetupOutput})); TEST_STEP("Report running") { diff --git a/tests/integration/rt_running_when_process_exits/filesystem_reader.cpp b/tests/integration/rt_running_when_process_exits/filesystem_reader.cpp index bfd564445b..cf520282ae 100644 --- a/tests/integration/rt_running_when_process_exits/filesystem_reader.cpp +++ b/tests/integration/rt_running_when_process_exits/filesystem_reader.cpp @@ -38,8 +38,6 @@ constexpr std::string_view kSetupOutputFile = "setup_filesystem_output.txt"; // (it writes a marker file and exits) before starting filesystem_reader. TEST(RtRunningWhenProcessExits, FilesystemReader) { - ASSERT_TRUE(check_clean({test_end_location})); - TEST_STEP("Report running") { score::mw::lifecycle::report_running(); diff --git a/tests/integration/rt_running_when_process_exits/rt_running_when_process_exits.py b/tests/integration/rt_running_when_process_exits/rt_running_when_process_exits.py index 09f2248da8..e3d6ebee10 100644 --- a/tests/integration/rt_running_when_process_exits/rt_running_when_process_exits.py +++ b/tests/integration/rt_running_when_process_exits/rt_running_when_process_exits.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -53,18 +52,11 @@ def test_rt_running_when_process_exits( """ - # launch manager will simply ignore the arguments if run with --//config:use_new_configuration=False. - # the old configuration will be used, which is the default behavior. - # The new configuration will be used if run with --//config:use_new_configuration=True - new_config_path = str(remote_test_dir / "etc/rt_running_when_process_exits.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/rt_running_when_process_exits.bin")], cwd=str(remote_test_dir), - args=["-c", new_config_path], - timeout_s=3.0, ) + assert process.wait() == 0 assert_test_results({"control_client_test_driver.xml", "filesystem_reader.xml"}) diff --git a/tests/integration/sandbox_options/sandbox_options.py b/tests/integration/sandbox_options/sandbox_options.py index 6b8be4aad4..e34bb9bef3 100644 --- a/tests/integration/sandbox_options/sandbox_options.py +++ b/tests/integration/sandbox_options/sandbox_options.py @@ -14,7 +14,6 @@ import subprocess import pytest from score.itf.plugins.core import determine_target_scope -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -130,16 +129,12 @@ def test_sandbox_options(target, setup_test, assert_test_results, remote_test_di Expected Behaviour: All run target transitions complete successfully and all processes report running. """ - config_path = str(remote_test_dir / "etc/sandbox_options.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/sandbox_options.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=3.0, ) + assert process.wait() == 0 # sandbox_options_process_a is configured with a custom working directory ("working_dir": "/tmp" # in sandbox_options.json), so its XML result file is written there rather than into diff --git a/tests/integration/shutdown_signal/control_client_test_driver.cpp b/tests/integration/shutdown_signal/control_client_test_driver.cpp index e10c6db689..c308a5c2f8 100644 --- a/tests/integration/shutdown_signal/control_client_test_driver.cpp +++ b/tests/integration/shutdown_signal/control_client_test_driver.cpp @@ -36,7 +36,7 @@ TEST(ShutdownSignal, Daemon) { score::mw::lifecycle::ControlClient client{}; - ASSERT_TRUE(check_clean({test_end_location, sigterm_received_file})); + ASSERT_TRUE(check_clean({sigterm_received_file})); TEST_STEP("Control daemon report running") { diff --git a/tests/integration/shutdown_signal/shutdown_signal.py b/tests/integration/shutdown_signal/shutdown_signal.py index 862e3fe0be..ef1cc77def 100644 --- a/tests/integration/shutdown_signal/shutdown_signal.py +++ b/tests/integration/shutdown_signal/shutdown_signal.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -42,16 +41,12 @@ def test_shutdown_signal(target, setup_test, assert_test_results, remote_test_di that PID no longer existing, since the process never self-terminates). """ - new_config_path = str(remote_test_dir / "etc/shutdown_signal.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/shutdown_signal.bin")], cwd=str(remote_test_dir), - args=["-c", new_config_path], - timeout_s=10.0, ) + assert process.wait() == 0 assert_test_results( {"control_client_test_driver.xml", "shutdown_signal_process.xml"} diff --git a/tests/integration/smoke/control_client_test_driver.cpp b/tests/integration/smoke/control_client_test_driver.cpp index 6c54ceaf91..994ab59c43 100644 --- a/tests/integration/smoke/control_client_test_driver.cpp +++ b/tests/integration/smoke/control_client_test_driver.cpp @@ -22,7 +22,6 @@ TEST(Smoke, Daemon) { score::mw::lifecycle::ControlClient client{}; - ASSERT_TRUE(check_clean({test_end_location})); TEST_STEP("Control daemon report running") { // report running diff --git a/tests/integration/smoke/smoke.py b/tests/integration/smoke/smoke.py index b1109a2cab..759e40aa3d 100644 --- a/tests/integration/smoke/smoke.py +++ b/tests/integration/smoke/smoke.py @@ -10,8 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -import logging -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -30,15 +28,11 @@ def test_smoke(target, setup_test, assert_test_results, remote_test_dir): Expected Behaviour: All run target transitions complete successfully and all processes report running. """ - config_path = str(remote_test_dir / "etc/lifecycle_smoketest.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/lifecycle_smoketest.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=3.0, ) + assert process.wait() == 0 assert_test_results({"control_client_test_driver.xml", "gtest_process.xml"}) diff --git a/tests/integration/switch_run_target/control_client_test_driver.cpp b/tests/integration/switch_run_target/control_client_test_driver.cpp index f532dbb0b3..26dba8a5c8 100644 --- a/tests/integration/switch_run_target/control_client_test_driver.cpp +++ b/tests/integration/switch_run_target/control_client_test_driver.cpp @@ -36,7 +36,7 @@ TEST(SwitchRunTarget, ControlClientTestDriver) { score::mw::lifecycle::ControlClient client; - ASSERT_TRUE(check_clean({test_end_location, a_started, b_started, d_started, e_started})); + ASSERT_TRUE(check_clean({a_started, b_started, d_started, e_started})); TEST_STEP("Report running") { score::mw::lifecycle::report_running(); diff --git a/tests/integration/switch_run_target/switch_run_target.py b/tests/integration/switch_run_target/switch_run_target.py index 8a906c0def..1fdb5c2558 100644 --- a/tests/integration/switch_run_target/switch_run_target.py +++ b/tests/integration/switch_run_target/switch_run_target.py @@ -10,7 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -from tests.utils.testing_utils.run_until_file_deployed import run_until_file_deployed from tests.utils.testing_utils.setup_test import setup_test from tests.utils.testing_utils.test_results import assert_test_results from attribute_plugin import add_test_properties @@ -37,16 +36,12 @@ def test_switch_run_target(target, setup_test, assert_test_results, remote_test_ Expected Behaviour: During activation resp. deactivation of run_target_a, component B starts before component A, component D is started, component A terminates before component B, and component E (not in the dependency chain) is never launched. """ - config_path = str(remote_test_dir / "etc/switch_run_target.bin") - - run_until_file_deployed( - target=target, - binary_path=str(remote_test_dir / "launch_manager"), - file_path=remote_test_dir.parent / "test_end", + process = target.execute_async( + str(remote_test_dir / "launch_manager"), + args=["-c", str(remote_test_dir / "etc/switch_run_target.bin")], cwd=str(remote_test_dir), - args=["-c", config_path], - timeout_s=2.0, ) + assert process.wait() == 0 # Process E never starts assert_test_results( diff --git a/tests/utils/test_helper/process_hanging_on_sigterm.cpp b/tests/utils/test_helper/process_hanging_on_sigterm.cpp index bcdb28adbc..c63392c8c4 100644 --- a/tests/utils/test_helper/process_hanging_on_sigterm.cpp +++ b/tests/utils/test_helper/process_hanging_on_sigterm.cpp @@ -57,7 +57,7 @@ TEST(ProcessHangingOnSigterm, StallsDuringTermination) TEST_STEP("Stall during termination to keep the run-target switch in progress") { - EXPECT_TRUE(touch_file(signal_file("terminating"))) << "failed to deploy file"; + EXPECT_EQ(kill(getppid(), SIGTERM), 0); static_cast(sleep(kTerminationDelaySeconds)); } } diff --git a/tests/utils/test_helper/test_helper.hpp b/tests/utils/test_helper/test_helper.hpp index 82c9429469..e11320ffa1 100644 --- a/tests/utils/test_helper/test_helper.hpp +++ b/tests/utils/test_helper/test_helper.hpp @@ -59,10 +59,6 @@ inline std::string crashCountPath(const int crashes_until_success) return std::string{crash_count_file} + "_" + std::to_string(crashes_until_success); } -/// @brief Where to store the test_end signal file. This must be kept consistent with where the test framework -/// searches for files. -constexpr std::string_view test_end_location = "../test_end"; - /// @brief Call at the start of a test to check for leftover files from a previous run /// Files can be leftover when running manually on the host system, but otherwise are cleaned up /// by the test framework. @@ -158,11 +154,7 @@ class TestRunner if (m_termination_notification == TerminationNotification::kTestEnd) { - const auto res = touch_file(test_end_location); - if (!res) - { - std::cerr << res.failure_message() << std::endl; - } + assert(kill(getppid(), SIGTERM) == 0); } } diff --git a/tests/utils/test_helper/verification_process.cpp b/tests/utils/test_helper/verification_process.cpp index 34845bccca..d29517726a 100644 --- a/tests/utils/test_helper/verification_process.cpp +++ b/tests/utils/test_helper/verification_process.cpp @@ -50,9 +50,9 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - if (touch_test_end && !touch_file(test_end_location)) + if (touch_test_end && kill(getppid(), SIGTERM) != 0) { - std::cout << "Failed to write test_end file!" << std::endl; + std::cout << "Failed to signal test end!" << std::endl; return EXIT_FAILURE; } diff --git a/tests/utils/testing_utils/BUILD b/tests/utils/testing_utils/BUILD index fd474ebf5e..875879a6e1 100644 --- a/tests/utils/testing_utils/BUILD +++ b/tests/utils/testing_utils/BUILD @@ -20,7 +20,6 @@ exports_files( py_library( name = "testing_utils", srcs = [ - "run_until_file_deployed.py", "setup_test.py", "test_results.py", ], diff --git a/tests/utils/testing_utils/run_until_file_deployed.py b/tests/utils/testing_utils/run_until_file_deployed.py deleted file mode 100644 index d765e11038..0000000000 --- a/tests/utils/testing_utils/run_until_file_deployed.py +++ /dev/null @@ -1,75 +0,0 @@ -# ******************************************************************************* -# Copyright (c) 2026 Contributors to the Eclipse Foundation -# -# See the NOTICE file(s) distributed with this work for additional -# information regarding copyright ownership. -# -# This program and the accompanying materials are made available under the -# terms of the Apache License Version 2.0 which is available at -# https://www.apache.org/licenses/LICENSE-2.0 -# -# SPDX-License-Identifier: Apache-2.0 -# ******************************************************************************* -import logging -import time - -from score.itf.core.process.async_process import AsyncProcess -from score.itf.core.target.target import Target - -logger = logging.getLogger(__name__) - - -def run_until_file_deployed( - target: Target, - binary_path: str, - file_path: str, - timeout_s: float = 30.0, - poll_interval_s: float = 0.5, - args=None, - cwd: str = "/", -) -> AsyncProcess: - """Start a binary and block until a file appears on the target, then stop the process. - - :param target: the QemuTarget or DockerTarget to run on. - :param binary_path: path to the binary to execute on the target. - :param file_path: path of the file to wait for on the target. - :param timeout_s: maximum seconds to wait for the file (default: 30). - :param poll_interval_s: seconds between file checks (default: 0.5). - :param args: optional list of arguments to pass to the binary. - :param cwd: working directory on the target (default: "/"). - :return: the stopped :class:`AsyncProcess` handle. - :raises TimeoutError: if the file does not appear within *timeout_s*. - :raises RuntimeError: if the process exits before the file appears. - """ - - exit_code, _ = target.execute(f"test -f {file_path}") - if exit_code == 0: - target.execute(f"rm {file_path}") - - proc = target.execute_async(binary_path, args=args, cwd=cwd) - - deadline = time.monotonic() + timeout_s - while time.monotonic() < deadline: - if not proc.is_running(): - raise RuntimeError( - f"Process '{binary_path}' exited (code {proc.get_exit_code()}) " - f"before '{file_path}' appeared." - f"stdout: {proc.get_output()}" - ) - - exit_code, _ = target.execute(f"test -f {file_path}") - if exit_code == 0: - exit_code = proc.stop() - assert exit_code == 0, ( - f"LCM did not exit cleanly, it died with code {exit_code}" - ) - return proc - logger.debug(f"Waiting for {file_path}") - - time.sleep(poll_interval_s) - - proc.stop() - raise TimeoutError( - f"File '{file_path}' did not appear within {timeout_s}s " - f"after starting '{binary_path}'." - )