|
44 | 44 |
|
45 | 45 | import glob |
46 | 46 | import os |
| 47 | +import multiprocessing |
47 | 48 | import re |
48 | 49 | import sys |
49 | 50 | from distutils.sysconfig import get_python_inc |
@@ -620,35 +621,64 @@ def exclude_tests_below(path): |
620 | 621 | exclude_test('tests/cpychecker/refcounts/cplusplus/destructor') |
621 | 622 | exclude_test('tests/cpychecker/refcounts/cplusplus/empty-function') |
622 | 623 |
|
623 | | - |
624 | | -num_passes = 0 |
625 | | -skipped_tests = [] |
626 | | -failed_tests = [] |
627 | | -for testdir in sorted(testdirs): |
| 624 | +def run_one_test(testdir): |
628 | 625 | try: |
629 | 626 | sys.stdout.write('%s: ' % testdir) |
630 | 627 | run_test(testdir) |
631 | 628 | print('OK') |
632 | | - num_passes += 1 |
| 629 | + return (testdir, 'OK', None) |
633 | 630 | except SkipTest: |
634 | 631 | err = sys.exc_info()[1] |
635 | 632 | print('skipped: %s' % err.reason) |
636 | | - skipped_tests.append(testdir) |
| 633 | + return (testdir, 'SKIP', err.reason) |
637 | 634 | except RuntimeError: |
638 | 635 | err = sys.exc_info()[1] |
639 | 636 | print('FAIL') |
640 | 637 | print(err) |
641 | | - failed_tests.append(testdir) |
| 638 | + return (testdir, 'FAIL', None) |
| 639 | + |
| 640 | +class TestRunner: |
| 641 | + def __init__(self): |
| 642 | + self.num_passes = 0 |
| 643 | + self.skipped_tests = [] |
| 644 | + self.failed_tests = [] |
| 645 | + |
| 646 | + def run_tests(self, testdirs): |
| 647 | + for testdir in sorted(testdirs): |
| 648 | + tr.handle_outcome(run_one_test(testdir)) |
| 649 | + |
| 650 | + def run_tests_in_parallel(self, testdirs): |
| 651 | + pool = multiprocessing.Pool(None) # uses cpu_count |
| 652 | + for outcome in pool.map(run_one_test, testdirs): |
| 653 | + tr.handle_outcome(outcome) |
| 654 | + |
| 655 | + def handle_outcome(self, outcome): |
| 656 | + testdir, result, detail = outcome |
| 657 | + if result == 'OK': |
| 658 | + self.num_passes += 1 |
| 659 | + elif result == 'SKIP': |
| 660 | + self.skipped_tests.append(testdir) |
| 661 | + else: |
| 662 | + assert result == 'FAIL' |
| 663 | + self.failed_tests.append(testdir) |
| 664 | + |
| 665 | + def print_results(self): |
| 666 | + def num(count, singular, plural): |
| 667 | + return '%i %s' % (count, singular if count == 1 else plural) |
642 | 668 |
|
643 | | -def num(count, singular, plural): |
644 | | - return '%i %s' % (count, singular if count == 1 else plural) |
| 669 | + print('%s; %s; %s' % (num(self.num_passes, "success", "successes"), |
| 670 | + num(len(self.failed_tests), "failure", "failures"), |
| 671 | + num(len(self.skipped_tests), "skipped", "skipped"))) |
645 | 672 |
|
646 | | -print('%s; %s; %s' % (num(num_passes, "success", "successes"), |
647 | | - num(len(failed_tests), "failure", "failures"), |
648 | | - num(len(skipped_tests), "skipped", "skipped"))) |
649 | | -if len(failed_tests) > 0: |
| 673 | +tr = TestRunner() |
| 674 | +if 1: |
| 675 | + tr.run_tests_in_parallel(sorted(testdirs)) |
| 676 | +else: |
| 677 | + tr.run_tests(sorted(testdirs)) |
| 678 | + |
| 679 | +tr.print_results() |
| 680 | +if len(tr.failed_tests) > 0: |
650 | 681 | print('Failed tests:') |
651 | | - for test in failed_tests: |
| 682 | + for test in tr.failed_tests: |
652 | 683 | print(' %s' % test) |
653 | 684 | sys.exit(1) |
654 | | - |
|
0 commit comments