diff --git a/craft_cli/messages.py b/craft_cli/messages.py index 8ed2549..c9b0293 100644 --- a/craft_cli/messages.py +++ b/craft_cli/messages.py @@ -70,6 +70,9 @@ class _MessageInfo: # pylint: disable=too-many-instance-attributes # the size of bytes chunk that the pipe reader will read at once _PIPE_READER_CHUNK_SIZE = 4096 +# set to true when running *application* tests so some behaviours change +TESTMODE = False + def _get_terminal_width() -> int: """Return the number of columns of the terminal.""" @@ -193,13 +196,17 @@ def stop(self) -> None: class _Printer: - """Handle writing the different messages to the different outputs (out, err and log).""" + """Handle writing the different messages to the different outputs (out, err and log). + + If TESTMODE is True, this class changes its behaviour: the spinner is never started, + so there is no thread polluting messages when running tests if they take too long to run. + """ def __init__(self, log_filepath: pathlib.Path) -> None: # holder of the previous message self.prv_msg: Optional[_MessageInfo] = None - # the open log file (will be closed explicitly when the thread ends) + # open the log file (will be closed explicitly later) self.log = open(log_filepath, "wt", encoding="utf8") # pylint: disable=consider-using-with # keep account of output streams with unfinished lines @@ -207,7 +214,8 @@ def __init__(self, log_filepath: pathlib.Path) -> None: # run the spinner supervisor self.spinner = _Spinner(self) - self.spinner.start() + if not TESTMODE: + self.spinner.start() def _write_line(self, message: _MessageInfo, *, spintext: str = "") -> None: """Write a simple line message to the screen.""" @@ -366,7 +374,8 @@ def stop(self) -> None: - add a new line to the screen (if needed) - close the log file """ - self.spinner.stop() + if not TESTMODE: + self.spinner.stop() if self.unfinished_stream is not None: print(flush=True, file=self.unfinished_stream) self.log.close() diff --git a/tests/unit/test_messages_printer.py b/tests/unit/test_messages_printer.py index 4d4e115..1def52d 100644 --- a/tests/unit/test_messages_printer.py +++ b/tests/unit/test_messages_printer.py @@ -634,7 +634,20 @@ def test_progress_bar_no_stream(recording_printer): assert recording_printer.prv_msg is None -# -- tests for stopping the printer +# -- tests for starting/stopping the printer + + +def test_init_printer_ok(log_filepath): + """Printer is initiated as usual.""" + printer = _Printer(log_filepath) + assert printer.spinner.is_alive() + + +def test_init_printer_testmode(log_filepath, monkeypatch): + """Printer is initiated as usual.""" + monkeypatch.setattr(messages, "TESTMODE", True) + printer = _Printer(log_filepath) + assert not printer.spinner.is_alive() def test_stop_streams_ok(capsys, log_filepath): @@ -670,9 +683,17 @@ def test_stop_streams_unfinished_err(capsys, log_filepath): assert err == "\n" -def test_stop_spinner(log_filepath): +def test_stop_spinner_ok(log_filepath): """Stop the spinner.""" printer = _Printer(log_filepath) assert printer.spinner.is_alive() printer.stop() assert not printer.spinner.is_alive() + + +def test_stop_spinner_testmode(log_filepath, monkeypatch): + """Stop the spinner.""" + monkeypatch.setattr(messages, "TESTMODE", True) + printer = _Printer(log_filepath) + printer.stop() + assert not printer.spinner.is_alive()