From 14265c3360b02191975654981715584227c0650e Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Thu, 8 Feb 2024 16:11:21 +0100 Subject: [PATCH 1/2] test-69: send SIGTERM to ask systemd-nspawn to properly stop the container The terminate() method sends SIGHUP but this signal is not handled by systemd-nspawn hence the process just exits leaving the container scope around breaking futher test executions. This patch sends SIGTERM instead which is a defined API to request sytemd-nspawn to stop and release the container's resources properly. Follow-up for 8a7032cfb108c6daa395686320d9361c2195860a. --- test/test-shutdown.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/test/test-shutdown.py b/test/test-shutdown.py index 5339afcdd0..e491f1e1a9 100755 --- a/test/test-shutdown.py +++ b/test/test-shutdown.py @@ -4,6 +4,7 @@ import argparse import logging +import signal import sys import time @@ -91,13 +92,10 @@ def run(args): except Exception as e: logger.error(e) logger.info("killing child pid %d", console.pid) - # We can't use console.terminate(force=True) right away, since - # the internal delay between sending a signal and checking the process - # is just 0.1s [0], which means we'd get SIGKILLed pretty quickly. - # Let's send SIGHUP/SIGINT first, wait a bit, and then follow-up with - # SIGHUP/SIGINT/SIGKILL if the process is still alive. - # [0] https://github.com/pexpect/pexpect/blob/acb017a97332c19a9295660fe87316926a8adc55/pexpect/spawnbase.py#L71 - console.terminate() + + # Ask systemd-nspawn to stop and release the container's resources properly. + console.kill(signal.SIGTERM) + for _ in range(10): if not console.isalive(): break From cf14d1144717967ebdd150cb21ed5dc00e832a80 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Thu, 8 Feb 2024 16:12:41 +0100 Subject: [PATCH 2/2] test/test-shutdown.py: optionally display the test I/Os in a dedicated log file Given that the test involves screen(1), sending various control sequences to resize/clear the screen, most of the logs sent from the python script were nearly impossible to read or mixed with other messages sent to the console hence making the debug harder when the test is run manually. This patch introduces an option to redirect the pexpect IOs into a file (to be used in $STATEDIR/TEST-69-SHUTDOWN/run-nspawn). The pexpect logs are also enabled later so the boot logs are skipped since those are already included in the journal. --- test/test-shutdown.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/test-shutdown.py b/test/test-shutdown.py index e491f1e1a9..f496122f80 100755 --- a/test/test-shutdown.py +++ b/test/test-shutdown.py @@ -21,15 +21,18 @@ def run(args): "TERM": "linux", }, encoding='utf-8', timeout=60) - if args.verbose: - console.logfile = sys.stdout - logger.debug("child pid %d", console.pid) try: logger.info("waiting for login prompt") console.expect('H login: ', 10) + if args.logfile: + logger.debug("Logging pexpect IOs to %s", args.logfile) + console.logfile = open(args.logfile, 'w') + elif args.verbose: + console.logfile = sys.stdout + logger.info("log in and start screen") console.sendline('root') console.expect('bash.*# ', 10) @@ -44,7 +47,7 @@ def run(args): console.sendline('tty') console.expect(r'/dev/(pts/\d+)') pty = console.match.group(1) - logger.info("window 1 at line %s", pty) + logger.info("window 1 at tty %s", pty) logger.info("schedule reboot") console.sendline('shutdown -r') @@ -112,6 +115,7 @@ def run(args): def main(): parser = argparse.ArgumentParser(description='test logind shutdown feature') parser.add_argument("-v", "--verbose", action="store_true", help="verbose") + parser.add_argument("--logfile", metavar='FILE', help="Save all test input/output to the given path") parser.add_argument("command", help="command to run") parser.add_argument("arg", nargs='*', help="args for command")