diff --git a/app/logger.py b/app/logger.py index bde815822..a20049c66 100644 --- a/app/logger.py +++ b/app/logger.py @@ -60,7 +60,7 @@ class LogInterceptor(io.TextIOWrapper): # Simple handling for cr to overwrite the last output if it isnt a full line # else logs just get full of progress messages - if isinstance(data, str) and data.startswith("\r") and not logs[-1]["m"].endswith("\n"): + if isinstance(data, str) and data.startswith("\r") and logs and not logs[-1]["m"].endswith("\n"): logs.pop() logs.append(entry) super().write(data) diff --git a/tests-unit/app_test/logger_test.py b/tests-unit/app_test/logger_test.py new file mode 100644 index 000000000..109906aba --- /dev/null +++ b/tests-unit/app_test/logger_test.py @@ -0,0 +1,30 @@ +from collections import deque +import io + +import app.logger +from app.logger import LogInterceptor + + +def make_interceptor(): + stream = io.TextIOWrapper(io.BytesIO(), encoding="utf-8", line_buffering=True) + return LogInterceptor(stream), stream + + +def test_carriage_return_write_with_empty_log_buffer(monkeypatch): + monkeypatch.setattr(app.logger, "logs", deque(maxlen=10)) + interceptor, _stream = make_interceptor() + + interceptor.write("\rprogress") + + assert len(app.logger.logs) == 1 + assert app.logger.logs[-1]["m"] == "\rprogress" + + +def test_carriage_return_replaces_incomplete_log_entry(monkeypatch): + monkeypatch.setattr(app.logger, "logs", deque(maxlen=10)) + interceptor, _stream = make_interceptor() + + interceptor.write("progress 1") + interceptor.write("\rprogress 2") + + assert [entry["m"] for entry in app.logger.logs] == ["\rprogress 2"]