summaryrefslogtreecommitdiffstats
path: root/cppunit-parallelize.py
diff options
context:
space:
mode:
authorVegard Sjonfjell <vegard@yahoo-inc.com>2016-11-14 16:50:55 +0100
committerVegard Sjonfjell <vegard@yahoo-inc.com>2016-11-14 16:50:55 +0100
commitaa3136d7f540d5d94075cbaee533681dcd80ac28 (patch)
tree51ddf4a2d21a031efeedcb02ad2971d4f8db5cbb /cppunit-parallelize.py
parentb27c743bfec32e720e53111eccdbc4db6a33222b (diff)
Refactoring
Diffstat (limited to 'cppunit-parallelize.py')
-rwxr-xr-xcppunit-parallelize.py70
1 files changed, 43 insertions, 27 deletions
diff --git a/cppunit-parallelize.py b/cppunit-parallelize.py
index 5909a0cc015..06c5f527ed4 100755
--- a/cppunit-parallelize.py
+++ b/cppunit-parallelize.py
@@ -5,7 +5,6 @@ import copy
import os
import subprocess
import time
-import collections
def parse_arguments():
argparser = argparse.ArgumentParser(description="Run Vespa cppunit tests in parallell")
@@ -27,46 +26,63 @@ def chunkify(lst, chunks):
return result
+class Process:
+ def __init__(self, cmd, group):
+ self.group = group
+ self.finished = False
+ self.output = ""
+ self.handle = subprocess.Popen(
+ cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ preexec_fn=os.setpgrp)
+
def build_processes(test_groups):
valgrind = os.getenv("VALGRIND")
- testrunner = (valgrind, args.testrunner) if valgrind is not None else (args.testrunner,)
+ testrunner = (valgrind, args.testrunner) if valgrind else (args.testrunner,)
processes = []
+
for group in test_groups:
cmd = testrunner + tuple(group)
- processes.append((group,
- subprocess.Popen(
- cmd,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- preexec_fn=os.setpgrp)))
+ processes.append(Process(cmd, group))
+
return processes
+def cleanup_processes(processes):
+ for proc in processes:
+ try:
+ proc.handle.kill()
+ except OSError as e:
+ if e.errno != os.errno.ESRCH: # "No such process"
+ print >>sys.stderr, e.message
+
args = parse_arguments()
test_suites = subprocess.check_output((args.testrunner, "--list")).strip().split("\n")
test_suite_groups = chunkify(test_suites, args.chunks)
processes = build_processes(test_suite_groups)
-output = collections.defaultdict(str)
print "Running %d test suites in %d parallel chunks with ~%d tests each" % (len(test_suites), len(test_suite_groups), len(test_suite_groups[0]))
+processes_left = len(processes)
while True:
- prevlen = len(processes)
- for group, proc in processes:
- return_code = proc.poll()
- output[proc] += proc.stdout.read()
-
- if return_code == 0:
- processes.remove((group, proc))
- if not len(processes):
- print "All tests suites ran successfully"
- sys.exit(0)
- elif return_code is not None:
- print "One of '%s' test suites failed:" % ", ".join(group)
- print >>sys.stderr, output[proc]
- sys.exit(return_code)
+ try:
+ for proc in processes:
+ return_code = proc.handle.poll()
+ proc.output += proc.handle.stdout.read()
- if prevlen != len(processes):
- prevlen = len(processes)
- print "%d test suite(s) left" % prevlen
+ if return_code == 0:
+ proc.finished = True
+ processes_left -= 1
+ if processes_left > 0:
+ print "%d test suite(s) left" % processes_left
+ else:
+ print "All test suites ran successfully"
+ sys.exit(0)
+ elif return_code is not None:
+ print "One of '%s' test suites failed:" % ", ".join(proc.group)
+ print >>sys.stderr, proc.output
+ sys.exit(return_code)
- time.sleep(0.01)
+ time.sleep(0.01)
+ finally:
+ cleanup_processes(processes)