2021-12-22 13:50:08 +03:00
#!/usr/bin/python3
# SPDX-License-Identifier: LGPL-2.1-or-later
2023-08-09 22:57:47 +03:00
# pylint: disable=broad-except
2021-12-22 13:50:08 +03:00
import argparse
import logging
2024-02-08 18:11:21 +03:00
import signal
2021-12-22 13:50:08 +03:00
import sys
2022-11-30 18:13:19 +03:00
import time
2021-12-22 13:50:08 +03:00
2022-05-27 12:45:15 +03:00
import pexpect
2021-12-22 13:50:08 +03:00
def run ( args ) :
ret = 1
logger = logging . getLogger ( " test-shutdown " )
2024-04-09 21:55:48 +03:00
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
2021-12-22 13:50:08 +03:00
logger . info ( " spawning test " )
2024-04-09 21:55:48 +03:00
console = pexpect . spawn ( args . command , args . arg , logfile = logfile , env = {
2024-04-11 12:35:17 +03:00
" TERM " : " dumb " ,
2023-01-23 21:13:49 +03:00
} , encoding = ' utf-8 ' , timeout = 60 )
2021-12-22 13:50:08 +03:00
2022-05-27 12:45:15 +03:00
logger . debug ( " child pid %d " , console . pid )
2021-12-22 13:50:08 +03:00
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 )
2024-04-09 22:16:41 +03:00
logger . info ( ' wait for the machine to fully boot ' )
console . sendline ( ' systemctl is-system-running --wait ' )
console . expect ( r ' \ b(running|degraded) \ b ' , 60 )
2021-12-22 13:50:08 +03:00
# console.interact()
console . sendline ( ' tty ' )
console . expect ( r ' /dev/(pts/ \ d+) ' )
pty = console . match . group ( 1 )
2024-02-08 18:12:41 +03:00
logger . info ( " window 1 at tty %s " , pty )
2021-12-22 13:50:08 +03:00
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 " )
2022-11-30 18:18:50 +03:00
console . expect ( f ' Broadcast message from root@H on { pty } ' , 2 )
console . expect ( f ' The system will reboot at { date } ' , 2 )
2021-12-22 13:50:08 +03:00
logger . info ( " check show output " )
console . sendline ( ' shutdown --show ' )
2022-11-30 18:18:50 +03:00
console . expect ( f " Reboot scheduled for { date } , use ' shutdown -c ' to cancel " , 2 )
2021-12-22 13:50:08 +03:00
logger . info ( " cancel shutdown " )
console . sendline ( ' shutdown -c ' )
console . sendcontrol ( ' a ' )
console . send ( ' 1 ' )
2022-05-30 13:08:41 +03:00
console . expect ( ' System shutdown has been cancelled ' , 2 )
2021-12-22 13:50:08 +03:00
logger . info ( " call for reboot " )
console . sendline ( ' sleep 10; shutdown -r now ' )
console . sendcontrol ( ' a ' )
console . send ( ' 0 ' )
2022-05-30 13:08:41 +03:00
console . expect ( " The system will reboot now! " , 12 )
2021-12-22 13:50:08 +03:00
logger . info ( " waiting for reboot " )
2022-08-26 16:53:46 +03:00
console . expect ( ' H login: ' , 60 )
2021-12-22 13:50:08 +03:00
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 )
2022-05-27 12:45:15 +03:00
logger . info ( " killing child pid %d " , console . pid )
2024-02-08 18:11:21 +03:00
# Ask systemd-nspawn to stop and release the container's resources properly.
console . kill ( signal . SIGTERM )
2022-11-30 18:13:19 +03:00
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 )
2021-12-22 13:50:08 +03:00
return ret
2022-05-27 12:45:15 +03:00
def main ( ) :
2021-12-22 13:50:08 +03:00
parser = argparse . ArgumentParser ( description = ' test logind shutdown feature ' )
parser . add_argument ( " -v " , " --verbose " , action = " store_true " , help = " verbose " )
2024-02-08 18:12:41 +03:00
parser . add_argument ( " --logfile " , metavar = ' FILE ' , help = " Save all test input/output to the given path " )
2021-12-22 13:50:08 +03:00
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 )
2022-05-27 12:45:15 +03:00
return run ( args )
if __name__ == ' __main__ ' :
sys . exit ( main ( ) )
2021-12-22 13:50:08 +03:00
# vim: sw=4 et