run-tests: optionally parallelize tests
When requested via 'run-tests -j', more than one test will be run at a time. On my system, (i5-3320m with 4 threads / 2 cores), this reduces elapsed time by over 50% when testing pots/unix/micropython. Elapsed time, seconds, best of 3 runs with each -j value: before patchset: 18.1 -j1: 18.1 -j2: 11.3 (-37%) -j4: 8.7 (-52%) -j6: 8.4 (-54%) In all cases the final output is identical: 651 tests performed (18932 individual testcases) 651 tests passed 23 tests skipped: buffered_writer... though the individual pass/fail messages can be different/interleaved.
This commit is contained in:
parent
b9dd6a5bb4
commit
a3309ebb80
|
@ -7,6 +7,7 @@ import platform
|
||||||
import argparse
|
import argparse
|
||||||
import re
|
import re
|
||||||
import threading
|
import threading
|
||||||
|
from multiprocessing.pool import ThreadPool
|
||||||
from glob import glob
|
from glob import glob
|
||||||
|
|
||||||
# Tests require at least CPython 3.3. If your default python3 executable
|
# Tests require at least CPython 3.3. If your default python3 executable
|
||||||
|
@ -213,7 +214,7 @@ class ThreadSafeCounter:
|
||||||
def value(self):
|
def value(self):
|
||||||
return self._value
|
return self._value
|
||||||
|
|
||||||
def run_tests(pyb, tests, args, base_path="."):
|
def run_tests(pyb, tests, args, base_path=".", num_threads=1):
|
||||||
test_count = ThreadSafeCounter()
|
test_count = ThreadSafeCounter()
|
||||||
testcase_count = ThreadSafeCounter()
|
testcase_count = ThreadSafeCounter()
|
||||||
passed_count = ThreadSafeCounter()
|
passed_count = ThreadSafeCounter()
|
||||||
|
@ -454,8 +455,12 @@ def run_tests(pyb, tests, args, base_path="."):
|
||||||
|
|
||||||
test_count.add(1)
|
test_count.add(1)
|
||||||
|
|
||||||
for test_file in tests:
|
if num_threads > 1:
|
||||||
run_one_test(test_file)
|
pool = ThreadPool(num_threads)
|
||||||
|
pool.map(run_one_test, tests)
|
||||||
|
else:
|
||||||
|
for test in tests:
|
||||||
|
run_one_test(test)
|
||||||
|
|
||||||
print("{} tests performed ({} individual testcases)".format(test_count.value, testcase_count.value))
|
print("{} tests performed ({} individual testcases)".format(test_count.value, testcase_count.value))
|
||||||
print("{} tests passed".format(passed_count.value))
|
print("{} tests passed".format(passed_count.value))
|
||||||
|
@ -482,6 +487,7 @@ def main():
|
||||||
cmd_parser.add_argument('--heapsize', help='heapsize to use (use default if not specified)')
|
cmd_parser.add_argument('--heapsize', help='heapsize to use (use default if not specified)')
|
||||||
cmd_parser.add_argument('--via-mpy', action='store_true', help='compile .py files to .mpy first')
|
cmd_parser.add_argument('--via-mpy', action='store_true', help='compile .py files to .mpy first')
|
||||||
cmd_parser.add_argument('--keep-path', action='store_true', help='do not clear MICROPYPATH when running tests')
|
cmd_parser.add_argument('--keep-path', action='store_true', help='do not clear MICROPYPATH when running tests')
|
||||||
|
cmd_parser.add_argument('-j', '--jobs', default=1, metavar='N', type=int, help='Number of tests to run simultaneously')
|
||||||
cmd_parser.add_argument('files', nargs='*', help='input test files')
|
cmd_parser.add_argument('files', nargs='*', help='input test files')
|
||||||
args = cmd_parser.parse_args()
|
args = cmd_parser.parse_args()
|
||||||
|
|
||||||
|
@ -525,7 +531,7 @@ def main():
|
||||||
# run-tests script itself.
|
# run-tests script itself.
|
||||||
base_path = os.path.dirname(sys.argv[0]) or "."
|
base_path = os.path.dirname(sys.argv[0]) or "."
|
||||||
try:
|
try:
|
||||||
res = run_tests(pyb, tests, args, base_path)
|
res = run_tests(pyb, tests, args, base_path, args.jobs)
|
||||||
finally:
|
finally:
|
||||||
if pyb:
|
if pyb:
|
||||||
pyb.close()
|
pyb.close()
|
||||||
|
|
Loading…
Reference in New Issue