diff --git a/checkbox-support/checkbox_support/helpers/timeout.py b/checkbox-support/checkbox_support/helpers/timeout.py index beb2a73fb6..8a617bf03e 100644 --- a/checkbox-support/checkbox_support/helpers/timeout.py +++ b/checkbox-support/checkbox_support/helpers/timeout.py @@ -127,7 +127,14 @@ def _f(*args, **kwargs): process = Process(target=_f, args=args, kwargs=kwargs) process.start() - process.join(timeout_s) + try: + process.join(timeout_s) + except BaseException: + # If an exception is raised in the main process, we will kill the + # process tree + kill_tree(process.pid) + # Re-raise so the parent can exit + raise if process.is_alive(): # this tries to kill the whole process tree, not just the child. diff --git a/checkbox-support/checkbox_support/tests/test_timeout.py b/checkbox-support/checkbox_support/tests/test_timeout.py index ab02e05399..b00b1d30a7 100644 --- a/checkbox-support/checkbox_support/tests/test_timeout.py +++ b/checkbox-support/checkbox_support/tests/test_timeout.py @@ -86,6 +86,12 @@ def test_function_exception_propagation(self): with self.assertRaises(ValueError): run_with_timeout(some_exception_raiser, 1) + @patch("checkbox_support.helpers.timeout.Process.join") + def test_function_exception_propagation_in_process(self, mock_join): + mock_join.side_effect = KeyboardInterrupt() + with self.assertRaises(BaseException): + run_with_timeout(heavy_function, 1) + def test_function_systemexit_propagation(self): with self.assertRaises(SystemExit): system_exit_raiser()