Skip to content

Commit 2619b93

Browse files
committed
refactor: redirect pytest output to log file without ANSI sequences
Signed-off-by: Gaëtan Lehmann <gaetan.lehmann@vates.tech>
1 parent 11257c3 commit 2619b93

1 file changed

Lines changed: 34 additions & 8 deletions

File tree

compat_kit/entrypoint.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import getpass
1919
import logging
2020
import os
21+
import re
2122
import shutil
2223
import subprocess
2324
import sys
@@ -351,8 +352,6 @@ def run_pytest(phase: int, test_args: list[str], log_file: str) -> None:
351352
'--color=yes',
352353
'--no-header',
353354
'--maxfail=0',
354-
'--log-file-level=debug',
355-
f'--log-file={log_path}',
356355
f'--log-cli-level={logging.getLevelName(state.log_level)}',
357356
f'--vm={state.vm_image_url}',
358357
] + test_args
@@ -364,16 +363,43 @@ def run_pytest(phase: int, test_args: list[str], log_file: str) -> None:
364363

365364
logging.debug(f"Running: {' '.join(cmd)}")
366365
try:
367-
subprocess.run(cmd, check=True, timeout=3600)
368-
logging.info(f"Phase {phase}: Tests completed successfully")
369-
except subprocess.CalledProcessError as e:
370-
logging.warning(f"Phase {phase}: Tests failed with exit code {e.returncode}")
371-
state.tests_failed = True
372-
# Don't raise, allow other phases to run
366+
ansi_escape = re.compile(br'\x1b\[[0-9;]*[a-zA-Z]')
367+
368+
# Launch pytest. We force colors so the terminal output stays pretty.
369+
# 'bufsize=1' and 'universal_newlines=False' allow us to process line by line.
370+
process = subprocess.Popen(
371+
cmd,
372+
stdout=subprocess.PIPE,
373+
stderr=subprocess.STDOUT
374+
)
375+
376+
assert process.stdout is not None
377+
with open(log_path, "wb") as f:
378+
# Read from the pipe until the process finishes
379+
for line in iter(process.stdout.readline, b''):
380+
# 1. Write the original colorful line to the actual terminal
381+
sys.stdout.buffer.write(line)
382+
sys.stdout.buffer.flush()
383+
384+
# 2. Strip the codes and write the clean text to the file
385+
clean_line = ansi_escape.sub(b'', line)
386+
f.write(clean_line)
387+
f.flush()
388+
389+
process.wait()
390+
if process.returncode != 0:
391+
logging.warning(f"Phase {phase}: Tests failed with exit code {process.returncode}")
392+
state.tests_failed = True
393+
else:
394+
logging.info(f"Phase {phase}: Tests completed successfully")
373395
except subprocess.TimeoutExpired:
374396
logging.error(f"Phase {phase}: Tests timed out")
375397
state.tests_failed = True
376398
raise
399+
except Exception as e:
400+
logging.error(f"Phase {phase}: Tests failed: {e}")
401+
state.tests_failed = True
402+
raise
377403

378404

379405
def setup_config_files() -> None:

0 commit comments

Comments
 (0)