Skip to content

Commit c37950f

Browse files
pspaceknicki-krizek
authored andcommitted
Enable live logging for non-parallel pytest runs
This provides incremental output when test is running _without xdist_, just like the old runner did. With xdist the live output is not available, I believe because of pytest-dev/pytest-xdist#402 pytest-dev/pytest-xdist#883 might help with that, but I'm not going to hold my breath until it is available on distros we use.
1 parent 4d5b078 commit c37950f

File tree

1 file changed

+33
-20
lines changed

1 file changed

+33
-20
lines changed

bin/tests/system/conftest.py

+33-20
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,21 @@ def control_port():
9090

9191
# ---------------------- Module initialization ---------------------------
9292

93+
def avoid_duplicated_logs():
94+
"""
95+
Remove direct root logger output to file descriptors.
96+
This default is causing duplicates because all our messages go through
97+
regular logging as well and are thus displayed twice.
98+
"""
99+
todel = []
100+
for handler in logging.root.handlers:
101+
if handler.__class__ == logging.StreamHandler:
102+
# Beware: As for pytest 7.2.2, LiveLogging and LogCapture
103+
# handlers inherit from logging.StreamHandler
104+
todel.append(handler)
105+
for handler in todel:
106+
logging.root.handlers.remove(handler)
107+
93108
def parse_env(env_text):
94109
"""Parse the POSIX env format into Python dictionary."""
95110
out = {}
@@ -282,6 +297,7 @@ def system_test_name(request):
282297
@pytest.fixture(scope="module")
283298
def logger(system_test_name):
284299
"""Logging facility specific to this test."""
300+
avoid_duplicated_logs()
285301
return logging.getLogger(system_test_name)
286302

287303
@pytest.fixture(scope="module")
@@ -377,29 +393,26 @@ def _run_script( # pylint: disable=too-many-arguments
377393
raise FileNotFoundError(f"script {script} not found in {cwd}")
378394
logger.debug("running script: %s %s %s", interpreter, script, " ".join(args))
379395
logger.debug(" workdir: %s", cwd)
380-
stdout = b""
381396
returncode = 1
382-
try:
383-
proc = subprocess.run(
384-
[interpreter, script] + args,
385-
env=env,
386-
check=True,
387-
stdout=subprocess.PIPE,
388-
stderr=subprocess.STDOUT,
389-
)
390-
except subprocess.CalledProcessError as exc:
391-
stdout = exc.stdout
392-
returncode = exc.returncode
393-
raise exc
394-
else:
395-
stdout = proc.stdout
397+
398+
cmd = [interpreter, script] + args
399+
with subprocess.Popen(
400+
cmd,
401+
env=env,
402+
stdout=subprocess.PIPE,
403+
stderr=subprocess.STDOUT,
404+
bufsize=1,
405+
universal_newlines=True,
406+
errors='backslashreplace'
407+
) as proc:
408+
if proc.stdout:
409+
for line in proc.stdout:
410+
logger.info(" %s", line.rstrip('\n'))
411+
proc.communicate()
396412
returncode = proc.returncode
397-
finally:
398-
if stdout:
399-
for line in stdout.decode().splitlines():
400-
logger.debug(" %s", line)
413+
if returncode:
414+
raise subprocess.CalledProcessError(returncode, cmd)
401415
logger.debug(" exited with %d", returncode)
402-
return proc
403416

404417
@pytest.fixture(scope="module")
405418
def shell(env, system_test_dir, logger):

0 commit comments

Comments
 (0)