blob: 0a7976f16abf08c64df8b4d14d1630a71c39fd82 [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
Daniel Maleab42556f2013-04-19 18:32:53 +00007import os, sys, platform
Steve Puccibefe2b12014-03-07 00:01:11 +00008import Queue, threading
Greg Clayton2256d0d2014-03-24 23:01:57 +00009import multiprocessing
Steve Puccibefe2b12014-03-07 00:01:11 +000010
Johnny Chene8d9dc62011-10-31 19:04:07 +000011from optparse import OptionParser
12
13# Command template of the invocation of the test driver.
Todd Fialaa4ec2fc2014-06-02 17:49:35 +000014template = '%s %s/dotest.py %s -p %s %s'
Johnny Chene8d9dc62011-10-31 19:04:07 +000015
Steve Puccibefe2b12014-03-07 00:01:11 +000016def process_dir(root, files, test_root, dotest_options):
17 """Examine a directory for tests, and invoke any found within it."""
Daniel Maleacbaef262013-02-15 21:31:37 +000018 failed = []
19 passed = []
Steve Puccibefe2b12014-03-07 00:01:11 +000020 for name in files:
21 path = os.path.join(root, name)
22
23 # We're only interested in the test file with the "Test*.py" naming pattern.
24 if not name.startswith("Test") or not name.endswith(".py"):
25 continue
26
27 # Neither a symbolically linked file.
28 if os.path.islink(path):
29 continue
30
Todd Fialaa4ec2fc2014-06-02 17:49:35 +000031 command = template % (sys.executable, test_root, dotest_options if dotest_options else "", name, root)
Steve Puccibefe2b12014-03-07 00:01:11 +000032 if 0 != os.system(command):
33 failed.append(name)
34 else:
35 passed.append(name)
36 return (failed, passed)
37
38in_q = None
39out_q = None
40
41def process_dir_worker():
42 """Worker thread main loop when in multithreaded mode.
43 Takes one directory specification at a time and works on it."""
44 while True:
45 (root, files, test_root, dotest_options) = in_q.get()
46 (dir_failed, dir_passed) = process_dir(root, files, test_root, dotest_options)
47 out_q.put((dir_failed, dir_passed))
48 in_q.task_done()
49
50def walk_and_invoke(test_root, dotest_options, num_threads):
51 """Look for matched files and invoke test driver on each one.
52 In single-threaded mode, each test driver is invoked directly.
53 In multi-threaded mode, submit each test driver to a worker
54 queue, and then wait for all to complete."""
55 failed = []
56 passed = []
57 if (num_threads > 1):
Ed Maste03c92072014-03-25 15:17:23 +000058 print("Running multithreaded with %d threads" % num_threads)
Steve Puccibefe2b12014-03-07 00:01:11 +000059 global in_q
60 global out_q
61 in_q = Queue.Queue()
62 out_q = Queue.Queue()
63 for i in range(num_threads):
64 t = threading.Thread(target=process_dir_worker)
65 t.daemon = True
66 t.start()
Steve Pucci44ba1712014-03-16 18:23:59 +000067 else:
Ed Maste03c92072014-03-25 15:17:23 +000068 print("Running single-threaded")
Johnny Chene8d9dc62011-10-31 19:04:07 +000069 for root, dirs, files in os.walk(test_root, topdown=False):
Steve Puccibefe2b12014-03-07 00:01:11 +000070 if (num_threads > 1):
71 in_q.put((root, files, test_root, dotest_options))
72 else:
73 (dir_failed, dir_passed) = process_dir(root, files, test_root, dotest_options)
74 failed += dir_failed
75 passed += dir_passed
76 if (num_threads > 1):
77 in_q.join()
78 while not out_q.empty():
79 (dir_failed, dir_passed) = out_q.get()
80 failed += dir_failed
81 passed += dir_passed
Daniel Maleacbaef262013-02-15 21:31:37 +000082 return (failed, passed)
Johnny Chene8d9dc62011-10-31 19:04:07 +000083
84def main():
Johnny Chene8d9dc62011-10-31 19:04:07 +000085 test_root = sys.path[0]
86
87 parser = OptionParser(usage="""\
88Run lldb test suite using a separate process for each test file.
89""")
90 parser.add_option('-o', '--options',
91 type='string', action='store',
92 dest='dotest_options',
93 help="""The options passed to 'dotest.py' if specified.""")
94
Greg Clayton2256d0d2014-03-24 23:01:57 +000095 parser.add_option('-t', '--threads',
96 type='int',
97 dest='num_threads',
98 help="""The number of threads to use when running tests separately.""",
99 default=multiprocessing.cpu_count())
100
Johnny Chene8d9dc62011-10-31 19:04:07 +0000101 opts, args = parser.parse_args()
102 dotest_options = opts.dotest_options
Greg Clayton2256d0d2014-03-24 23:01:57 +0000103 num_threads = opts.num_threads
104 if num_threads < 1:
105 num_threads_str = os.environ.get("LLDB_TEST_THREADS")
106 if num_threads_str:
107 num_threads = int(num_threads_str)
108 if num_threads < 1:
109 num_threads = 1
110 else:
Steve Puccibefe2b12014-03-07 00:01:11 +0000111 num_threads = 1
Johnny Chene8d9dc62011-10-31 19:04:07 +0000112
Daniel Maleab42556f2013-04-19 18:32:53 +0000113 system_info = " ".join(platform.uname())
Steve Puccibefe2b12014-03-07 00:01:11 +0000114 (failed, passed) = walk_and_invoke(test_root, dotest_options, num_threads)
Daniel Maleacbaef262013-02-15 21:31:37 +0000115 num_tests = len(failed) + len(passed)
Daniel Maleab42556f2013-04-19 18:32:53 +0000116
Daniel Maleacbaef262013-02-15 21:31:37 +0000117 print "Ran %d tests." % num_tests
118 if len(failed) > 0:
119 print "Failing Tests (%d)" % len(failed)
120 for f in failed:
Daniel Maleab42556f2013-04-19 18:32:53 +0000121 print "FAIL: LLDB (suite) :: %s (%s)" % (f, system_info)
Daniel Maleacbaef262013-02-15 21:31:37 +0000122 sys.exit(1)
123 sys.exit(0)
Johnny Chene8d9dc62011-10-31 19:04:07 +0000124
125if __name__ == '__main__':
126 main()