import importlib.util import signal import subprocess import unittest from pathlib import Path from unittest import mock MODULE_PATH = Path(__file__).parents[1] / "tools" / "launcher_ui.py" SPEC = importlib.util.spec_from_file_location("launcher_ui", MODULE_PATH) launcher_ui = importlib.util.module_from_spec(SPEC) assert SPEC.loader is not None SPEC.loader.exec_module(launcher_ui) class LauncherCleanupTest(unittest.TestCase): def test_xrobotoolkit_cleanup_policy_only_stops_service_on_window_close(self) -> None: stop_all_patterns = set( launcher_ui._xrobotoolkit_cleanup_patterns(stop_pc_service=False) ) window_close_patterns = set( launcher_ui._xrobotoolkit_cleanup_patterns(stop_pc_service=True) ) self.assertLessEqual( {"RobotLinuxDemo.x86_64", "PXREAClientUnity"}, stop_all_patterns, ) self.assertNotIn("RoboticsServiceProcess", stop_all_patterns) self.assertIn("RoboticsServiceProcess", window_close_patterns) def test_close_and_stop_all_select_different_pc_service_policies(self) -> None: app = object.__new__(launcher_ui.LauncherApp) calls = [] class Root: destroyed = False def destroy(self) -> None: self.destroyed = True app.root = Root() app.stop_launched_processes = lambda **kwargs: calls.append(kwargs) or True app.kill_launched_processes() app.on_close_requested() self.assertEqual( calls, [ {"confirm": True, "notify": True, "stop_pc_service": False}, {"confirm": True, "notify": False, "stop_pc_service": True}, ], ) self.assertTrue(app.root.destroyed) def test_stop_all_keeps_oldest_pc_service_and_stops_duplicates(self) -> None: app = object.__new__(launcher_ui.LauncherApp) app.status = mock.Mock() app.close_related_terminal_windows = lambda: 0 def fake_check_output(command, **_kwargs): if command == ["pgrep", "-o", "-f", "RoboticsServiceProcess"]: return "101\n" if command == ["pgrep", "-f", "RoboticsServiceProcess"]: return "101\n202\n303\n" raise subprocess.CalledProcessError(1, command) with ( mock.patch.object( launcher_ui.subprocess, "check_output", side_effect=fake_check_output, ), mock.patch.object(launcher_ui.os, "kill") as kill, mock.patch.object(launcher_ui.time, "sleep"), ): app.stop_launched_processes( confirm=False, notify=False, stop_pc_service=False, ) self.assertEqual( kill.call_args_list, [ mock.call(202, signal.SIGTERM), mock.call(303, signal.SIGTERM), ], ) if __name__ == "__main__": unittest.main()