tests: Move VM starting delay control into parallel-vm.py

This is more efficient since we can now start only the necessary number
of VMs instead of always forcing all VMs to start with one second delay.
This can also control the starting delay by keeping at most two VMs
starting at a time instead of using the hardcoded one second wait for
each consecutive VM.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2019-12-27 10:09:43 +02:00
parent 4ee4778676
commit 179279eb34
2 changed files with 37 additions and 20 deletions

View file

@ -113,6 +113,8 @@ def vm_read_stdout(vm, i, test_queue):
pending = pending[(pos + 1):] pending = pending[(pos + 1):]
logger.debug("VM[%d] stdout full line[%s]" % (i, line)) logger.debug("VM[%d] stdout full line[%s]" % (i, line))
if line.startswith("READY"): if line.startswith("READY"):
vm['starting'] = False
vm['started'] = True
ready = True ready = True
elif line.startswith("PASS"): elif line.startswith("PASS"):
ready = True ready = True
@ -155,6 +157,25 @@ def vm_read_stdout(vm, i, test_queue):
vm['pending'] = pending vm['pending'] = pending
return ready return ready
def start_vm(vm):
vm['starting'] = True
vm['proc'] = subprocess.Popen(vm['cmd'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
vm['cmd'] = None
for stream in [vm['proc'].stdout, vm['proc'].stderr]:
fd = stream.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
def num_vm_starting():
count = 0
for i in range(num_servers):
if vm[i]['starting']:
count += 1
return count
def show_progress(scr): def show_progress(scr):
global num_servers global num_servers
global vm global vm
@ -168,12 +189,14 @@ def show_progress(scr):
total_tests = len(tests) total_tests = len(tests)
logger.info("Total tests: %d" % total_tests) logger.info("Total tests: %d" % total_tests)
test_queue = [(t, 0) for t in tests] test_queue = [(t, 0) for t in tests]
start_vm(vm[0])
scr.leaveok(1) scr.leaveok(1)
scr.addstr(0, 0, "Parallel test execution status", curses.A_BOLD) scr.addstr(0, 0, "Parallel test execution status", curses.A_BOLD)
for i in range(0, num_servers): for i in range(0, num_servers):
scr.addstr(i + 1, 0, "VM %d:" % (i + 1), curses.A_BOLD) scr.addstr(i + 1, 0, "VM %d:" % (i + 1), curses.A_BOLD)
scr.addstr(i + 1, 10, "starting VM") status = "starting VM" if vm[i]['proc'] else "not yet started"
scr.addstr(i + 1, 10, status)
scr.addstr(num_servers + 1, 0, "Total:", curses.A_BOLD) scr.addstr(num_servers + 1, 0, "Total:", curses.A_BOLD)
scr.addstr(num_servers + 1, 20, "TOTAL={} STARTED=0 PASS=0 FAIL=0 SKIP=0".format(total_tests)) scr.addstr(num_servers + 1, 20, "TOTAL={} STARTED=0 PASS=0 FAIL=0 SKIP=0".format(total_tests))
scr.refresh() scr.refresh()
@ -184,6 +207,12 @@ def show_progress(scr):
for i in range(num_servers): for i in range(num_servers):
if not vm[i]['proc']: if not vm[i]['proc']:
if test_queue and vm[i]['cmd'] and num_vm_starting() < 2:
scr.move(i + 1, 10)
scr.clrtoeol()
scr.addstr(i + 1, 10, "starting VM")
updated = True
start_vm(vm[i])
continue continue
if vm[i]['proc'].poll() is not None: if vm[i]['proc'].poll() is not None:
vm[i]['proc'] = None vm[i]['proc'] = None
@ -408,26 +437,22 @@ def main():
print("\rStarting virtual machine {}/{}".format(i + 1, num_servers), print("\rStarting virtual machine {}/{}".format(i + 1, num_servers),
end='') end='')
logger.info("Starting virtual machine {}/{}".format(i + 1, num_servers)) logger.info("Starting virtual machine {}/{}".format(i + 1, num_servers))
cmd = [os.path.join(scriptsdir, 'vm-run.sh'), '--delay', str(i), cmd = [os.path.join(scriptsdir, 'vm-run.sh'),
'--timestamp', str(timestamp), '--timestamp', str(timestamp),
'--ext', 'srv.%d' % (i + 1), '--ext', 'srv.%d' % (i + 1),
'-i'] + codecov_args + extra_args '-i'] + codecov_args + extra_args
if args.telnet: if args.telnet:
cmd += ['--telnet', str(args.telnet + i)] cmd += ['--telnet', str(args.telnet + i)]
vm[i] = {} vm[i] = {}
vm[i]['proc'] = subprocess.Popen(cmd, vm[i]['starting'] = False
stdin=subprocess.PIPE, vm[i]['started'] = False
stdout=subprocess.PIPE, vm[i]['cmd'] = cmd
stderr=subprocess.PIPE) vm[i]['proc'] = None
vm[i]['out'] = "" vm[i]['out'] = ""
vm[i]['pending'] = "" vm[i]['pending'] = ""
vm[i]['err'] = "" vm[i]['err'] = ""
vm[i]['failed'] = [] vm[i]['failed'] = []
vm[i]['fail_seq'] = [] vm[i]['fail_seq'] = []
for stream in [vm[i]['proc'].stdout, vm[i]['proc'].stderr]:
fd = stream.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
print('') print('')
curses.wrapper(show_progress) curses.wrapper(show_progress)
@ -497,6 +522,8 @@ def main():
logger.info("Logs: " + dir + '/' + str(timestamp)) logger.info("Logs: " + dir + '/' + str(timestamp))
for i in range(num_servers): for i in range(num_servers):
if not vm[i]['started']:
continue
if len(vm[i]['pending']) > 0: if len(vm[i]['pending']) > 0:
logger.info("Unprocessed stdout from VM[%d]: '%s'" % logger.info("Unprocessed stdout from VM[%d]: '%s'" %
(i, vm[i]['pending'])) (i, vm[i]['pending']))

View file

@ -64,7 +64,6 @@ CODECOV=no
TIMEWARP=0 TIMEWARP=0
TELNET_QEMU= TELNET_QEMU=
TELNET_ARG=0 TELNET_ARG=0
DELAY=0
CODECOV_DIR= CODECOV_DIR=
while [ "$1" != "" ]; do while [ "$1" != "" ]; do
case $1 in case $1 in
@ -91,10 +90,6 @@ while [ "$1" != "" ]; do
TELNET_QEMU="-net nic,model=virtio -net user,id=telnet,restrict=on,net=172.16.0.0/24,hostfwd=tcp:127.0.0.1:$1-:23" TELNET_QEMU="-net nic,model=virtio -net user,id=telnet,restrict=on,net=172.16.0.0/24,hostfwd=tcp:127.0.0.1:$1-:23"
shift shift
;; ;;
--delay ) shift
DELAY=$1
shift
;;
* ) * )
RUN_TEST_ARGS="$RUN_TEST_ARGS$1 " RUN_TEST_ARGS="$RUN_TEST_ARGS$1 "
shift shift
@ -118,11 +113,6 @@ else
CODECOV=no CODECOV=no
fi fi
if [ $DELAY -gt 0 ]; then
echo "Wait $DELAY seconds before starting VM"
sleep $DELAY
fi
echo "Starting test run in a virtual machine" echo "Starting test run in a virtual machine"
if [ -x $KERNEL ]; then if [ -x $KERNEL ]; then