test-runner: fix logging, verbose, and process output

There were some major problems related to logging and process
output. Tests which required output from start_process would
break if used with '--log/--verbose'. This is because we relied
on 'communicate' to retrieve the process output, but Popen does
not store process output when stdout/stderr are anything other
than PIPE.

Intead, in the case of logging or outfiles, we can simply read
from the file we just wrote to.

For an explicit --verbose application we must handle things
slightly different. A keyword argument was added to Process,
'need_out' which will ensure the process output is kept
regardless of --log or --verbose.

Now a user should be able to use --log/--verbose without any
tests failing.
This commit is contained in:
James Prestwood 2021-01-26 09:46:56 -08:00 committed by Denis Kenzior
parent cc345582ad
commit b0e970ae38
2 changed files with 15 additions and 11 deletions

View File

@ -152,7 +152,7 @@ class HostapdCLI:
ctx.start_process(self.cmdline + ['enable'], wait=True) ctx.start_process(self.cmdline + ['enable'], wait=True)
def list_sta(self): def list_sta(self):
proc = ctx.start_process(self.cmdline + ['list_sta'], wait=True) proc = ctx.start_process(self.cmdline + ['list_sta'], wait=True, need_out=True)
if not proc.out: if not proc.out:
return [] return []

View File

@ -162,7 +162,7 @@ class Process:
test exits. test exits.
''' '''
def __init__(self, args, wait=False, multi_test=False, env=None, ctx=None, check=False, def __init__(self, args, wait=False, multi_test=False, env=None, ctx=None, check=False,
outfile=None, namespace=None): outfile=None, namespace=None, need_out=False):
self.args = args self.args = args
self.wait = wait self.wait = wait
self.name = args[0] self.name = args[0]
@ -171,14 +171,13 @@ class Process:
self.stderr = subprocess.PIPE self.stderr = subprocess.PIPE
self.ret = None self.ret = None
self.ctx = ctx self.ctx = ctx
set_stdout = False
if namespace: if namespace:
self.args = ['ip', 'netns', 'exec', namespace] self.args = ['ip', 'netns', 'exec', namespace]
self.args.extend(args) self.args.extend(args)
if ctx: if ctx:
set_stdout = False
if ctx.is_verbose(args[0]): if ctx.is_verbose(args[0]):
print("Verbose on for %s" % args[0]) print("Verbose on for %s" % args[0])
set_stdout = True set_stdout = True
@ -204,12 +203,12 @@ class Process:
os.chown(test_dir, int(ctx.args.log_uid), \ os.chown(test_dir, int(ctx.args.log_uid), \
int(ctx.args.log_gid)) int(ctx.args.log_gid))
self.stdout = open('%s/%s' % (test_dir, args[0]), 'w') self.stdout = open('%s/%s' % (test_dir, args[0]), 'w+')
self.stderr = open('%s/%s' % (test_dir, args[0]), 'w') self.stderr = open('%s/%s' % (test_dir, args[0]), 'w+')
elif outfile: elif outfile:
self.stdout = open(outfile, 'w') self.stdout = open(outfile, 'w')
self.stderr = open(outfile, 'w') self.stderr = open(outfile, 'w')
else: elif not need_out:
self.stdout = sys.__stdout__ self.stdout = sys.__stdout__
self.stderr = sys.__stderr__ self.stderr = sys.__stderr__
@ -224,11 +223,16 @@ class Process:
self.pid.wait() self.pid.wait()
self.out, _ = self.pid.communicate() if ctx and ctx.args.log or outfile:
self.ret = self.pid.returncode self.stdout.seek(0)
self.out = self.stdout.read()
else:
self.out, _ = self.pid.communicate()
if self.out: if self.out:
self.out = self.out.decode('utf-8') self.out = self.out.decode('utf-8')
self.ret = self.pid.returncode
print("%s returned %d" % (args[0], self.ret)) print("%s returned %d" % (args[0], self.ret))
if check and self.ret != 0: if check and self.ret != 0: