test: add shutdown test

Wraps nspawn to be able to use pexpect. The test logs in on the console
and runs screen. In one screen window it types in shutdown commands and
checks whether a wall message was sent to the other.
This commit is contained in:
Ludwig Nussel 2021-12-22 11:50:08 +01:00
parent 38d55bf264
commit 48f3bc5cc4
5 changed files with 159 additions and 0 deletions

View file

@ -0,0 +1 @@
../TEST-01-BASIC/Makefile

33
test/TEST-69-SHUTDOWN/test.sh Executable file
View file

@ -0,0 +1,33 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
TEST_DESCRIPTION="shutdown testing"
IMAGE_NAME="shutdown"
TEST_NO_QEMU=1
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
_ORIG_NSPAWN="$SYSTEMD_NSPAWN"
SYSTEMD_NSPAWN="$STATEDIR/run-nspawn"
setup_nspawn_root_hook() {
cat > "$STATEDIR"/run-nspawn <<-EOF
#!/bin/bash
exec "$TEST_BASE_DIR"/test-shutdown.py -- "$_ORIG_NSPAWN" "\$@"
exit 1
EOF
chmod 755 "$STATEDIR"/run-nspawn
}
test_append_files() {
# prevent shutdown in test suite, the expect script does that manually.
rm "$1"/usr/lib/systemd/tests/testdata/units/end.service
inst /usr/bin/screen
echo "PS1='screen\$WINDOW # '" > "$1"/etc/bash.bashrc
echo 'startup_message off' > "$1"/etc/screenrc
echo 'bell_msg ""' >> "$1"/etc/screenrc
}
do_test "$@"

View file

@ -1884,6 +1884,8 @@ has_user_dbus_socket() {
fi
}
setup_nspawn_root_hook() { :;}
setup_nspawn_root() {
if [ -z "${initdir}" ]; then
dfatal "\$initdir not defined"
@ -1896,6 +1898,8 @@ setup_nspawn_root() {
ddebug "cp -ar $initdir $TESTDIR/unprivileged-nspawn-root"
cp -ar "$initdir" "$TESTDIR/unprivileged-nspawn-root"
fi
setup_nspawn_root_hook
}
setup_basic_dirs() {

114
test/test-shutdown.py Executable file
View file

@ -0,0 +1,114 @@
#!/usr/bin/python3
# SPDX-License-Identifier: LGPL-2.1-or-later
#
import argparse
import logging
import pexpect
import sys
def run(args):
ret = 1
logger = logging.getLogger("test-shutdown")
logger.info("spawning test")
console = pexpect.spawn(args.command, args.arg, env={
"TERM": "linux",
}, encoding='utf-8', timeout=30)
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)
logger.info("log in and start screen")
console.sendline('root')
console.expect('bash.*# ', 10)
console.sendline('screen')
console.expect('screen0 ', 10)
console.sendcontrol('a')
console.send('c')
console.expect('screen1 ', 10)
# 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("schedule reboot")
console.sendline('shutdown -r')
console.expect("Reboot scheduled for (?P<date>.*), use 'shutdown -c' to cancel", 2)
date = console.match.group('date')
logger.info("reboot scheduled for %s", date)
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)
logger.info("check show output")
console.sendline('shutdown --show')
console.expect("Reboot scheduled for %s, use 'shutdown -c' to cancel" % date, 2)
logger.info("cancel shutdown")
console.sendline('shutdown -c')
console.sendcontrol('a')
console.send('1')
console.expect('The 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)
logger.info("waiting for reboot")
console.expect('H login: ', 10)
console.sendline('root')
console.expect('bash.*# ', 10)
console.sendline('> /testok')
logger.info("power off")
console.sendline('poweroff')
logger.info("expect termination now")
console.expect(pexpect.EOF)
ret = 0
except Exception as e:
logger.error(e)
logger.info("killing child pid %d" % console.pid)
console.terminate()
return ret
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='test logind shutdown feature')
parser.add_argument("-v", "--verbose", action="store_true", help="verbose")
parser.add_argument("command", help="command to run")
parser.add_argument("arg", nargs='*', help="args for command")
args = parser.parse_args()
if args.verbose:
level = logging.DEBUG
else:
level = logging.INFO
logging.basicConfig(level=level)
sys.exit(run(args))
# vim: sw=4 et

View file

@ -0,0 +1,7 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Unit]
Description=TEST-69-SHUTDOWN
[Service]
Type=oneshot
ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh