blob: 153b8fc9bfd1d97cc648583facf504686fc912f9 [file] [log] [blame]
Johnny Chene8d9dc62011-10-31 19:04:07 +00001#!/usr/bin/env python
2
3"""
4Run the test suite using a separate process for each test file.
5"""
6
Greg Clayton2256d0d2014-03-24 23:01:57 +00007import multiprocessing
Todd Fiala3f0a3602014-07-08 06:42:37 +00008import os
9import platform
10import sys
Steve Puccibefe2b12014-03-07 00:01:11 +000011
Johnny Chene8d9dc62011-10-31 19:04:07 +000012from optparse import OptionParser
13
14# Command template of the invocation of the test driver.
Todd Fialaa4ec2fc2014-06-02 17:49:35 +000015template = '%s %s/dotest.py %s -p %s %s'
Johnny Chene8d9dc62011-10-31 19:04:07 +000016
Steve Puccibefe2b12014-03-07 00:01:11 +000017def process_dir(root, files, test_root, dotest_options):
18 """Examine a directory for tests, and invoke any found within it."""
Daniel Maleacbaef262013-02-15 21:31:37 +000019 failed = []
20 passed = []
Steve Puccibefe2b12014-03-07 00:01:11 +000021 for name in files:
22 path = os.path.join(root, name)
23
24 # We're only interested in the test file with the "Test*.py" naming pattern.
25 if not name.startswith("Test") or not name.endswith(".py"):
26 continue
27
28 # Neither a symbolically linked file.
29 if os.path.islink(path):
30 continue
31
Todd Fialaa4ec2fc2014-06-02 17:49:35 +000032 command = template % (sys.executable, test_root, dotest_options if dotest_options else "", name, root)
Steve Puccibefe2b12014-03-07 00:01:11 +000033 if 0 != os.system(command):
34 failed.append(name)
35 else:
36 passed.append(name)
37 return (failed, passed)
38
39in_q = None
40out_q = None
41
Todd Fiala3f0a3602014-07-08 06:42:37 +000042def process_dir_worker(arg_tuple):
Steve Puccibefe2b12014-03-07 00:01:11 +000043 """Worker thread main loop when in multithreaded mode.
44 Takes one directory specification at a time and works on it."""
Todd Fiala3f0a3602014-07-08 06:42:37 +000045 (root, files, test_root, dotest_options) = arg_tuple
46 return process_dir(root, files, test_root, dotest_options)
Steve Puccibefe2b12014-03-07 00:01:11 +000047
48def walk_and_invoke(test_root, dotest_options, num_threads):
49 """Look for matched files and invoke test driver on each one.
50 In single-threaded mode, each test driver is invoked directly.
51 In multi-threaded mode, submit each test driver to a worker
52 queue, and then wait for all to complete."""
Todd Fiala3f0a3602014-07-08 06:42:37 +000053
54 # Collect the test files that we'll run.
55 test_work_items = []
56 for root, dirs, files in os.walk(test_root, topdown=False):
57 test_work_items.append((root, files, test_root, dotest_options))
58
59 # Run the items, either in a pool (for multicore speedup) or
60 # calling each individually.
61 if num_threads > 1:
62 pool = multiprocessing.Pool(num_threads)
63 test_results = pool.map(process_dir_worker, test_work_items)
64 else:
65 test_results = []
66 for work_item in test_work_items:
67 test_results.append(process_dir_worker(work_item))
68
Steve Puccibefe2b12014-03-07 00:01:11 +000069 failed = []
70 passed = []
Todd Fiala3f0a3602014-07-08 06:42:37 +000071
72 for test_result in test_results:
73 (dir_failed, dir_passed) = test_result
74 failed += dir_failed
75 passed += dir_passed
76
Daniel Maleacbaef262013-02-15 21:31:37 +000077 return (failed, passed)
Johnny Chene8d9dc62011-10-31 19:04:07 +000078
79def main():
Johnny Chene8d9dc62011-10-31 19:04:07 +000080 test_root = sys.path[0]
81
82 parser = OptionParser(usage="""\
83Run lldb test suite using a separate process for each test file.
84""")
85 parser.add_option('-o', '--options',
86 type='string', action='store',
87 dest='dotest_options',
88 help="""The options passed to 'dotest.py' if specified.""")
89
Greg Clayton2256d0d2014-03-24 23:01:57 +000090 parser.add_option('-t', '--threads',
91 type='int',
92 dest='num_threads',
Ed Mastecec2a5b2014-11-21 02:41:25 +000093 help="""The number of threads to use when running tests separately.""")
Greg Clayton2256d0d2014-03-24 23:01:57 +000094
Johnny Chene8d9dc62011-10-31 19:04:07 +000095 opts, args = parser.parse_args()
96 dotest_options = opts.dotest_options
Ed Mastecec2a5b2014-11-21 02:41:25 +000097
98 if opts.num_threads:
99 num_threads = opts.num_threads
100 else:
Greg Clayton2256d0d2014-03-24 23:01:57 +0000101 num_threads_str = os.environ.get("LLDB_TEST_THREADS")
102 if num_threads_str:
103 num_threads = int(num_threads_str)
Greg Clayton2256d0d2014-03-24 23:01:57 +0000104 else:
Ed Mastecec2a5b2014-11-21 02:41:25 +0000105 num_threads = multiprocessing.cpu_count()
106 if num_threads < 1:
107 num_threads = 1
Johnny Chene8d9dc62011-10-31 19:04:07 +0000108
Daniel Maleab42556f2013-04-19 18:32:53 +0000109 system_info = " ".join(platform.uname())
Steve Puccibefe2b12014-03-07 00:01:11 +0000110 (failed, passed) = walk_and_invoke(test_root, dotest_options, num_threads)
Daniel Maleacbaef262013-02-15 21:31:37 +0000111 num_tests = len(failed) + len(passed)
Daniel Maleab42556f2013-04-19 18:32:53 +0000112
Daniel Maleacbaef262013-02-15 21:31:37 +0000113 print "Ran %d tests." % num_tests
114 if len(failed) > 0:
Shawn Best13491c42014-10-22 19:29:00 +0000115 failed.sort()
Daniel Maleacbaef262013-02-15 21:31:37 +0000116 print "Failing Tests (%d)" % len(failed)
117 for f in failed:
Daniel Maleab42556f2013-04-19 18:32:53 +0000118 print "FAIL: LLDB (suite) :: %s (%s)" % (f, system_info)
Daniel Maleacbaef262013-02-15 21:31:37 +0000119 sys.exit(1)
120 sys.exit(0)
Johnny Chene8d9dc62011-10-31 19:04:07 +0000121
122if __name__ == '__main__':
123 main()