]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - test/test-shutdown.py
test-network: introduce check_networkd_log() helper function
[thirdparty/systemd.git] / test / test-shutdown.py
index 1a91753b87a9f9580e7bbd7cd5c05106fc1aecfc..d19a03742c246f6c5cd2f2b40da28be601f38d21 100755 (executable)
@@ -1,27 +1,33 @@
 #!/usr/bin/python3
 # SPDX-License-Identifier: LGPL-2.1-or-later
-#
+# pylint: disable=broad-except
 
 import argparse
 import logging
-import pexpect
+import signal
 import sys
+import time
+
+import pexpect
 
 
 def run(args):
-
     ret = 1
     logger = logging.getLogger("test-shutdown")
+    logfile = None
 
-    logger.info("spawning test")
-    console = pexpect.spawn(args.command, args.arg, env={
-            "TERM": "linux",
-        }, encoding='utf-8', timeout=30)
+    if args.logfile:
+        logger.debug("Logging pexpect IOs to %s", args.logfile)
+        logfile = open(args.logfile, 'w')
+    elif args.verbose:
+        logfile = sys.stdout
 
-    if args.verbose:
-        console.logfile = sys.stdout
+    logger.info("spawning test")
+    console = pexpect.spawn(args.command, args.arg, logfile=logfile, env={
+            "TERM": "dumb",
+        }, encoding='utf-8', timeout=60)
 
-    logger.debug("child pid %d" % console.pid)
+    logger.debug("child pid %d", console.pid)
 
     try:
         logger.info("waiting for login prompt")
@@ -36,12 +42,16 @@ def run(args):
         console.send('c')
         console.expect('screen1 ', 10)
 
+        logger.info('wait for the machine to fully boot')
+        console.sendline('systemctl is-system-running --wait')
+        console.expect(r'\b(running|degraded)\b', 60)
+
 #        console.interact()
 
         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')
@@ -52,28 +62,28 @@ def run(args):
         console.sendcontrol('a')
         console.send('0')
         logger.info("verify broadcast message")
-        console.expect('Broadcast message from root@H on %s' % pty, 2)
-        console.expect('The system is going down for reboot at %s' % date, 2)
+        console.expect(f'Broadcast message from root@H on {pty}', 2)
+        console.expect(f'The system will reboot at {date}', 2)
 
         logger.info("check show output")
         console.sendline('shutdown --show')
-        console.expect("Reboot scheduled for %s, use 'shutdown -c' to cancel" % date, 2)
+        console.expect(f"Reboot scheduled for {date}, use 'shutdown -c' to cancel", 2)
 
         logger.info("cancel shutdown")
         console.sendline('shutdown -c')
         console.sendcontrol('a')
         console.send('1')
-        console.expect('The system shutdown has been cancelled', 2)
+        console.expect('System shutdown has been cancelled', 2)
 
         logger.info("call for reboot")
         console.sendline('sleep 10; shutdown -r now')
         console.sendcontrol('a')
         console.send('0')
-        console.expect("The system is going down for reboot NOW!", 12)
+        console.expect("The system will reboot now!", 12)
 
         logger.info("waiting for reboot")
 
-        console.expect('H login: ', 30)
+        console.expect('H login: ', 60)
         console.sendline('root')
         console.expect('bash.*# ', 10)
 
@@ -88,15 +98,28 @@ def run(args):
         ret = 0
     except Exception as e:
         logger.error(e)
-        logger.info("killing child pid %d" % console.pid)
-        console.terminate()
+        logger.info("killing child pid %d", console.pid)
 
-    return ret
+        # 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
 
-if __name__ == '__main__':
+            time.sleep(1)
+        else:
+            # We haven't exited the loop early, so check if the process is
+            # still alive - if so, force-kill it.
+            if console.isalive():
+                console.terminate(force=True)
+
+    return ret
+
+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")
 
@@ -109,6 +132,9 @@ if __name__ == '__main__':
 
     logging.basicConfig(level=level)
 
-    sys.exit(run(args))
+    return run(args)
+
+if __name__ == '__main__':
+    sys.exit(main())
 
 # vim: sw=4 et