Commit d59dcac0 authored by Thanassis Tsiodras's avatar Thanassis Tsiodras
Browse files

Parallel execution of all tests.

parent 2726f5c8
#!/usr/bin/env python3
This uses all available cores to spawn processes that build
all test projects (Demo_*/)
import os
import sys
import time
import signal
import multiprocessing
# Tell the orchestrator to..
# - stop complaining about POHI issues under multicores
# - immediately abort in case of error (No "Hit ENTER...")
os.putenv("CLEANUP", "1")
def get_tests():
"""Collect all Demo_... folders not excluded via 'NOTEST' """
for folder in sorted(os.listdir(".")):
if all([folder.startswith('Demo'),
not os.path.exists(folder + "/NOTEST")]):
yield folder
def build_me(folder):
Performs a build in the passed-in folder, and also spawns
(if it exists in that folder).
Spawned from a multiprocessing pool, returns the result back in tuple form
for asynchronous reporting.
root = os.getcwd()
res = os.system("./bui*.sh > build.log 2>&1 || exit 1")
if res != 0:
return folder, False, "Build failed..."
if os.path.exists(""):
res = os.system("./ > regression.log 2>&1 || exit 1")
if res != 0:
return folder, False, "Regression check failed..."
return folder, True, "OK"
def color_me(result, msg):
"""Color the output according to the result."""
if sys.stdout.isatty():
msg = chr(27) + "[3" + (
"2" if result else "1") + "m" + msg + chr(27) + "[0m"
return msg
def main():
"""Run the TASTE regression-checking project suite"""
cwd = os.path.dirname(os.path.realpath(__file__))
# Navigate to the folder hosting all test projects (i.e. "Demo_*/")
# Detect how many workers we will use
total_cpus = multiprocessing.cpu_count()
total_tests = len(list(get_tests()))
# Measure time to execute
start_time = time.time()
print("Spawning", total_cpus, "workers to run", total_tests, "tests...\n")
pool = multiprocessing.Pool(total_cpus)
failed_tests = 0
run_tests = 0
results = pool.imap_unordered(build_me, get_tests())
for res in results:
run_tests += 1
test, result, msg = res
print("%40s: %s" % (test, color_me(result, msg)))
if not result:
failed_tests += 1
except KeyboardInterrupt:
# The devil is always in the details... This is the only
# way I found to propagate the SIGINT to the builds done
# by the worker processes of the pool AND immediately
# terminate. Numerous people cry about it on the web...
# ...and I had to look at the code of concurrent.futures
# (which I abandoned), multiprocessing/,
# multiprocessing/ AND to see
# what I had to do. Gotta love our profession.
for job in pool._pool: # pylint: disable=W0212
os.kill(, signal.SIGINT)
print("\nFinished in %d seconds." % (time.time() - start_time))
print(run_tests, "tests,", failed_tests, "failure" + (
"s" if (failed_tests > 1 or failed_tests == 0) else "") + ".")
if __name__ == "__main__":
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment