blob: e5f63fac812604eb8ed74896444616ded10f93f6 [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.
Vince Harronede59652015-01-08 02:11:26 +00005
Siva Chandra2d7832e2015-05-08 23:08:53 +00006Each test will run with a time limit of 10 minutes by default.
Vince Harronede59652015-01-08 02:11:26 +00007
Siva Chandra2d7832e2015-05-08 23:08:53 +00008Override the default time limit of 10 minutes by setting
Vince Harronede59652015-01-08 02:11:26 +00009the environment variable LLDB_TEST_TIMEOUT.
10
11E.g., export LLDB_TEST_TIMEOUT=10m
12
13Override the time limit for individual tests by setting
14the environment variable LLDB_[TEST NAME]_TIMEOUT.
15
16E.g., export LLDB_TESTCONCURRENTEVENTS_TIMEOUT=2m
17
18Set to "0" to run without time limit.
19
20E.g., export LLDB_TEST_TIMEOUT=0
21or export LLDB_TESTCONCURRENTEVENTS_TIMEOUT=0
Vince Harrondcc2b9f2015-05-27 04:40:36 +000022
Chaoren Linb6325d02015-08-12 18:02:54 +000023To collect core files for timed out tests,
24do the following before running dosep.py
Vince Harrondcc2b9f2015-05-27 04:40:36 +000025
26OSX
27ulimit -c unlimited
28sudo sysctl -w kern.corefile=core.%P
29
30Linux:
31ulimit -c unlimited
32echo core.%p | sudo tee /proc/sys/kernel/core_pattern
Johnny Chene8d9dc62011-10-31 19:04:07 +000033"""
34
Greg Clayton2256d0d2014-03-24 23:01:57 +000035import multiprocessing
Todd Fiala3f0a3602014-07-08 06:42:37 +000036import os
Vince Harrondcc2b9f2015-05-27 04:40:36 +000037import fnmatch
Todd Fiala3f0a3602014-07-08 06:42:37 +000038import platform
Vince Harron06381732015-05-12 23:10:36 +000039import re
Vince Harronf8b9a1d2015-05-18 19:40:54 +000040import dotest_args
Vince Harron17f429f2014-12-13 00:08:19 +000041import subprocess
Todd Fiala3f0a3602014-07-08 06:42:37 +000042import sys
Steve Puccibefe2b12014-03-07 00:01:11 +000043
Johnny Chene8d9dc62011-10-31 19:04:07 +000044from optparse import OptionParser
45
Chaoren Linb6325d02015-08-12 18:02:54 +000046
Vince Harron17f429f2014-12-13 00:08:19 +000047def get_timeout_command():
Vince Harronede59652015-01-08 02:11:26 +000048 """Search for a suitable timeout command."""
Ying Chen93190c42015-07-20 20:04:22 +000049 if not sys.platform.startswith("win32"):
50 try:
51 subprocess.call("timeout", stderr=subprocess.PIPE)
52 return "timeout"
53 except OSError:
54 pass
Vince Harron17f429f2014-12-13 00:08:19 +000055 try:
Chaoren Lin45c17ff2015-05-28 23:00:10 +000056 subprocess.call("gtimeout", stderr=subprocess.PIPE)
Vince Harron17f429f2014-12-13 00:08:19 +000057 return "gtimeout"
58 except OSError:
59 pass
60 return None
61
62timeout_command = get_timeout_command()
63
Vince Harron17f429f2014-12-13 00:08:19 +000064# Status codes for running command with timeout.
65eTimedOut, ePassed, eFailed = 124, 0, 1
66
Chaoren Lin5e3ab2b2015-06-01 17:49:25 +000067output_lock = None
68test_counter = None
69total_tests = None
Chaoren Linffc63b02015-08-12 18:02:49 +000070test_name_len = None
Pavel Labath05ab2372015-07-06 15:57:52 +000071dotest_options = None
Zachary Turner38e64172015-08-10 17:46:11 +000072output_on_success = False
Chaoren Lin5e3ab2b2015-06-01 17:49:25 +000073
Chaoren Linb6325d02015-08-12 18:02:54 +000074
Chaoren Linffc63b02015-08-12 18:02:49 +000075def setup_global_variables(lock, counter, total, name_len, options):
76 global output_lock, test_counter, total_tests, test_name_len
77 global dotest_options
Chaoren Lin5e3ab2b2015-06-01 17:49:25 +000078 output_lock = lock
79 test_counter = counter
80 total_tests = total
Chaoren Linffc63b02015-08-12 18:02:49 +000081 test_name_len = name_len
Pavel Labath05ab2372015-07-06 15:57:52 +000082 dotest_options = options
Chaoren Lin5e3ab2b2015-06-01 17:49:25 +000083
Chaoren Linb6325d02015-08-12 18:02:54 +000084
Zachary Turner38e64172015-08-10 17:46:11 +000085def report_test_failure(name, command, output):
86 global output_lock
87 with output_lock:
Chaoren Linffc63b02015-08-12 18:02:49 +000088 print >> sys.stderr
Zachary Turner38e64172015-08-10 17:46:11 +000089 print >> sys.stderr, output
Chaoren Linffc63b02015-08-12 18:02:49 +000090 print >> sys.stderr, "[%s FAILED]" % name
Zachary Turner38e64172015-08-10 17:46:11 +000091 print >> sys.stderr, "Command invoked: %s" % ' '.join(command)
Chaoren Linffc63b02015-08-12 18:02:49 +000092 update_progress(name)
Zachary Turner38e64172015-08-10 17:46:11 +000093
Chaoren Linb6325d02015-08-12 18:02:54 +000094
Zachary Turner38e64172015-08-10 17:46:11 +000095def report_test_pass(name, output):
96 global output_lock, output_on_success
97 with output_lock:
98 if output_on_success:
Chaoren Linffc63b02015-08-12 18:02:49 +000099 print >> sys.stderr
Zachary Turner38e64172015-08-10 17:46:11 +0000100 print >> sys.stderr, output
Chaoren Linffc63b02015-08-12 18:02:49 +0000101 print >> sys.stderr, "[%s PASSED]" % name
102 update_progress(name)
Zachary Turner38e64172015-08-10 17:46:11 +0000103
Chaoren Linb6325d02015-08-12 18:02:54 +0000104
Chaoren Linffc63b02015-08-12 18:02:49 +0000105def update_progress(test_name=""):
106 global output_lock, test_counter, total_tests, test_name_len
Chaoren Lin5e3ab2b2015-06-01 17:49:25 +0000107 with output_lock:
Chaoren Linffc63b02015-08-12 18:02:49 +0000108 counter_len = len(str(total_tests))
109 sys.stderr.write(
110 "\r%*d out of %d test suites processed - %-*s" %
111 (counter_len, test_counter.value, total_tests,
112 test_name_len.value, test_name))
113 if len(test_name) > test_name_len.value:
114 test_name_len.value = len(test_name)
Chaoren Lin5e3ab2b2015-06-01 17:49:25 +0000115 test_counter.value += 1
Zachary Turner38e64172015-08-10 17:46:11 +0000116 sys.stdout.flush()
117 sys.stderr.flush()
Chaoren Lin5e3ab2b2015-06-01 17:49:25 +0000118
Chaoren Linb6325d02015-08-12 18:02:54 +0000119
Zachary Turnerc7a7c8a2015-05-28 19:56:26 +0000120def parse_test_results(output):
121 passes = 0
122 failures = 0
Zachary Turner4cceca72015-08-14 16:45:32 +0000123 unexpected_successes = 0
Zachary Turnerc7a7c8a2015-05-28 19:56:26 +0000124 for result in output:
Chaoren Linb6325d02015-08-12 18:02:54 +0000125 pass_count = re.search("^RESULT:.*([0-9]+) passes",
126 result, re.MULTILINE)
127 fail_count = re.search("^RESULT:.*([0-9]+) failures",
128 result, re.MULTILINE)
129 error_count = re.search("^RESULT:.*([0-9]+) errors",
130 result, re.MULTILINE)
Zachary Turner4cceca72015-08-14 16:45:32 +0000131 unexpected_success_count = re.search("^RESULT:.*([0-9]+) unexpected successes",
132 result, re.MULTILINE)
Chaoren Linb6325d02015-08-12 18:02:54 +0000133 if pass_count is not None:
Zachary Turnerc7a7c8a2015-05-28 19:56:26 +0000134 passes = passes + int(pass_count.group(1))
Chaoren Linb6325d02015-08-12 18:02:54 +0000135 if fail_count is not None:
Zachary Turnerc7a7c8a2015-05-28 19:56:26 +0000136 failures = failures + int(fail_count.group(1))
Zachary Turner4cceca72015-08-14 16:45:32 +0000137 if unexpected_success_count is not None:
138 unexpected_successes = unexpected_successes + int(unexpected_success_count.group(1))
Chaoren Linb6325d02015-08-12 18:02:54 +0000139 if error_count is not None:
Zachary Turnerc7a7c8a2015-05-28 19:56:26 +0000140 failures = failures + int(error_count.group(1))
141 pass
Zachary Turner4cceca72015-08-14 16:45:32 +0000142 return passes, failures, unexpected_successes
Zachary Turnerc7a7c8a2015-05-28 19:56:26 +0000143
Chaoren Linb6325d02015-08-12 18:02:54 +0000144
Chaoren Lin5e3ab2b2015-06-01 17:49:25 +0000145def call_with_timeout(command, timeout, name):
Vince Harronede59652015-01-08 02:11:26 +0000146 """Run command with a timeout if possible."""
Vince Harrondcc2b9f2015-05-27 04:40:36 +0000147 """-s QUIT will create a coredump if they are enabled on your system"""
Zachary Turnerc7a7c8a2015-05-28 19:56:26 +0000148 process = None
149 if timeout_command and timeout != "0":
150 command = [timeout_command, '-s', 'QUIT', timeout] + command
Chaoren Linb6325d02015-08-12 18:02:54 +0000151 # Specifying a value for close_fds is unsupported on Windows when using
152 # subprocess.PIPE
Zachary Turnerdc494d52015-02-07 00:14:55 +0000153 if os.name != "nt":
Chaoren Linb6325d02015-08-12 18:02:54 +0000154 process = subprocess.Popen(command,
155 stdin=subprocess.PIPE,
156 stdout=subprocess.PIPE,
157 stderr=subprocess.PIPE,
158 close_fds=True)
Zachary Turnerdc494d52015-02-07 00:14:55 +0000159 else:
Chaoren Linb6325d02015-08-12 18:02:54 +0000160 process = subprocess.Popen(command,
161 stdin=subprocess.PIPE,
162 stdout=subprocess.PIPE,
163 stderr=subprocess.PIPE)
Zachary Turnerc7a7c8a2015-05-28 19:56:26 +0000164 output = process.communicate()
165 exit_status = process.returncode
Zachary Turner4cceca72015-08-14 16:45:32 +0000166 passes, failures, unexpected_successes = parse_test_results(output)
Zachary Turner38e64172015-08-10 17:46:11 +0000167 if exit_status == 0:
Chaoren Linb6325d02015-08-12 18:02:54 +0000168 # stdout does not have any useful information from 'dotest.py',
169 # only stderr does.
Zachary Turner38e64172015-08-10 17:46:11 +0000170 report_test_pass(name, output[1])
171 else:
172 report_test_failure(name, command, output[1])
Zachary Turner4cceca72015-08-14 16:45:32 +0000173 return name, exit_status, passes, failures, unexpected_successes
Johnny Chene8d9dc62011-10-31 19:04:07 +0000174
Chaoren Linb6325d02015-08-12 18:02:54 +0000175
Vince Harron41657cc2015-05-21 18:15:09 +0000176def process_dir(root, files, test_root, dotest_argv):
Steve Puccibefe2b12014-03-07 00:01:11 +0000177 """Examine a directory for tests, and invoke any found within it."""
Chaoren Line80372a2015-08-12 18:02:53 +0000178 results = []
Steve Puccibefe2b12014-03-07 00:01:11 +0000179 for name in files:
Zachary Turnerf6896b02015-01-05 19:37:03 +0000180 script_file = os.path.join(test_root, "dotest.py")
Zachary Turnerf6896b02015-01-05 19:37:03 +0000181 command = ([sys.executable, script_file] +
Vince Harron41657cc2015-05-21 18:15:09 +0000182 dotest_argv +
Todd Fialafed95662015-09-03 18:58:44 +0000183 ["--inferior", "-p", name, root])
Vince Harron17f429f2014-12-13 00:08:19 +0000184
185 timeout_name = os.path.basename(os.path.splitext(name)[0]).upper()
186
Chaoren Linb6325d02015-08-12 18:02:54 +0000187 timeout = (os.getenv("LLDB_%s_TIMEOUT" % timeout_name) or
188 getDefaultTimeout(dotest_options.lldb_platform_name))
Vince Harron17f429f2014-12-13 00:08:19 +0000189
Chaoren Line80372a2015-08-12 18:02:53 +0000190 results.append(call_with_timeout(command, timeout, name))
Vince Harron17f429f2014-12-13 00:08:19 +0000191
Zachary Turner4cceca72015-08-14 16:45:32 +0000192 # result = (name, status, passes, failures, unexpected_successes)
193 timed_out = [name for name, status, _, _, _ in results
Chaoren Line80372a2015-08-12 18:02:53 +0000194 if status == eTimedOut]
Zachary Turner4cceca72015-08-14 16:45:32 +0000195 passed = [name for name, status, _, _, _ in results
Chaoren Line80372a2015-08-12 18:02:53 +0000196 if status == ePassed]
Zachary Turner4cceca72015-08-14 16:45:32 +0000197 failed = [name for name, status, _, _, _ in results
Chaoren Line80372a2015-08-12 18:02:53 +0000198 if status != ePassed]
Zachary Turner4cceca72015-08-14 16:45:32 +0000199 unexpected_passes = [name for name, _, _, _, unexpected_successes in results
200 if unexpected_successes > 0]
Todd Fialafed95662015-09-03 18:58:44 +0000201
Chaoren Line80372a2015-08-12 18:02:53 +0000202 pass_count = sum([result[2] for result in results])
203 fail_count = sum([result[3] for result in results])
Zachary Turnerc7a7c8a2015-05-28 19:56:26 +0000204
Zachary Turner4cceca72015-08-14 16:45:32 +0000205 return (timed_out, passed, failed, unexpected_passes, pass_count, fail_count)
Steve Puccibefe2b12014-03-07 00:01:11 +0000206
207in_q = None
208out_q = None
209
Chaoren Linb6325d02015-08-12 18:02:54 +0000210
Todd Fiala3f0a3602014-07-08 06:42:37 +0000211def process_dir_worker(arg_tuple):
Steve Puccibefe2b12014-03-07 00:01:11 +0000212 """Worker thread main loop when in multithreaded mode.
213 Takes one directory specification at a time and works on it."""
Chaoren Line80372a2015-08-12 18:02:53 +0000214 return process_dir(*arg_tuple)
Steve Puccibefe2b12014-03-07 00:01:11 +0000215
Chaoren Linb6325d02015-08-12 18:02:54 +0000216
Vince Harron41657cc2015-05-21 18:15:09 +0000217def walk_and_invoke(test_directory, test_subdir, dotest_argv, num_threads):
Steve Puccibefe2b12014-03-07 00:01:11 +0000218 """Look for matched files and invoke test driver on each one.
219 In single-threaded mode, each test driver is invoked directly.
220 In multi-threaded mode, submit each test driver to a worker
Vince Harrone06a7a82015-05-12 23:12:19 +0000221 queue, and then wait for all to complete.
222
223 test_directory - lldb/test/ directory
Chaoren Linb6325d02015-08-12 18:02:54 +0000224 test_subdir - lldb/test/ or a subfolder with the tests we're interested in
225 running
Vince Harrone06a7a82015-05-12 23:12:19 +0000226 """
Todd Fiala3f0a3602014-07-08 06:42:37 +0000227
228 # Collect the test files that we'll run.
229 test_work_items = []
Vince Harrone06a7a82015-05-12 23:12:19 +0000230 for root, dirs, files in os.walk(test_subdir, topdown=False):
Chaoren Linffc63b02015-08-12 18:02:49 +0000231 def is_test(name):
232 # Not interested in symbolically linked files.
233 if os.path.islink(os.path.join(root, name)):
234 return False
235 # Only interested in test files with the "Test*.py" naming pattern.
236 return name.startswith("Test") and name.endswith(".py")
Todd Fiala3f0a3602014-07-08 06:42:37 +0000237
Chaoren Linffc63b02015-08-12 18:02:49 +0000238 tests = filter(is_test, files)
239 test_work_items.append((root, tests, test_directory, dotest_argv))
240
241 global output_lock, test_counter, total_tests, test_name_len
Zachary Turner38e64172015-08-10 17:46:11 +0000242 output_lock = multiprocessing.RLock()
Chaoren Linffc63b02015-08-12 18:02:49 +0000243 # item = (root, tests, test_directory, dotest_argv)
244 total_tests = sum([len(item[1]) for item in test_work_items])
Chaoren Lin5e3ab2b2015-06-01 17:49:25 +0000245 test_counter = multiprocessing.Value('i', 0)
Chaoren Linffc63b02015-08-12 18:02:49 +0000246 test_name_len = multiprocessing.Value('i', 0)
247 print >> sys.stderr, "Testing: %d test suites, %d thread%s" % (
248 total_tests, num_threads, (num_threads > 1) * "s")
249 update_progress()
Chaoren Lin5e3ab2b2015-06-01 17:49:25 +0000250
Todd Fiala3f0a3602014-07-08 06:42:37 +0000251 # Run the items, either in a pool (for multicore speedup) or
252 # calling each individually.
253 if num_threads > 1:
Chaoren Linffc63b02015-08-12 18:02:49 +0000254 pool = multiprocessing.Pool(
255 num_threads,
256 initializer=setup_global_variables,
257 initargs=(output_lock, test_counter, total_tests, test_name_len,
258 dotest_options))
Todd Fiala3f0a3602014-07-08 06:42:37 +0000259 test_results = pool.map(process_dir_worker, test_work_items)
260 else:
Chaoren Line80372a2015-08-12 18:02:53 +0000261 test_results = map(process_dir_worker, test_work_items)
Todd Fiala3f0a3602014-07-08 06:42:37 +0000262
Zachary Turner4cceca72015-08-14 16:45:32 +0000263 # result = (timed_out, failed, passed, unexpected_successes, fail_count, pass_count)
Chaoren Line80372a2015-08-12 18:02:53 +0000264 timed_out = sum([result[0] for result in test_results], [])
265 passed = sum([result[1] for result in test_results], [])
266 failed = sum([result[2] for result in test_results], [])
Zachary Turner4cceca72015-08-14 16:45:32 +0000267 unexpected_successes = sum([result[3] for result in test_results], [])
268 pass_count = sum([result[4] for result in test_results])
269 fail_count = sum([result[5] for result in test_results])
Todd Fiala3f0a3602014-07-08 06:42:37 +0000270
Zachary Turner4cceca72015-08-14 16:45:32 +0000271 return (timed_out, passed, failed, unexpected_successes, pass_count, fail_count)
Johnny Chene8d9dc62011-10-31 19:04:07 +0000272
Chaoren Linb6325d02015-08-12 18:02:54 +0000273
Vince Harronf8b9a1d2015-05-18 19:40:54 +0000274def getExpectedTimeouts(platform_name):
Vince Harron06381732015-05-12 23:10:36 +0000275 # returns a set of test filenames that might timeout
276 # are we running against a remote target?
Chaoren Linfebef1b2015-08-19 17:22:12 +0000277 host = sys.platform
Vince Harronf8b9a1d2015-05-18 19:40:54 +0000278 if platform_name is None:
Vince Harron06381732015-05-12 23:10:36 +0000279 target = sys.platform
280 remote = False
Vince Harronf8b9a1d2015-05-18 19:40:54 +0000281 else:
282 m = re.search('remote-(\w+)', platform_name)
283 target = m.group(1)
Vince Harron06381732015-05-12 23:10:36 +0000284
285 expected_timeout = set()
286
287 if target.startswith("linux"):
288 expected_timeout |= {
Vince Harronde92b522015-05-13 23:59:03 +0000289 "TestAttachDenied.py",
Chaoren Lin0b8bb3d2015-07-22 20:52:17 +0000290 "TestProcessAttach.py",
Vince Harron06381732015-05-12 23:10:36 +0000291 "TestConnectRemote.py",
292 "TestCreateAfterAttach.py",
Tamas Berghammer0d0ec9f2015-05-19 10:49:40 +0000293 "TestEvents.py",
Vince Harron06381732015-05-12 23:10:36 +0000294 "TestExitDuringStep.py",
Chaoren Linb6325d02015-08-12 18:02:54 +0000295
296 # Times out in ~10% of the times on the build bot
297 "TestHelloWorld.py",
Oleksiy Vyalov18f4c9f2015-06-10 01:34:25 +0000298 "TestMultithreaded.py",
Chaoren Linb6325d02015-08-12 18:02:54 +0000299 "TestRegisters.py", # ~12/600 dosep runs (build 3120-3122)
Vince Harron06381732015-05-12 23:10:36 +0000300 "TestThreadStepOut.py",
Chaoren Linb0138022015-08-19 18:39:25 +0000301 "TestChangeProcessGroup.py",
Vince Harron06381732015-05-12 23:10:36 +0000302 }
303 elif target.startswith("android"):
304 expected_timeout |= {
305 "TestExitDuringStep.py",
306 "TestHelloWorld.py",
307 }
Chaoren Linfebef1b2015-08-19 17:22:12 +0000308 if host.startswith("win32"):
309 expected_timeout |= {
310 "TestEvents.py",
311 "TestThreadStates.py",
312 }
Ed Maste4dd8fba2015-05-14 16:25:52 +0000313 elif target.startswith("freebsd"):
314 expected_timeout |= {
315 "TestBreakpointConditions.py",
Ed Maste08948132015-05-28 18:45:30 +0000316 "TestChangeProcessGroup.py",
Ed Mastebfd05632015-05-27 19:11:29 +0000317 "TestValueObjectRecursion.py",
Ed Maste4dd8fba2015-05-14 16:25:52 +0000318 "TestWatchpointConditionAPI.py",
319 }
Vince Harron0f173ac2015-05-18 19:36:33 +0000320 elif target.startswith("darwin"):
321 expected_timeout |= {
Chaoren Linb6325d02015-08-12 18:02:54 +0000322 # times out on MBP Retina, Mid 2012
323 "TestThreadSpecificBreakpoint.py",
Chaoren Lind9043712015-08-19 17:13:02 +0000324 "TestExitDuringStep.py",
Chaoren Lin99f25be2015-08-20 01:26:57 +0000325 "TestIntegerTypesExpr.py",
Vince Harron0f173ac2015-05-18 19:36:33 +0000326 }
Vince Harron06381732015-05-12 23:10:36 +0000327 return expected_timeout
328
Chaoren Linb6325d02015-08-12 18:02:54 +0000329
Pavel Labathfad30cf2015-06-29 14:16:51 +0000330def getDefaultTimeout(platform_name):
331 if os.getenv("LLDB_TEST_TIMEOUT"):
332 return os.getenv("LLDB_TEST_TIMEOUT")
333
334 if platform_name is None:
335 platform_name = sys.platform
336
337 if platform_name.startswith("remote-"):
338 return "10m"
339 else:
340 return "4m"
341
Chaoren Linb6325d02015-08-12 18:02:54 +0000342
Vince Harron0b9dbb52015-05-21 18:18:52 +0000343def touch(fname, times=None):
Greg Clayton8c3f9c92015-08-11 21:01:32 +0000344 if os.path.exists(fname):
Vince Harron0b9dbb52015-05-21 18:18:52 +0000345 os.utime(fname, times)
346
Chaoren Linb6325d02015-08-12 18:02:54 +0000347
Vince Harrondcc2b9f2015-05-27 04:40:36 +0000348def find(pattern, path):
349 result = []
350 for root, dirs, files in os.walk(path):
351 for name in files:
352 if fnmatch.fnmatch(name, pattern):
353 result.append(os.path.join(root, name))
354 return result
355
Chaoren Linb6325d02015-08-12 18:02:54 +0000356
Todd Fialafed95662015-09-03 18:58:44 +0000357def main(print_details_on_success, num_threads, test_subdir):
358 """Run dotest.py in inferior mode in parallel.
359
360 @param print_details_on_success the parsed value of the output-on-success
361 command line argument. When True, details of a successful dotest inferior
362 are printed even when everything succeeds. The normal behavior is to
363 not print any details when all the inferior tests pass.
364
365 @param num_threads the parsed value of the num-threads command line
366 argument.
367
368 @param test_subdir optionally specifies a subdir to limit testing
369 within. May be None if the entire test tree is to be used. This subdir
370 is assumed to be relative to the lldb/test root of the test hierarchy.
371 """
372
373 dotest_argv = sys.argv[1:]
374
375 global output_on_success
376 output_on_success = print_details_on_success
377
Vince Harrond5fa1022015-05-10 15:24:12 +0000378 # We can't use sys.path[0] to determine the script directory
379 # because it doesn't work under a debugger
Vince Harrone06a7a82015-05-12 23:12:19 +0000380 test_directory = os.path.dirname(os.path.realpath(__file__))
Johnny Chene8d9dc62011-10-31 19:04:07 +0000381 parser = OptionParser(usage="""\
382Run lldb test suite using a separate process for each test file.
Vince Harronede59652015-01-08 02:11:26 +0000383
Siva Chandra2d7832e2015-05-08 23:08:53 +0000384 Each test will run with a time limit of 10 minutes by default.
Vince Harronede59652015-01-08 02:11:26 +0000385
Siva Chandra2d7832e2015-05-08 23:08:53 +0000386 Override the default time limit of 10 minutes by setting
Vince Harronede59652015-01-08 02:11:26 +0000387 the environment variable LLDB_TEST_TIMEOUT.
388
389 E.g., export LLDB_TEST_TIMEOUT=10m
390
391 Override the time limit for individual tests by setting
392 the environment variable LLDB_[TEST NAME]_TIMEOUT.
393
394 E.g., export LLDB_TESTCONCURRENTEVENTS_TIMEOUT=2m
395
396 Set to "0" to run without time limit.
397
398 E.g., export LLDB_TEST_TIMEOUT=0
399 or export LLDB_TESTCONCURRENTEVENTS_TIMEOUT=0
Johnny Chene8d9dc62011-10-31 19:04:07 +0000400""")
Vince Harron8994fed2015-05-22 19:49:23 +0000401 parser = dotest_args.create_parser()
Pavel Labath05ab2372015-07-06 15:57:52 +0000402 global dotest_options
Vince Harron8994fed2015-05-22 19:49:23 +0000403 dotest_options = dotest_args.parse_args(parser, dotest_argv)
404
Vince Harron41657cc2015-05-21 18:15:09 +0000405 if not dotest_options.s:
406 # no session log directory, we need to add this to prevent
407 # every dotest invocation from creating its own directory
408 import datetime
409 # The windows platforms don't like ':' in the pathname.
Chaoren Linb6325d02015-08-12 18:02:54 +0000410 timestamp_started = datetime.datetime.now().strftime("%F-%H_%M_%S")
Vince Harron41657cc2015-05-21 18:15:09 +0000411 dotest_argv.append('-s')
412 dotest_argv.append(timestamp_started)
Vince Harron0b9dbb52015-05-21 18:18:52 +0000413 dotest_options.s = timestamp_started
414
415 session_dir = os.path.join(os.getcwd(), dotest_options.s)
Ed Mastecec2a5b2014-11-21 02:41:25 +0000416
Vince Harrone06a7a82015-05-12 23:12:19 +0000417 # The root directory was specified on the command line
Todd Fialafed95662015-09-03 18:58:44 +0000418 if test_subdir and len(test_subdir) > 0:
419 test_subdir = os.path.join(test_directory, test_subdir)
Vince Harrone06a7a82015-05-12 23:12:19 +0000420 else:
Todd Fialafed95662015-09-03 18:58:44 +0000421 test_subdir = test_directory
Vince Harrone06a7a82015-05-12 23:12:19 +0000422
Vince Harrondcc2b9f2015-05-27 04:40:36 +0000423 # clean core files in test tree from previous runs (Linux)
424 cores = find('core.*', test_subdir)
425 for core in cores:
426 os.unlink(core)
427
Todd Fialafed95662015-09-03 18:58:44 +0000428 if not num_threads:
Greg Clayton2256d0d2014-03-24 23:01:57 +0000429 num_threads_str = os.environ.get("LLDB_TEST_THREADS")
430 if num_threads_str:
431 num_threads = int(num_threads_str)
Greg Clayton2256d0d2014-03-24 23:01:57 +0000432 else:
Ed Mastecec2a5b2014-11-21 02:41:25 +0000433 num_threads = multiprocessing.cpu_count()
434 if num_threads < 1:
435 num_threads = 1
Johnny Chene8d9dc62011-10-31 19:04:07 +0000436
Daniel Maleab42556f2013-04-19 18:32:53 +0000437 system_info = " ".join(platform.uname())
Zachary Turner4cceca72015-08-14 16:45:32 +0000438 (timed_out, passed, failed, unexpected_successes, pass_count, fail_count) = walk_and_invoke(
Chaoren Line80372a2015-08-12 18:02:53 +0000439 test_directory, test_subdir, dotest_argv, num_threads)
Zachary Turnerc7a7c8a2015-05-28 19:56:26 +0000440
Vince Harron17f429f2014-12-13 00:08:19 +0000441 timed_out = set(timed_out)
Chaoren Line80372a2015-08-12 18:02:53 +0000442 num_test_files = len(passed) + len(failed)
443 num_test_cases = pass_count + fail_count
Daniel Maleab42556f2013-04-19 18:32:53 +0000444
Vince Harrondcc2b9f2015-05-27 04:40:36 +0000445 # move core files into session dir
446 cores = find('core.*', test_subdir)
447 for core in cores:
448 dst = core.replace(test_directory, "")[1:]
449 dst = dst.replace(os.path.sep, "-")
450 os.rename(core, os.path.join(session_dir, dst))
451
Vince Harron06381732015-05-12 23:10:36 +0000452 # remove expected timeouts from failures
Vince Harronf8b9a1d2015-05-18 19:40:54 +0000453 expected_timeout = getExpectedTimeouts(dotest_options.lldb_platform_name)
Vince Harron06381732015-05-12 23:10:36 +0000454 for xtime in expected_timeout:
455 if xtime in timed_out:
456 timed_out.remove(xtime)
457 failed.remove(xtime)
Vince Harron0b9dbb52015-05-21 18:18:52 +0000458 result = "ExpectedTimeout"
459 elif xtime in passed:
460 result = "UnexpectedCompletion"
461 else:
462 result = None # failed
463
464 if result:
465 test_name = os.path.splitext(xtime)[0]
466 touch(os.path.join(session_dir, "{}-{}".format(result, test_name)))
Vince Harron06381732015-05-12 23:10:36 +0000467
Chaoren Lin5e3ab2b2015-06-01 17:49:25 +0000468 print
Chaoren Lin5a59e462015-08-12 18:02:51 +0000469 sys.stdout.write("Ran %d test suites" % num_test_files)
470 if num_test_files > 0:
471 sys.stdout.write(" (%d failed) (%f%%)" % (
472 len(failed), 100.0 * len(failed) / num_test_files))
473 print
Chaoren Line80372a2015-08-12 18:02:53 +0000474 sys.stdout.write("Ran %d test cases" % num_test_cases)
475 if num_test_cases > 0:
Chaoren Lin5a59e462015-08-12 18:02:51 +0000476 sys.stdout.write(" (%d failed) (%f%%)" % (
Chaoren Line80372a2015-08-12 18:02:53 +0000477 fail_count, 100.0 * fail_count / num_test_cases))
Chaoren Lin5a59e462015-08-12 18:02:51 +0000478 print
Zachary Turner4cceca72015-08-14 16:45:32 +0000479 exit_code = 0
480
Daniel Maleacbaef262013-02-15 21:31:37 +0000481 if len(failed) > 0:
Shawn Best13491c42014-10-22 19:29:00 +0000482 failed.sort()
Ying Chen10ed1a92015-05-28 23:51:49 +0000483 print "Failing Tests (%d)" % len(failed)
Daniel Maleacbaef262013-02-15 21:31:37 +0000484 for f in failed:
Vince Harron17f429f2014-12-13 00:08:19 +0000485 print "%s: LLDB (suite) :: %s (%s)" % (
486 "TIMEOUT" if f in timed_out else "FAIL", f, system_info
487 )
Zachary Turner4cceca72015-08-14 16:45:32 +0000488 exit_code = 1
489
490 if len(unexpected_successes) > 0:
491 unexpected_successes.sort()
492 print "\nUnexpected Successes (%d)" % len(unexpected_successes)
493 for u in unexpected_successes:
494 print "UNEXPECTED SUCCESS: LLDB (suite) :: %s (%s)" % (u, system_info)
495
496 sys.exit(exit_code)
Johnny Chene8d9dc62011-10-31 19:04:07 +0000497
498if __name__ == '__main__':
Todd Fialafed95662015-09-03 18:58:44 +0000499 sys.stderr.write(
500 "error: dosep.py no longer supports being called directly. "
501 "Please call dotest.py directly. The dosep.py-specific arguments "
502 "have been added under the Parallel processing arguments.\n")
503 sys.exit(128)