| #!/usr/bin/env python |
| |
| from __future__ import print_function, unicode_literals |
| |
| """Parallel runner for clar |
| """ |
| |
| import sys, time |
| from os import path |
| import subprocess |
| |
| def parse_suites(exe): |
| suites = subprocess.check_output([exe, '-l']) |
| return map(lambda s: s.split(' ')[1], # get the name from each line of output |
| filter(lambda s: s, # Remove any empty lines |
| map(lambda s: s.strip(), # remove leading whitespace |
| suites.split('\n')[3:]))) # skip first three which are info messages |
| |
| def start_process(exe, suites): |
| argv = [exe] |
| for suite in suites: |
| argv.append("-s{}".format(suite)) |
| |
| return subprocess.Popen(argv, stdout=subprocess.PIPE) |
| |
| if __name__ == '__main__': |
| from argparse import ArgumentParser |
| |
| parser = ArgumentParser(description="Parallel runner for clar") |
| parser.add_argument('clar', type=unicode, help="Clar runner") |
| parser.add_argument('-j', '--jobs', type=int, default=1, |
| help="Number of parallel clars to run") |
| args = parser.parse_args() |
| |
| if not args.jobs > 0: |
| print("fatal: umber of jobs must be positive", file=sys.stderr) |
| exit(1) |
| |
| if not path.isfile(args.clar): |
| print("fatal: clar runner not found", file=sys.stderr) |
| exit(1) |
| |
| suites = parse_suites(args.clar) |
| plural = "" if args.jobs == 1 else "es" |
| print("Loaded {} suites, using {} process{}".format(len(suites), args.jobs, plural)) |
| |
| # Split the suites into groups so we can give the list to the |
| # runners. The last one gets a few more in case the number of |
| # suites does not split evenly into the runners |
| indices = range(0, len(suites)+1, len(suites) / args.jobs) |
| indices[-1] = len(suites) |
| |
| procs = [] |
| for i in range(1, len(indices)): |
| lower = indices[i-1] |
| upper = indices[i] |
| |
| procs.append(start_process(args.clar, suites[lower:upper])) |
| |
| # Processes have been started |
| print("Started processes: {}".format(map(lambda p: p.pid, procs))) |
| |
| while True: |
| running = len(filter(lambda p: p.poll() is None, procs)) |
| if running == 0: |
| break |
| |
| sys.stdout.write("\r{}Running {}".format("\033[K", running)) |
| sys.stdout.flush() |
| time.sleep(1) |
| |
| failures = len(filter(lambda p: p.poll() < 0, procs)) |
| errors = sum(filter(lambda p: p.poll() > 0, procs)) |
| successes = filter(lambda p: p.poll() == 0, procs) |
| |
| print("") |
| print("errors: {}, failures: {}".format(errors, failures)) |