Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

packetdrill: run_all: add --tap <DIR> option #83

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions gtests/net/packetdrill/run_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def __init__(self, args):
self.num_pass = 0
self.num_fail = 0
self.num_timedout = 0
self.tap = None

def FindTests(self, path='.'):
"""Return all *.pkt files in a given directory and its subdirectories."""
Expand Down Expand Up @@ -116,7 +117,19 @@ def Log(self, outfile, errfile):
errfile.seek(0)
sys.stderr.write(errfile.read())

def StartTest(self, cmd, execdir, path, variant, basename):
def TapInit(self, path, n):
fname = 'packetdrill_' + os.path.splitext(os.path.basename(path))[0] + '.tap'
self.tap = open(os.path.join(self.args['tap'], fname), mode='w')
print('TAP version 13\n1..' + str(n), file=self.tap)

def TapLog(self, result, outfile, errfile):
print(result, file=self.tap)
outfile.seek(0)
errfile.seek(0)
for line in outfile.readlines() + errfile.readlines():
print('# ' + line.rstrip(), file=self.tap)

def StartTest(self, cmd, execdir, path, variant, basename, id):
"""Run a packetdrill test"""
outfile = tempfile.TemporaryFile(mode='w+')
errfile = tempfile.TemporaryFile(mode='w+')
Expand All @@ -130,13 +143,17 @@ def StartTest(self, cmd, execdir, path, variant, basename):
process = subprocess.Popen(cmd, stdout=outfile, stderr=errfile, cwd=execdir,
env=env)

return (process, path, variant, outfile, errfile, time_start)
return (process, path, variant, outfile, errfile, time_start, id)

def PollTest(self, process, path, variant, outfile, errfile, time_start, now):
def PollTest(self, process, path, variant, outfile, errfile, time_start, id, now):
"""Test whether a test has finished and if so record its return value."""
if process.poll() is None:
return False, now - time_start >= self.max_runtime

if self.tap:
ok = 'not ok' if process.returncode else 'ok'
self.TapLog('%s %d %s (%s)' % (ok, id, path, variant), outfile, errfile)

if not process.returncode:
self.num_pass += 1
if self.args['verbose']:
Expand All @@ -158,9 +175,11 @@ def StartPollTestSet(self, cmds):
if max_in_parallel == 0 or max_in_parallel > len(cmds):
max_in_parallel = len(cmds)

id = 1
procs = []
while len(procs) < max_in_parallel:
procs.append(self.StartTest(*cmds.pop(0)))
procs.append(self.StartTest(*cmds.pop(0), id))
id += 1

timedouts = []
while procs:
Expand All @@ -172,12 +191,13 @@ def StartPollTestSet(self, cmds):
if stopped or timedout:
procs.remove(entry)
if cmds:
procs.append(self.StartTest(*cmds.pop(0)))
procs.append(self.StartTest(*cmds.pop(0), id))
id += 1
if timedout:
timedouts.append(entry)

self.num_timedout = len(timedouts)
for proc, path, variant, outfile, errfile, _ in timedouts:
for proc, path, variant, outfile, errfile, _, id in timedouts:
try:
proc.kill()
except:
Expand All @@ -187,6 +207,9 @@ def StartPollTestSet(self, cmds):
print('KILL [%s (%s)]' % (path, variant))
if self.args['log_on_error']:
self.Log(outfile, errfile)
if self.tap:
self.TapLog('not ok %d %s (%s) # timeout' % (id, path, variant),
outfile, errfile)

def RunTests(self, path):
"""Find all packetdrill scripts in a path and run them."""
Expand All @@ -201,8 +224,14 @@ def RunTests(self, path):
print(' '.join(cmd[0]))
return

if self.args['tap'] is not None:
self.TapInit(path, len(cmds))

self.StartPollTestSet(cmds)

if self.tap:
self.tap.close()

print(
'Ran % 4d tests: % 4d passing, % 4d failing, % 4d timed out (%.2f sec): %s' # pylint: disable=line-too-long
% (self.num_pass + self.num_fail + self.num_timedout, self.num_pass,
Expand Down Expand Up @@ -279,6 +308,8 @@ def ParseArgs():
args.add_argument('--dry_run', action='store_true')
args.add_argument('-s', '--subdirs', action='store_true')
args.add_argument('-S', '--serialized', action='store_true')
args.add_argument('-t', '--tap', metavar='DIR',
help='save results in TAP format in the specified directory')
args.add_argument('-v', '--verbose', action='count', default=0,
help="can be repeated to run packetdrill with -v")
return vars(args.parse_args())
Expand Down