mirror of
https://github.com/systemd/systemd.git
synced 2026-06-24 08:47:49 +00:00
168 lines
4.2 KiB
Python
Executable File
168 lines
4.2 KiB
Python
Executable File
#!/usr/bin/python3
|
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
# pylint: disable=broad-except
|
|
|
|
import argparse
|
|
import logging
|
|
import signal
|
|
import sys
|
|
import time
|
|
|
|
import pexpect
|
|
|
|
|
|
def run(args):
|
|
ret = 1
|
|
logger = logging.getLogger('test-shutdown')
|
|
logfile = None
|
|
|
|
if args.logfile:
|
|
logger.debug('Logging pexpect IOs to %s', args.logfile)
|
|
logfile = open(args.logfile, 'w')
|
|
elif args.verbose:
|
|
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)
|
|
|
|
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)
|
|
|
|
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 tty %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(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(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('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 will reboot now!', 12)
|
|
|
|
logger.info('waiting for reboot')
|
|
|
|
console.expect('H login: ', 60)
|
|
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)
|
|
|
|
# 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
|
|
|
|
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',
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.verbose:
|
|
level = logging.DEBUG
|
|
else:
|
|
level = logging.INFO
|
|
|
|
logging.basicConfig(level=level)
|
|
|
|
return run(args)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|
|
|
|
# vim: sw=4 et
|