diff --git a/launch/launch/actions/execute_process.py b/launch/launch/actions/execute_process.py index ad4f089dc..334f61956 100644 --- a/launch/launch/actions/execute_process.py +++ b/launch/launch/actions/execute_process.py @@ -96,7 +96,7 @@ def __init__( 'sigterm_timeout', default=5), sigkill_timeout: SomeSubstitutionsType = LaunchConfiguration( 'sigkill_timeout', default=5), - emulate_tty: bool = False, + emulate_tty: bool = True, prefix: Optional[SomeSubstitutionsType] = None, output: Text = 'log', output_format: Text = '[{this.name}] {line}', @@ -175,7 +175,7 @@ def __init__( as a string or a list of strings and Substitutions to be resolved at runtime, defaults to the LaunchConfiguration called 'sigkill_timeout' - :param: emulate_tty emulate a tty (terminal), defaults to False, but can + :param: emulate_tty emulate a tty (terminal), defaults to True, but can be overridden with the LaunchConfiguration called 'emulate_tty', the value of which is evaluated as true or false according to :py:func:`evaluate_condition_expression`. @@ -345,6 +345,8 @@ def __on_signal_process_event( raise RuntimeError('Signal event received before execution.') if self._subprocess_transport is None: raise RuntimeError('Signal event received before subprocess transport available.') + if self._subprocess_protocol is None: + raise RuntimeError('Signal event received before subprocess protocol available.') if self._subprocess_protocol.complete.done(): # the process is done or is cleaning up, no need to signal self.__logger.debug( @@ -390,6 +392,8 @@ def __on_process_stdin( def __on_process_stdout( self, event: ProcessIO ) -> Optional[SomeActionsType]: + if self.__stdout_buffer.closed: + raise RuntimeError('OnProcessIO (stdout) received after stdout buffer closed.') self.__stdout_buffer.write(event.text.decode(errors='replace')) self.__stdout_buffer.seek(0) last_line = None @@ -409,6 +413,8 @@ def __on_process_stdout( def __on_process_stderr( self, event: ProcessIO ) -> Optional[SomeActionsType]: + if self.__stderr_buffer.closed: + raise RuntimeError('OnProcessIO (stderr) received after stderr buffer closed.') self.__stderr_buffer.write(event.text.decode(errors='replace')) self.__stderr_buffer.seek(0) last_line = None diff --git a/launch/test/launch/actions/test_emulate_tty.py b/launch/test/launch/actions/test_emulate_tty.py index b9d874d2b..81200a05d 100644 --- a/launch/test/launch/actions/test_emulate_tty.py +++ b/launch/test/launch/actions/test_emulate_tty.py @@ -36,7 +36,7 @@ def tty_expected_unless_windows(): @pytest.mark.parametrize('test_input,expected', [ # use the default defined by ExecuteProcess - (None, not tty_expected_unless_windows()), + (None, tty_expected_unless_windows()), # redundantly override the default via LaunchConfiguration ('true', tty_expected_unless_windows()), # override the default via LaunchConfiguration diff --git a/launch_testing/launch_testing/test_runner.py b/launch_testing/launch_testing/test_runner.py index 356f3a012..360f325db 100644 --- a/launch_testing/launch_testing/test_runner.py +++ b/launch_testing/launch_testing/test_runner.py @@ -59,7 +59,6 @@ def __init__(self, self._test_tr = threading.Thread( target=self._run_test, name='test_runner_thread', - daemon=True ) def run(self): @@ -160,6 +159,9 @@ def run(self): self._results.append(inactive_results) + # Join the test thread before returning to avoid it being daemonized. + self._test_tr.join() + return self._results def _run_test(self):