From f7b249a65baeeb8f48ebfc6ca98265f23cd26d57 Mon Sep 17 00:00:00 2001 From: pasinskim Date: Thu, 2 Jul 2026 09:25:07 +0200 Subject: [PATCH] test: capture the QEMU client serial console on failure The failure teardown only prints device output over SSH, which is empty when the device is unreachable -- which is exactly the "Device never rebooted" failure mode (a hung guest reset). Capture the client's serial console via "docker compose logs" (which works without SSH) into the per-test logs, so the guest's actual reboot behaviour (e.g. "reboot: machine restart" followed by silence) is visible directly in CI artifacts. Changelog: None Signed-off-by: pasinskim --- tests/conftest.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index fcd00c2f4..c62c80a54 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -346,6 +346,49 @@ def pytest_exception_interact(node, call, report): f"database snapshot captured; import using: mongorestore --archive={log.TEST_LOGS_PATH}/{node.name}.bson" ) + # Capture the QEMU client's serial console. "docker compose + # logs" of the client works even when the device is unreachable + # over SSH -- which is exactly the "Device never rebooted" + # failure mode -- so it is the only record of what the guest + # actually did on reboot (the SSH-based logs below are empty + # when the guest is dead). + for svc in ("mender-client", "mender-client-docker-addons"): + try: + console = subprocess.run( + [ + "docker", + "compose", + "-p", + env.name, + "logs", + "--no-color", + "--no-log-prefix", + svc, + ], + env=dict( + **os.environ, + COMPOSE_FILE=":".join(env.docker_compose_files), + ), + capture_output=True, + text=True, + timeout=120, + ).stdout + except Exception as ex: + logger.warning("failed to capture %s console: %s", svc, ex) + continue + if console.strip(): + console_path = ( + f"{log.TEST_LOGS_PATH}/{node.name}_{svc}_console.log" + ) + with open(console_path, "w") as fh: + fh.write(console) + logger.info( + "captured %s serial console -> %s (%d bytes)", + svc, + console_path, + len(console), + ) + # If we have devices (or groups) try to print deployment and systemd logs if devices is []: logger.info("Could not find devices in test environment, no printing logs")