blob: 466f7f5c2be6bd8b2d75e98b4450b89c24875340 [file] [log] [blame]
Johnny Chen9707bb62010-06-25 21:14:08 +00001#!/usr/bin/env python
2
3"""
4A simple testing framework for lldb using python's unit testing framework.
5
6Tests for lldb are written as python scripts which take advantage of the script
7bridging provided by LLDB.framework to interact with lldb core.
8
9A specific naming pattern is followed by the .py script to be recognized as
10a module which implements a test scenario, namely, Test*.py.
11
12To specify the directories where "Test*.py" python test scripts are located,
13you need to pass in a list of directory names. By default, the current
14working directory is searched if nothing is specified on the command line.
Johnny Chen872aee12010-09-16 15:44:23 +000015
16Type:
17
18./dotest.py -h
19
20for available options.
Johnny Chen9707bb62010-06-25 21:14:08 +000021"""
22
Johnny Chen91960d32010-09-08 20:56:16 +000023import os, signal, sys, time
Johnny Chen2891bb02011-09-16 01:04:26 +000024import subprocess
Johnny Chen75e28f92010-08-05 23:42:46 +000025import unittest2
Johnny Chen9707bb62010-06-25 21:14:08 +000026
Johnny Chen26901c82011-03-11 19:47:23 +000027def is_exe(fpath):
Johnny Chenf2c7b282011-04-26 23:10:51 +000028 """Returns true if fpath is an executable."""
Johnny Chen26901c82011-03-11 19:47:23 +000029 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
30
Johnny Chen26901c82011-03-11 19:47:23 +000031def which(program):
Johnny Chenf2c7b282011-04-26 23:10:51 +000032 """Returns the full path to a program; None otherwise."""
Johnny Chen26901c82011-03-11 19:47:23 +000033 fpath, fname = os.path.split(program)
34 if fpath:
35 if is_exe(program):
36 return program
37 else:
38 for path in os.environ["PATH"].split(os.pathsep):
39 exe_file = os.path.join(path, program)
40 if is_exe(exe_file):
41 return exe_file
42 return None
43
Johnny Chen877c7e42010-08-07 00:16:07 +000044class _WritelnDecorator(object):
45 """Used to decorate file-like objects with a handy 'writeln' method"""
46 def __init__(self,stream):
47 self.stream = stream
48
49 def __getattr__(self, attr):
50 if attr in ('stream', '__getstate__'):
51 raise AttributeError(attr)
52 return getattr(self.stream,attr)
53
54 def writeln(self, arg=None):
55 if arg:
56 self.write(arg)
57 self.write('\n') # text-mode streams translate to \r\n if needed
58
Johnny Chen9707bb62010-06-25 21:14:08 +000059#
60# Global variables:
61#
62
63# The test suite.
Johnny Chen75e28f92010-08-05 23:42:46 +000064suite = unittest2.TestSuite()
Johnny Chen9707bb62010-06-25 21:14:08 +000065
Johnny Chen4f93bf12010-12-10 00:51:23 +000066# By default, both command line and Python API tests are performed.
Johnny Chen3ebdacc2010-12-10 18:52:10 +000067# Use @python_api_test decorator, defined in lldbtest.py, to mark a test as
68# a Python API test.
Johnny Chen4f93bf12010-12-10 00:51:23 +000069dont_do_python_api_test = False
70
71# By default, both command line and Python API tests are performed.
Johnny Chen4f93bf12010-12-10 00:51:23 +000072just_do_python_api_test = False
73
Johnny Chen82ccf402011-07-30 01:39:58 +000074# By default, benchmarks tests are not run.
75just_do_benchmarks_test = False
76
Johnny Chen82e6b1e2010-12-01 22:47:54 +000077# The blacklist is optional (-b blacklistFile) and allows a central place to skip
78# testclass's and/or testclass.testmethod's.
79blacklist = None
80
81# The dictionary as a result of sourcing blacklistFile.
82blacklistConfig = {}
83
Johnny Chen9fdb0a92010-09-18 00:16:47 +000084# The config file is optional.
85configFile = None
86
Johnny Chend2acdb32010-11-16 22:42:58 +000087# Test suite repeat count. Can be overwritten with '-# count'.
88count = 1
89
Johnny Chenb40056b2010-09-21 00:09:27 +000090# The dictionary as a result of sourcing configFile.
91config = {}
92
Johnny Chen1a4d5e72011-03-04 01:35:22 +000093# The 'archs' and 'compilers' can be specified via either command line or configFile,
94# with the command line overriding the configFile. When specified, they should be
95# of the list type. For example, "-A x86_64^i386" => archs=['x86_64', 'i386'] and
96# "-C gcc^clang" => compilers=['gcc', 'clang'].
Johnny Chen7798d782012-03-09 00:44:59 +000097archs = ['x86_64', 'i386']
Johnny Chen92693b52012-03-09 02:11:37 +000098compilers = ['clang']
Johnny Chen1a4d5e72011-03-04 01:35:22 +000099
Johnny Chen91960d32010-09-08 20:56:16 +0000100# Delay startup in order for the debugger to attach.
101delay = False
102
Johnny Chend5362332011-01-29 01:21:04 +0000103# Dump the Python sys.path variable. Use '-D' to dump sys.path.
Johnny Chen50bc6382011-01-29 01:16:52 +0000104dumpSysPath = False
105
Johnny Chene00c9302011-10-10 22:03:44 +0000106# Full path of the benchmark executable, as specified by the '-e' option.
107bmExecutable = None
108# The breakpoint specification of bmExecutable, as specified by the '-x' option.
109bmBreakpointSpec = None
Johnny Chen5f2ed172011-10-20 18:43:28 +0000110# The benchamrk iteration count, as specified by the '-y' option.
111bmIterationCount = -1
Johnny Chene00c9302011-10-10 22:03:44 +0000112
Johnny Chene9eae812012-01-18 05:15:00 +0000113# By default, don't exclude any directories. Use '-X' to add one excluded directory.
114excluded = set(['.svn', '.git'])
115
Johnny Chen7d6d8442010-12-03 19:59:35 +0000116# By default, failfast is False. Use '-F' to overwrite it.
117failfast = False
118
Johnny Chenc5fa0052011-07-29 22:54:56 +0000119# The filters (testclass.testmethod) used to admit tests into our test suite.
120filters = []
Johnny Chenb62436b2010-10-06 20:40:56 +0000121
Johnny Chen38f823c2011-10-11 01:30:27 +0000122# The runhooks is a list of lldb commands specifically for the debugger.
123# Use '-k' to specify a runhook.
124runHooks = []
125
Johnny Chena224cd12010-11-08 01:21:03 +0000126# If '-g' is specified, the filterspec is not exclusive. If a test module does
127# not contain testclass.testmethod which matches the filterspec, the whole test
128# module is still admitted into our test suite. fs4all flag defaults to True.
129fs4all = True
Johnny Chenb62436b2010-10-06 20:40:56 +0000130
Johnny Chenaf149a02010-09-16 17:11:30 +0000131# Ignore the build search path relative to this script to locate the lldb.py module.
132ignore = False
133
Johnny Chen028d8eb2011-11-17 19:57:27 +0000134# By default, we do not skip build and cleanup. Use '-S' option to override.
135skip_build_and_cleanup = False
136
Johnny Chen548aefd2010-10-11 22:25:46 +0000137# By default, we skip long running test case. Use '-l' option to override.
Johnny Chen028d8eb2011-11-17 19:57:27 +0000138skip_long_running_test = True
Johnny Chen41998192010-10-01 22:59:49 +0000139
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000140# By default, we print the build dir, lldb version, and svn info. Use '-n' option to
141# turn it off.
142noHeaders = False
143
Johnny Chen7c52ff12010-09-27 23:29:54 +0000144# The regular expression pattern to match against eligible filenames as our test cases.
145regexp = None
146
Johnny Chen548aefd2010-10-11 22:25:46 +0000147# By default, tests are executed in place and cleanups are performed afterwards.
148# Use '-r dir' option to relocate the tests and their intermediate files to a
149# different directory and to forgo any cleanups. The directory specified must
150# not exist yet.
151rdir = None
152
Johnny Chen125fc2b2010-10-21 16:55:35 +0000153# By default, recorded session info for errored/failed test are dumped into its
154# own file under a session directory named after the timestamp of the test suite
155# run. Use '-s session-dir-name' to specify a specific dir name.
156sdir_name = None
157
Johnny Chen63c2cba2010-10-29 22:20:36 +0000158# Set this flag if there is any session info dumped during the test run.
159sdir_has_content = False
160
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000161# svn_info stores the output from 'svn info lldb.base.dir'.
162svn_info = ''
163
Johnny Chen0f907b82012-01-31 00:38:03 +0000164# The environment variables to unset before running the test cases.
165unsets = []
166
Johnny Chen9707bb62010-06-25 21:14:08 +0000167# Default verbosity is 0.
168verbose = 0
169
Johnny Chen08967192011-11-18 00:19:29 +0000170# Set to True only if verbose is 0 and LLDB trace mode is off.
171progress_bar = False
172
Peter Collingbourne61aca482011-06-20 19:06:29 +0000173# By default, search from the script directory.
174testdirs = [ sys.path[0] ]
Johnny Chen9707bb62010-06-25 21:14:08 +0000175
Johnny Chen877c7e42010-08-07 00:16:07 +0000176# Separator string.
177separator = '-' * 70
178
Johnny Chen9707bb62010-06-25 21:14:08 +0000179
180def usage():
181 print """
182Usage: dotest.py [option] [args]
183where options:
Jim Ingham4f347cb2011-04-13 21:11:41 +0000184-h : print this help message and exit. Add '-v' for more detailed help.
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000185-A : specify the architecture(s) to launch for the inferior process
186 -A i386 => launch inferior with i386 architecture
187 -A x86_64^i386 => launch inferior with x86_64 and i386 architectures
188-C : specify the compiler(s) used to build the inferior executable
189 -C clang => build debuggee using clang compiler
Johnny Chence9cf4e2012-01-17 01:26:06 +0000190 -C /my/full/path/to/clang => specify a full path to the clang binary
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000191 -C clang^gcc => build debuggee using clang and gcc compilers
Johnny Chen50bc6382011-01-29 01:16:52 +0000192-D : dump the Python sys.path variable
Johnny Chen4f93bf12010-12-10 00:51:23 +0000193-a : don't do lldb Python API tests
194 use @python_api_test to decorate a test case as lldb Python API test
Johnny Chen3ebdacc2010-12-10 18:52:10 +0000195+a : just do lldb Python API tests
Johnny Chencc659ad2010-12-10 19:02:23 +0000196 do not specify both '-a' and '+a' at the same time
Johnny Chen82ccf402011-07-30 01:39:58 +0000197+b : just do benchmark tests
198 use @benchmark_test to decorate a test case as such
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000199-b : read a blacklist file specified after this option
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000200-c : read a config file specified after this option
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000201 the architectures and compilers (note the plurals) specified via '-A' and '-C'
202 will override those specified via a config file
Johnny Chenb40056b2010-09-21 00:09:27 +0000203 (see also lldb-trunk/example/test/usage-config)
Johnny Chen91960d32010-09-08 20:56:16 +0000204-d : delay startup for 10 seconds (in order for the debugger to attach)
Johnny Chene00c9302011-10-10 22:03:44 +0000205-e : specify the full path of an executable used for benchmark purpose;
206 see also '-x', which provides the breakpoint sepcification
Johnny Chen7d6d8442010-12-03 19:59:35 +0000207-F : failfast, stop the test suite on the first error/failure
Johnny Chen46be75d2010-10-11 16:19:48 +0000208-f : specify a filter, which consists of the test class name, a dot, followed by
Johnny Chen1a6e92a2010-11-08 20:17:04 +0000209 the test method, to only admit such test into the test suite
Johnny Chenb62436b2010-10-06 20:40:56 +0000210 e.g., -f 'ClassTypesTestCase.test_with_dwarf_and_python_api'
Johnny Chena224cd12010-11-08 01:21:03 +0000211-g : if specified, the filterspec by -f is not exclusive, i.e., if a test module
212 does not match the filterspec (testclass.testmethod), the whole module is
213 still admitted to the test suite
Johnny Chenaf149a02010-09-16 17:11:30 +0000214-i : ignore (don't bailout) if 'lldb.py' module cannot be located in the build
215 tree relative to this script; use PYTHONPATH to locate the module
Johnny Chen38f823c2011-10-11 01:30:27 +0000216-k : specify a runhook, which is an lldb command to be executed by the debugger;
217 '-k' option can occur multiple times, the commands are executed one after the
218 other to bring the debugger to a desired state, so that, for example, further
219 benchmarking can be done
Johnny Chen41998192010-10-01 22:59:49 +0000220-l : don't skip long running test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000221-n : don't print the headers like build dir, lldb version, and svn info at all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000222-p : specify a regexp filename pattern for inclusion in the test suite
Johnny Chen548aefd2010-10-11 22:25:46 +0000223-r : specify a dir to relocate the tests and their intermediate files to;
224 the directory must not exist before running this test driver;
225 no cleanup of intermediate test files is performed in this case
Johnny Chen028d8eb2011-11-17 19:57:27 +0000226-S : skip the build and cleanup while running the test
227 use this option with care as you would need to build the inferior(s) by hand
228 and build the executable(s) with the correct name(s)
229 this can be used with '-# n' to stress test certain test cases for n number of
230 times
Johnny Chen125fc2b2010-10-21 16:55:35 +0000231-s : specify the name of the dir created to store the session files of tests
232 with errored or failed status; if not specified, the test driver uses the
233 timestamp as the session dir name
Johnny Chena2486f22011-04-21 20:48:32 +0000234-t : turn on tracing of lldb command and other detailed test executions
Johnny Chen0f907b82012-01-31 00:38:03 +0000235-u : specify an environment variable to unset before running the test cases
236 e.g., -u DYLD_INSERT_LIBRARIES -u MallocScribble'
Johnny Chena2486f22011-04-21 20:48:32 +0000237-v : do verbose mode of unittest framework (print out each test case invocation)
Johnny Chene9eae812012-01-18 05:15:00 +0000238-X : exclude a directory from consideration for test discovery
239 -X types => if 'types' appear in the pathname components of a potential testfile
240 it will be ignored
Johnny Chene00c9302011-10-10 22:03:44 +0000241-x : specify the breakpoint specification for the benchmark executable;
242 see also '-e', which provides the full path of the executable
Johnny Chen5f2ed172011-10-20 18:43:28 +0000243-y : specify the iteration count used to collect our benchmarks; an example is
244 the number of times to do 'thread step-over' to measure stepping speed
245 see also '-e' and '-x' options
Johnny Chene47649c2010-10-07 02:04:14 +0000246-w : insert some wait time (currently 0.5 sec) between consecutive test cases
Johnny Chend2acdb32010-11-16 22:42:58 +0000247-# : Repeat the test suite for a specified number of times
Johnny Chen9707bb62010-06-25 21:14:08 +0000248
249and:
Johnny Chen9656ab22010-10-22 19:00:18 +0000250args : specify a list of directory names to search for test modules named after
251 Test*.py (test discovery)
Peter Collingbourne5f2b5d62011-06-14 03:55:45 +0000252 if empty, search from the current working directory, instead
Jim Ingham4f347cb2011-04-13 21:11:41 +0000253"""
Johnny Chen58f93922010-06-29 23:10:39 +0000254
Jim Ingham4f347cb2011-04-13 21:11:41 +0000255 if verbose > 0:
256 print """
Johnny Chen9656ab22010-10-22 19:00:18 +0000257Examples:
258
Johnny Chena224cd12010-11-08 01:21:03 +0000259This is an example of using the -f option to pinpoint to a specfic test class
260and test method to be run:
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000261
Johnny Chena224cd12010-11-08 01:21:03 +0000262$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000263----------------------------------------------------------------------
264Collected 1 test
265
266test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
267Test 'frame variable this' when stopped on a class constructor. ... ok
268
269----------------------------------------------------------------------
270Ran 1 test in 1.396s
271
272OK
Johnny Chen9656ab22010-10-22 19:00:18 +0000273
274And this is an example of using the -p option to run a single file (the filename
275matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
276
277$ ./dotest.py -v -p ObjC
278----------------------------------------------------------------------
279Collected 4 tests
280
281test_break_with_dsym (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000282Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000283test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000284Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000285test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
286Lookup objective-c data types and evaluate expressions. ... ok
287test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
288Lookup objective-c data types and evaluate expressions. ... ok
289
290----------------------------------------------------------------------
291Ran 4 tests in 16.661s
292
293OK
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000294
Johnny Chen58f93922010-06-29 23:10:39 +0000295Running of this script also sets up the LLDB_TEST environment variable so that
Johnny Chenaf149a02010-09-16 17:11:30 +0000296individual test cases can locate their supporting files correctly. The script
297tries to set up Python's search paths for modules by looking at the build tree
Johnny Chena85859f2010-11-11 22:14:56 +0000298relative to this script. See also the '-i' option in the following example.
299
300Finally, this is an example of using the lldb.py module distributed/installed by
301Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
302option to add some delay between two tests. It uses ARCH=x86_64 to specify that
303as the architecture and CC=clang to specify the compiler used for the test run:
304
305$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
306
307Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
308----------------------------------------------------------------------
309Collected 2 tests
310
311test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
312Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
313test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
314Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
315
316----------------------------------------------------------------------
317Ran 2 tests in 5.659s
318
319OK
320
321The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
322notify the directory containing the session logs for test failures or errors.
323In case there is any test failure/error, a similar message is appended at the
324end of the stderr output for your convenience.
Johnny Chenfde69bc2010-09-14 22:01:40 +0000325
326Environment variables related to loggings:
327
328o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
329 with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
330
331o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
332 'process.gdb-remote' subsystem with a default option of 'packets' if
333 GDB_REMOTE_LOG_OPTION is not defined.
Johnny Chen9707bb62010-06-25 21:14:08 +0000334"""
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000335 sys.exit(0)
Johnny Chen9707bb62010-06-25 21:14:08 +0000336
337
Johnny Chenaf149a02010-09-16 17:11:30 +0000338def parseOptionsAndInitTestdirs():
339 """Initialize the list of directories containing our unittest scripts.
340
341 '-h/--help as the first option prints out usage info and exit the program.
342 """
343
Johnny Chen4f93bf12010-12-10 00:51:23 +0000344 global dont_do_python_api_test
345 global just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000346 global just_do_benchmarks_test
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000347 global blacklist
348 global blacklistConfig
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000349 global configFile
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000350 global archs
351 global compilers
Johnny Chend2acdb32010-11-16 22:42:58 +0000352 global count
Johnny Chenaf149a02010-09-16 17:11:30 +0000353 global delay
Johnny Chen50bc6382011-01-29 01:16:52 +0000354 global dumpSysPath
Johnny Chene00c9302011-10-10 22:03:44 +0000355 global bmExecutable
356 global bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000357 global bmIterationCount
Johnny Chen7d6d8442010-12-03 19:59:35 +0000358 global failfast
Johnny Chenc5fa0052011-07-29 22:54:56 +0000359 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000360 global fs4all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000361 global ignore
Johnny Chen08967192011-11-18 00:19:29 +0000362 global progress_bar
Johnny Chen38f823c2011-10-11 01:30:27 +0000363 global runHooks
Johnny Chen028d8eb2011-11-17 19:57:27 +0000364 global skip_build_and_cleanup
365 global skip_long_running_test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000366 global noHeaders
Johnny Chen7c52ff12010-09-27 23:29:54 +0000367 global regexp
Johnny Chen548aefd2010-10-11 22:25:46 +0000368 global rdir
Johnny Chen125fc2b2010-10-21 16:55:35 +0000369 global sdir_name
Johnny Chen0f907b82012-01-31 00:38:03 +0000370 global unsets
Johnny Chenaf149a02010-09-16 17:11:30 +0000371 global verbose
372 global testdirs
373
Jim Ingham4f347cb2011-04-13 21:11:41 +0000374 do_help = False
375
Johnny Chenaf149a02010-09-16 17:11:30 +0000376 if len(sys.argv) == 1:
377 return
378
379 # Process possible trace and/or verbose flag, among other things.
380 index = 1
Johnny Chence2212c2010-10-07 15:41:55 +0000381 while index < len(sys.argv):
Johnny Chen4f93bf12010-12-10 00:51:23 +0000382 if sys.argv[index].startswith('-') or sys.argv[index].startswith('+'):
383 # We should continue processing...
384 pass
385 else:
Johnny Chenaf149a02010-09-16 17:11:30 +0000386 # End of option processing.
387 break
388
389 if sys.argv[index].find('-h') != -1:
Jim Ingham4f347cb2011-04-13 21:11:41 +0000390 index += 1
391 do_help = True
Johnny Chen012cba12011-01-26 19:07:42 +0000392 elif sys.argv[index].startswith('-A'):
393 # Increment by 1 to fetch the ARCH spec.
394 index += 1
395 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
396 usage()
Johnny Cheneee9b862011-04-26 20:45:00 +0000397 archs = sys.argv[index].split('^')
Johnny Chen012cba12011-01-26 19:07:42 +0000398 index += 1
399 elif sys.argv[index].startswith('-C'):
400 # Increment by 1 to fetch the CC spec.
401 index += 1
402 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
403 usage()
Johnny Cheneee9b862011-04-26 20:45:00 +0000404 compilers = sys.argv[index].split('^')
Johnny Chen012cba12011-01-26 19:07:42 +0000405 index += 1
Johnny Chen50bc6382011-01-29 01:16:52 +0000406 elif sys.argv[index].startswith('-D'):
407 dumpSysPath = True
408 index += 1
Johnny Chen4f93bf12010-12-10 00:51:23 +0000409 elif sys.argv[index].startswith('-a'):
410 dont_do_python_api_test = True
411 index += 1
412 elif sys.argv[index].startswith('+a'):
413 just_do_python_api_test = True
414 index += 1
Johnny Chen82ccf402011-07-30 01:39:58 +0000415 elif sys.argv[index].startswith('+b'):
416 just_do_benchmarks_test = True
417 index += 1
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000418 elif sys.argv[index].startswith('-b'):
419 # Increment by 1 to fetch the blacklist file name option argument.
420 index += 1
421 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
422 usage()
423 blacklistFile = sys.argv[index]
424 if not os.path.isfile(blacklistFile):
425 print "Blacklist file:", blacklistFile, "does not exist!"
426 usage()
427 index += 1
428 # Now read the blacklist contents and assign it to blacklist.
429 execfile(blacklistFile, globals(), blacklistConfig)
430 blacklist = blacklistConfig.get('blacklist')
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000431 elif sys.argv[index].startswith('-c'):
432 # Increment by 1 to fetch the config file name option argument.
433 index += 1
434 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
435 usage()
436 configFile = sys.argv[index]
437 if not os.path.isfile(configFile):
438 print "Config file:", configFile, "does not exist!"
439 usage()
440 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000441 elif sys.argv[index].startswith('-d'):
442 delay = True
443 index += 1
Johnny Chene00c9302011-10-10 22:03:44 +0000444 elif sys.argv[index].startswith('-e'):
445 # Increment by 1 to fetch the full path of the benchmark executable.
446 index += 1
447 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
448 usage()
449 bmExecutable = sys.argv[index]
450 if not is_exe(bmExecutable):
451 usage()
452 index += 1
Johnny Chen7d6d8442010-12-03 19:59:35 +0000453 elif sys.argv[index].startswith('-F'):
454 failfast = True
455 index += 1
Johnny Chenb62436b2010-10-06 20:40:56 +0000456 elif sys.argv[index].startswith('-f'):
457 # Increment by 1 to fetch the filter spec.
458 index += 1
459 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
460 usage()
Johnny Chenc5fa0052011-07-29 22:54:56 +0000461 filters.append(sys.argv[index])
Johnny Chenb62436b2010-10-06 20:40:56 +0000462 index += 1
463 elif sys.argv[index].startswith('-g'):
Johnny Chena224cd12010-11-08 01:21:03 +0000464 fs4all = False
Johnny Chenb62436b2010-10-06 20:40:56 +0000465 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000466 elif sys.argv[index].startswith('-i'):
467 ignore = True
468 index += 1
Johnny Chen38f823c2011-10-11 01:30:27 +0000469 elif sys.argv[index].startswith('-k'):
470 # Increment by 1 to fetch the runhook lldb command.
471 index += 1
472 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
473 usage()
474 runHooks.append(sys.argv[index])
475 index += 1
Johnny Chen41998192010-10-01 22:59:49 +0000476 elif sys.argv[index].startswith('-l'):
Johnny Chen028d8eb2011-11-17 19:57:27 +0000477 skip_long_running_test = False
Johnny Chen41998192010-10-01 22:59:49 +0000478 index += 1
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000479 elif sys.argv[index].startswith('-n'):
480 noHeaders = True
481 index += 1
Johnny Chen7c52ff12010-09-27 23:29:54 +0000482 elif sys.argv[index].startswith('-p'):
483 # Increment by 1 to fetch the reg exp pattern argument.
484 index += 1
485 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
486 usage()
487 regexp = sys.argv[index]
488 index += 1
Johnny Chen548aefd2010-10-11 22:25:46 +0000489 elif sys.argv[index].startswith('-r'):
490 # Increment by 1 to fetch the relocated directory argument.
491 index += 1
492 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
493 usage()
494 rdir = os.path.abspath(sys.argv[index])
495 if os.path.exists(rdir):
496 print "Relocated directory:", rdir, "must not exist!"
497 usage()
498 index += 1
Johnny Chen028d8eb2011-11-17 19:57:27 +0000499 elif sys.argv[index].startswith('-S'):
500 skip_build_and_cleanup = True
501 index += 1
Johnny Chen125fc2b2010-10-21 16:55:35 +0000502 elif sys.argv[index].startswith('-s'):
503 # Increment by 1 to fetch the session dir name.
504 index += 1
505 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
506 usage()
507 sdir_name = sys.argv[index]
508 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000509 elif sys.argv[index].startswith('-t'):
510 os.environ["LLDB_COMMAND_TRACE"] = "YES"
511 index += 1
Johnny Chen0f907b82012-01-31 00:38:03 +0000512 elif sys.argv[index].startswith('-u'):
513 # Increment by 1 to fetch the environment variable to unset.
514 index += 1
515 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
516 usage()
517 unsets.append(sys.argv[index])
518 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000519 elif sys.argv[index].startswith('-v'):
520 verbose = 2
521 index += 1
Johnny Chene47649c2010-10-07 02:04:14 +0000522 elif sys.argv[index].startswith('-w'):
523 os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] = 'YES'
524 index += 1
Johnny Chene9eae812012-01-18 05:15:00 +0000525 elif sys.argv[index].startswith('-X'):
526 # Increment by 1 to fetch an excluded directory.
527 index += 1
528 if index >= len(sys.argv):
529 usage()
530 excluded.add(sys.argv[index])
531 index += 1
Johnny Chene00c9302011-10-10 22:03:44 +0000532 elif sys.argv[index].startswith('-x'):
533 # Increment by 1 to fetch the breakpoint specification of the benchmark executable.
534 index += 1
Johnny Chen8a1b1222011-10-20 22:16:24 +0000535 if index >= len(sys.argv):
Johnny Chene00c9302011-10-10 22:03:44 +0000536 usage()
537 bmBreakpointSpec = sys.argv[index]
538 index += 1
Johnny Chen5f2ed172011-10-20 18:43:28 +0000539 elif sys.argv[index].startswith('-y'):
540 # Increment by 1 to fetch the the benchmark iteration count.
541 index += 1
542 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
543 usage()
544 bmIterationCount = int(sys.argv[index])
545 index += 1
Johnny Chend2acdb32010-11-16 22:42:58 +0000546 elif sys.argv[index].startswith('-#'):
547 # Increment by 1 to fetch the repeat count argument.
548 index += 1
549 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
550 usage()
551 count = int(sys.argv[index])
552 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000553 else:
554 print "Unknown option: ", sys.argv[index]
555 usage()
Johnny Chenaf149a02010-09-16 17:11:30 +0000556
Jim Ingham4f347cb2011-04-13 21:11:41 +0000557 if do_help == True:
558 usage()
559
Johnny Chencc659ad2010-12-10 19:02:23 +0000560 # Do not specify both '-a' and '+a' at the same time.
561 if dont_do_python_api_test and just_do_python_api_test:
562 usage()
563
Johnny Chen08967192011-11-18 00:19:29 +0000564 # The simple progress bar is turned on only if verbose == 0 and LLDB_COMMAND_TRACE is not 'YES'
565 if ("LLDB_COMMAND_TRACE" not in os.environ or os.environ["LLDB_COMMAND_TRACE"]!="YES") and verbose==0:
566 progress_bar = True
567
Johnny Chenaf149a02010-09-16 17:11:30 +0000568 # Gather all the dirs passed on the command line.
569 if len(sys.argv) > index:
570 testdirs = map(os.path.abspath, sys.argv[index:])
571
Johnny Chen548aefd2010-10-11 22:25:46 +0000572 # If '-r dir' is specified, the tests should be run under the relocated
573 # directory. Let's copy the testdirs over.
574 if rdir:
575 from shutil import copytree, ignore_patterns
576
577 tmpdirs = []
578 for srcdir in testdirs:
579 dstdir = os.path.join(rdir, os.path.basename(srcdir))
580 # Don't copy the *.pyc and .svn stuffs.
581 copytree(srcdir, dstdir, ignore=ignore_patterns('*.pyc', '.svn'))
582 tmpdirs.append(dstdir)
583
584 # This will be our modified testdirs.
585 testdirs = tmpdirs
586
587 # With '-r dir' specified, there's no cleanup of intermediate test files.
588 os.environ["LLDB_DO_CLEANUP"] = 'NO'
589
590 # If testdirs is ['test'], the make directory has already been copied
591 # recursively and is contained within the rdir/test dir. For anything
592 # else, we would need to copy over the make directory and its contents,
593 # so that, os.listdir(rdir) looks like, for example:
594 #
595 # array_types conditional_break make
596 #
597 # where the make directory contains the Makefile.rules file.
598 if len(testdirs) != 1 or os.path.basename(testdirs[0]) != 'test':
599 # Don't copy the .svn stuffs.
600 copytree('make', os.path.join(rdir, 'make'),
601 ignore=ignore_patterns('.svn'))
602
603 #print "testdirs:", testdirs
604
Johnny Chenb40056b2010-09-21 00:09:27 +0000605 # Source the configFile if specified.
606 # The side effect, if any, will be felt from this point on. An example
607 # config file may be these simple two lines:
608 #
609 # sys.stderr = open("/tmp/lldbtest-stderr", "w")
610 # sys.stdout = open("/tmp/lldbtest-stdout", "w")
611 #
612 # which will reassign the two file objects to sys.stderr and sys.stdout,
613 # respectively.
614 #
615 # See also lldb-trunk/example/test/usage-config.
616 global config
617 if configFile:
618 # Pass config (a dictionary) as the locals namespace for side-effect.
619 execfile(configFile, globals(), config)
620 #print "config:", config
621 #print "sys.stderr:", sys.stderr
622 #print "sys.stdout:", sys.stdout
623
Johnny Chenaf149a02010-09-16 17:11:30 +0000624
Johnny Chen9707bb62010-06-25 21:14:08 +0000625def setupSysPath():
Johnny Chen8a3c0432011-03-11 20:13:06 +0000626 """
627 Add LLDB.framework/Resources/Python to the search paths for modules.
628 As a side effect, we also discover the 'lldb' executable and export it here.
629 """
Johnny Chen9707bb62010-06-25 21:14:08 +0000630
Johnny Chen548aefd2010-10-11 22:25:46 +0000631 global rdir
632 global testdirs
Johnny Chen50bc6382011-01-29 01:16:52 +0000633 global dumpSysPath
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000634 global noHeaders
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000635 global svn_info
Johnny Chen548aefd2010-10-11 22:25:46 +0000636
Johnny Chen9707bb62010-06-25 21:14:08 +0000637 # Get the directory containing the current script.
Johnny Chen4d162e52011-08-12 18:54:11 +0000638 if ("DOTEST_PROFILE" in os.environ or "DOTEST_PDB" in os.environ) and "DOTEST_SCRIPT_DIR" in os.environ:
Johnny Chen0de6ab52011-01-19 02:10:40 +0000639 scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
640 else:
641 scriptPath = sys.path[0]
Johnny Chena1affab2010-07-03 03:41:59 +0000642 if not scriptPath.endswith('test'):
Johnny Chen9707bb62010-06-25 21:14:08 +0000643 print "This script expects to reside in lldb's test directory."
644 sys.exit(-1)
645
Johnny Chen548aefd2010-10-11 22:25:46 +0000646 if rdir:
647 # Set up the LLDB_TEST environment variable appropriately, so that the
648 # individual tests can be located relatively.
649 #
650 # See also lldbtest.TestBase.setUpClass(cls).
651 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
652 os.environ["LLDB_TEST"] = os.path.join(rdir, 'test')
653 else:
654 os.environ["LLDB_TEST"] = rdir
655 else:
656 os.environ["LLDB_TEST"] = scriptPath
Peter Collingbournef6c3de82011-06-20 19:06:45 +0000657
658 # Set up the LLDB_SRC environment variable, so that the tests can locate
659 # the LLDB source code.
660 os.environ["LLDB_SRC"] = os.path.join(sys.path[0], os.pardir)
661
Johnny Chen9de4ede2010-08-31 17:42:54 +0000662 pluginPath = os.path.join(scriptPath, 'plugins')
Johnny Chen8a3c0432011-03-11 20:13:06 +0000663 pexpectPath = os.path.join(scriptPath, 'pexpect-2.4')
Johnny Chen58f93922010-06-29 23:10:39 +0000664
Johnny Chen8a3c0432011-03-11 20:13:06 +0000665 # Append script dir, plugin dir, and pexpect dir to the sys.path.
Johnny Chenaf149a02010-09-16 17:11:30 +0000666 sys.path.append(scriptPath)
667 sys.path.append(pluginPath)
Johnny Chen8a3c0432011-03-11 20:13:06 +0000668 sys.path.append(pexpectPath)
Johnny Chenaf149a02010-09-16 17:11:30 +0000669
Johnny Chen26901c82011-03-11 19:47:23 +0000670 # This is our base name component.
Johnny Chena1affab2010-07-03 03:41:59 +0000671 base = os.path.abspath(os.path.join(scriptPath, os.pardir))
Johnny Chen6a564a42011-02-15 18:50:19 +0000672
Johnny Chen26901c82011-03-11 19:47:23 +0000673 # These are for xcode build directories.
Johnny Chen6a564a42011-02-15 18:50:19 +0000674 xcode3_build_dir = ['build']
675 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
676 dbg = ['Debug']
677 rel = ['Release']
678 bai = ['BuildAndIntegration']
679 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
Johnny Chen26901c82011-03-11 19:47:23 +0000680
681 # Some of the tests can invoke the 'lldb' command directly.
682 # We'll try to locate the appropriate executable right here.
683
Johnny Chen6033bed2011-08-26 00:00:01 +0000684 # First, you can define an environment variable LLDB_EXEC specifying the
685 # full pathname of the lldb executable.
686 if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
687 lldbExec = os.environ["LLDB_EXEC"]
688 else:
689 lldbExec = None
690
Johnny Chen26901c82011-03-11 19:47:23 +0000691 executable = ['lldb']
692 dbgExec = os.path.join(base, *(xcode3_build_dir + dbg + executable))
693 dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
694 relExec = os.path.join(base, *(xcode3_build_dir + rel + executable))
695 relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
696 baiExec = os.path.join(base, *(xcode3_build_dir + bai + executable))
697 baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
698
Johnny Chen6033bed2011-08-26 00:00:01 +0000699 # The 'lldb' executable built here in the source tree.
700 lldbHere = None
Johnny Chen26901c82011-03-11 19:47:23 +0000701 if is_exe(dbgExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000702 lldbHere = dbgExec
Johnny Chen26901c82011-03-11 19:47:23 +0000703 elif is_exe(dbgExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000704 lldbHere = dbgExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000705 elif is_exe(relExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000706 lldbHere = relExec
Johnny Chen26901c82011-03-11 19:47:23 +0000707 elif is_exe(relExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000708 lldbHere = relExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000709 elif is_exe(baiExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000710 lldbHere = baiExec
Johnny Chen26901c82011-03-11 19:47:23 +0000711 elif is_exe(baiExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000712 lldbHere = baiExec2
Daniel Dunbar2bd310c2011-10-31 23:27:06 +0000713 elif lldbExec:
714 lldbHere = lldbExec
Johnny Chen26901c82011-03-11 19:47:23 +0000715
Johnny Chen6033bed2011-08-26 00:00:01 +0000716 if lldbHere:
717 os.environ["LLDB_HERE"] = lldbHere
Johnny Chen0409d992011-10-25 20:08:03 +0000718 os.environ["LLDB_BUILD_DIR"] = os.path.split(lldbHere)[0]
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000719 if not noHeaders:
720 print "LLDB build dir:", os.environ["LLDB_BUILD_DIR"]
Johnny Chen91da0052011-10-28 17:56:02 +0000721 os.system('%s -v' % lldbHere)
Johnny Chen62d527e2011-08-04 18:17:16 +0000722
Johnny Chen6033bed2011-08-26 00:00:01 +0000723 # One last chance to locate the 'lldb' executable.
Johnny Chen26901c82011-03-11 19:47:23 +0000724 if not lldbExec:
Johnny Chen0409d992011-10-25 20:08:03 +0000725 lldbExec = which('lldb')
726 if lldbHere and not lldbExec:
Johnny Chen6033bed2011-08-26 00:00:01 +0000727 lldbExec = lldbHere
Johnny Chen0409d992011-10-25 20:08:03 +0000728
Johnny Chen26901c82011-03-11 19:47:23 +0000729
730 if not lldbExec:
731 print "The 'lldb' executable cannot be located. Some of the tests may not be run as a result."
732 else:
733 os.environ["LLDB_EXEC"] = lldbExec
Johnny Chen8904eb02011-10-28 00:59:00 +0000734 #print "The 'lldb' from PATH env variable", lldbExec
Johnny Chend7931462011-03-17 00:38:22 +0000735
Johnny Chenb264c9b2011-06-24 22:52:05 +0000736 if os.path.isdir(os.path.join(base, '.svn')):
737 pipe = subprocess.Popen(["svn", "info", base], stdout = subprocess.PIPE)
738 svn_info = pipe.stdout.read()
739 elif os.path.isdir(os.path.join(base, '.git')):
740 pipe = subprocess.Popen(["git", "svn", "info", base], stdout = subprocess.PIPE)
741 svn_info = pipe.stdout.read()
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000742 if not noHeaders:
743 print svn_info
Johnny Chen26901c82011-03-11 19:47:23 +0000744
745 global ignore
746
747 # The '-i' option is used to skip looking for lldb.py in the build tree.
748 if ignore:
749 return
750
Johnny Chen6a564a42011-02-15 18:50:19 +0000751 dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
752 dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
753 relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
754 relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
755 baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
756 baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
Johnny Chen9707bb62010-06-25 21:14:08 +0000757
758 lldbPath = None
759 if os.path.isfile(os.path.join(dbgPath, 'lldb.py')):
760 lldbPath = dbgPath
Greg Claytond9846b02011-02-14 21:17:06 +0000761 elif os.path.isfile(os.path.join(dbgPath2, 'lldb.py')):
762 lldbPath = dbgPath2
Johnny Chen9707bb62010-06-25 21:14:08 +0000763 elif os.path.isfile(os.path.join(relPath, 'lldb.py')):
764 lldbPath = relPath
Greg Claytond9846b02011-02-14 21:17:06 +0000765 elif os.path.isfile(os.path.join(relPath2, 'lldb.py')):
766 lldbPath = relPath2
Johnny Chenc202c462010-09-15 18:11:19 +0000767 elif os.path.isfile(os.path.join(baiPath, 'lldb.py')):
768 lldbPath = baiPath
Greg Claytond9846b02011-02-14 21:17:06 +0000769 elif os.path.isfile(os.path.join(baiPath2, 'lldb.py')):
770 lldbPath = baiPath2
Johnny Chen9707bb62010-06-25 21:14:08 +0000771
772 if not lldbPath:
Johnny Chenc202c462010-09-15 18:11:19 +0000773 print 'This script requires lldb.py to be in either ' + dbgPath + ',',
774 print relPath + ', or ' + baiPath
Johnny Chen9707bb62010-06-25 21:14:08 +0000775 sys.exit(-1)
776
Johnny Chenaf149a02010-09-16 17:11:30 +0000777 # This is to locate the lldb.py module. Insert it right after sys.path[0].
778 sys.path[1:1] = [lldbPath]
Johnny Chen50bc6382011-01-29 01:16:52 +0000779 if dumpSysPath:
780 print "sys.path:", sys.path
Johnny Chen9707bb62010-06-25 21:14:08 +0000781
Johnny Chen9707bb62010-06-25 21:14:08 +0000782
Johnny Chencd0279d2010-09-20 18:07:50 +0000783def doDelay(delta):
784 """Delaying startup for delta-seconds to facilitate debugger attachment."""
785 def alarm_handler(*args):
786 raise Exception("timeout")
787
788 signal.signal(signal.SIGALRM, alarm_handler)
789 signal.alarm(delta)
790 sys.stdout.write("pid=%d\n" % os.getpid())
791 sys.stdout.write("Enter RET to proceed (or timeout after %d seconds):" %
792 delta)
793 sys.stdout.flush()
794 try:
795 text = sys.stdin.readline()
796 except:
797 text = ""
798 signal.alarm(0)
799 sys.stdout.write("proceeding...\n")
800 pass
801
802
Johnny Chen9707bb62010-06-25 21:14:08 +0000803def visit(prefix, dir, names):
804 """Visitor function for os.path.walk(path, visit, arg)."""
805
806 global suite
Johnny Chen7c52ff12010-09-27 23:29:54 +0000807 global regexp
Johnny Chenc5fa0052011-07-29 22:54:56 +0000808 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000809 global fs4all
Johnny Chene9eae812012-01-18 05:15:00 +0000810 global excluded
811
812 if set(dir.split(os.sep)).intersection(excluded):
813 #print "Detected an excluded dir component: %s" % dir
814 return
Johnny Chen9707bb62010-06-25 21:14:08 +0000815
816 for name in names:
817 if os.path.isdir(os.path.join(dir, name)):
818 continue
819
820 if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
Johnny Chen7c52ff12010-09-27 23:29:54 +0000821 # Try to match the regexp pattern, if specified.
822 if regexp:
823 import re
824 if re.search(regexp, name):
825 #print "Filename: '%s' matches pattern: '%s'" % (name, regexp)
826 pass
827 else:
828 #print "Filename: '%s' does not match pattern: '%s'" % (name, regexp)
829 continue
830
Johnny Chen953864a2010-10-12 21:35:54 +0000831 # We found a match for our test. Add it to the suite.
Johnny Chen79723352010-10-12 15:53:22 +0000832
833 # Update the sys.path first.
Johnny Chena85d7ee2010-06-26 00:19:32 +0000834 if not sys.path.count(dir):
Johnny Chen548aefd2010-10-11 22:25:46 +0000835 sys.path.insert(0, dir)
Johnny Chen9707bb62010-06-25 21:14:08 +0000836 base = os.path.splitext(name)[0]
Johnny Chenb62436b2010-10-06 20:40:56 +0000837
838 # Thoroughly check the filterspec against the base module and admit
839 # the (base, filterspec) combination only when it makes sense.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000840 filterspec = None
841 for filterspec in filters:
Johnny Chenb62436b2010-10-06 20:40:56 +0000842 # Optimistically set the flag to True.
843 filtered = True
844 module = __import__(base)
845 parts = filterspec.split('.')
846 obj = module
847 for part in parts:
848 try:
849 parent, obj = obj, getattr(obj, part)
850 except AttributeError:
851 # The filterspec has failed.
852 filtered = False
853 break
Johnny Chenc5fa0052011-07-29 22:54:56 +0000854
Johnny Chendb4be602011-08-12 23:55:07 +0000855 # If filtered, we have a good filterspec. Add it.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000856 if filtered:
Johnny Chendb4be602011-08-12 23:55:07 +0000857 #print "adding filter spec %s to module %s" % (filterspec, module)
858 suite.addTests(
859 unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
860 continue
Johnny Chenc5fa0052011-07-29 22:54:56 +0000861
862 # Forgo this module if the (base, filterspec) combo is invalid
863 # and no '-g' option is specified
864 if filters and fs4all and not filtered:
865 continue
Johnny Chenb62436b2010-10-06 20:40:56 +0000866
Johnny Chendb4be602011-08-12 23:55:07 +0000867 # Add either the filtered test case(s) (which is done before) or the entire test class.
868 if not filterspec or not filtered:
Johnny Chenb62436b2010-10-06 20:40:56 +0000869 # A simple case of just the module name. Also the failover case
870 # from the filterspec branch when the (base, filterspec) combo
871 # doesn't make sense.
872 suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
Johnny Chen9707bb62010-06-25 21:14:08 +0000873
874
Johnny Chencd0279d2010-09-20 18:07:50 +0000875def lldbLoggings():
876 """Check and do lldb loggings if necessary."""
877
878 # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
879 # defined. Use ${LLDB_LOG} to specify the log file.
880 ci = lldb.DBG.GetCommandInterpreter()
881 res = lldb.SBCommandReturnObject()
882 if ("LLDB_LOG" in os.environ):
883 if ("LLDB_LOG_OPTION" in os.environ):
884 lldb_log_option = os.environ["LLDB_LOG_OPTION"]
885 else:
Johnny Chen8fd886c2010-12-08 01:25:21 +0000886 lldb_log_option = "event process expr state api"
Johnny Chencd0279d2010-09-20 18:07:50 +0000887 ci.HandleCommand(
Greg Clayton940b1032011-02-23 00:35:02 +0000888 "log enable -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option,
Johnny Chencd0279d2010-09-20 18:07:50 +0000889 res)
890 if not res.Succeeded():
891 raise Exception('log enable failed (check LLDB_LOG env variable.')
892 # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
893 # Use ${GDB_REMOTE_LOG} to specify the log file.
894 if ("GDB_REMOTE_LOG" in os.environ):
895 if ("GDB_REMOTE_LOG_OPTION" in os.environ):
896 gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
897 else:
Johnny Chen7ab8c852010-12-02 18:35:13 +0000898 gdb_remote_log_option = "packets process"
Johnny Chencd0279d2010-09-20 18:07:50 +0000899 ci.HandleCommand(
Johnny Chenc935a892011-06-21 19:25:45 +0000900 "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
Johnny Chencd0279d2010-09-20 18:07:50 +0000901 + gdb_remote_log_option,
902 res)
903 if not res.Succeeded():
904 raise Exception('log enable failed (check GDB_REMOTE_LOG env variable.')
905
Johnny Chen067022b2011-01-19 19:31:46 +0000906def getMyCommandLine():
Johnny Chen067022b2011-01-19 19:31:46 +0000907 ps = subprocess.Popen(['ps', '-o', "command=CMD", str(os.getpid())], stdout=subprocess.PIPE).communicate()[0]
908 lines = ps.split('\n')
909 cmd_line = lines[1]
910 return cmd_line
Johnny Chencd0279d2010-09-20 18:07:50 +0000911
Johnny Chend96b5682010-11-05 17:30:53 +0000912# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +0000913# #
914# Execution of the test driver starts here #
915# #
Johnny Chend96b5682010-11-05 17:30:53 +0000916# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +0000917
Johnny Chen2891bb02011-09-16 01:04:26 +0000918def checkDsymForUUIDIsNotOn():
Johnny Chen6a4e0872011-09-16 17:50:44 +0000919 cmd = ["defaults", "read", "com.apple.DebugSymbols"]
920 pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
921 cmd_output = pipe.stdout.read()
Johnny Chen178c8d92011-09-16 18:03:19 +0000922 if cmd_output and "DBGFileMappedPaths = " in cmd_output:
Johnny Chen6a451482011-09-16 18:09:45 +0000923 print "%s =>" % ' '.join(cmd)
Johnny Chen6a4e0872011-09-16 17:50:44 +0000924 print cmd_output
Johnny Chen2891bb02011-09-16 01:04:26 +0000925 print "Disable automatic lookup and caching of dSYMs before running the test suite!"
926 print "Exiting..."
927 sys.exit(0)
928
929# On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
930# does not exist before proceeding to running the test suite.
931if sys.platform.startswith("darwin"):
932 checkDsymForUUIDIsNotOn()
933
Johnny Chen9707bb62010-06-25 21:14:08 +0000934#
Johnny Chenaf149a02010-09-16 17:11:30 +0000935# Start the actions by first parsing the options while setting up the test
936# directories, followed by setting up the search paths for lldb utilities;
937# then, we walk the directory trees and collect the tests into our test suite.
Johnny Chen9707bb62010-06-25 21:14:08 +0000938#
Johnny Chenaf149a02010-09-16 17:11:30 +0000939parseOptionsAndInitTestdirs()
Johnny Chen9707bb62010-06-25 21:14:08 +0000940setupSysPath()
Johnny Chen91960d32010-09-08 20:56:16 +0000941
942#
943# If '-d' is specified, do a delay of 10 seconds for the debugger to attach.
944#
945if delay:
Johnny Chencd0279d2010-09-20 18:07:50 +0000946 doDelay(10)
Johnny Chen91960d32010-09-08 20:56:16 +0000947
Johnny Chen49f2f7a2010-09-20 17:25:45 +0000948#
Johnny Chen41998192010-10-01 22:59:49 +0000949# If '-l' is specified, do not skip the long running tests.
Johnny Chen028d8eb2011-11-17 19:57:27 +0000950if not skip_long_running_test:
Johnny Chen41998192010-10-01 22:59:49 +0000951 os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
952
953#
Johnny Chen79723352010-10-12 15:53:22 +0000954# Walk through the testdirs while collecting tests.
Johnny Chen49f2f7a2010-09-20 17:25:45 +0000955#
Johnny Chen9707bb62010-06-25 21:14:08 +0000956for testdir in testdirs:
957 os.path.walk(testdir, visit, 'Test')
958
Johnny Chenb40056b2010-09-21 00:09:27 +0000959#
Johnny Chen9707bb62010-06-25 21:14:08 +0000960# Now that we have loaded all the test cases, run the whole test suite.
Johnny Chenb40056b2010-09-21 00:09:27 +0000961#
Johnny Chencd0279d2010-09-20 18:07:50 +0000962
Johnny Chen1bfbd412010-06-29 19:44:16 +0000963# For the time being, let's bracket the test runner within the
964# lldb.SBDebugger.Initialize()/Terminate() pair.
Johnny Chen01f2a6a2010-08-10 20:23:55 +0000965import lldb, atexit
Johnny Chen6b6f5ba2010-10-14 16:36:49 +0000966# Update: the act of importing lldb now executes lldb.SBDebugger.Initialize(),
967# there's no need to call it a second time.
968#lldb.SBDebugger.Initialize()
Johnny Chen01f2a6a2010-08-10 20:23:55 +0000969atexit.register(lambda: lldb.SBDebugger.Terminate())
Johnny Chen1bfbd412010-06-29 19:44:16 +0000970
Johnny Chen909e5a62010-07-01 22:52:57 +0000971# Create a singleton SBDebugger in the lldb namespace.
972lldb.DBG = lldb.SBDebugger.Create()
973
Johnny Chen4f93bf12010-12-10 00:51:23 +0000974# Put the blacklist in the lldb namespace, to be used by lldb.TestBase.
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000975lldb.blacklist = blacklist
976
Johnny Chene00c9302011-10-10 22:03:44 +0000977# Put dont/just_do_python_api_test in the lldb namespace.
Johnny Chen4f93bf12010-12-10 00:51:23 +0000978lldb.dont_do_python_api_test = dont_do_python_api_test
979lldb.just_do_python_api_test = just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000980lldb.just_do_benchmarks_test = just_do_benchmarks_test
Johnny Chen4f93bf12010-12-10 00:51:23 +0000981
Johnny Chen028d8eb2011-11-17 19:57:27 +0000982# Do we need to skip build and cleanup?
983lldb.skip_build_and_cleanup = skip_build_and_cleanup
984
Johnny Chen5f2ed172011-10-20 18:43:28 +0000985# Put bmExecutable, bmBreakpointSpec, and bmIterationCount into the lldb namespace, too.
Johnny Chene00c9302011-10-10 22:03:44 +0000986lldb.bmExecutable = bmExecutable
987lldb.bmBreakpointSpec = bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000988lldb.bmIterationCount = bmIterationCount
Johnny Chene00c9302011-10-10 22:03:44 +0000989
Johnny Chen38f823c2011-10-11 01:30:27 +0000990# And don't forget the runHooks!
991lldb.runHooks = runHooks
992
Johnny Chencd0279d2010-09-20 18:07:50 +0000993# Turn on lldb loggings if necessary.
994lldbLoggings()
Johnny Chen909e5a62010-07-01 22:52:57 +0000995
Johnny Chen7987ac92010-08-09 20:40:52 +0000996# Install the control-c handler.
997unittest2.signals.installHandler()
998
Johnny Chen125fc2b2010-10-21 16:55:35 +0000999# If sdir_name is not specified through the '-s sdir_name' option, get a
1000# timestamp string and export it as LLDB_SESSION_DIR environment var. This will
1001# be used when/if we want to dump the session info of individual test cases
1002# later on.
Johnny Chence681462010-10-19 00:25:01 +00001003#
1004# See also TestBase.dumpSessionInfo() in lldbtest.py.
Johnny Chen125fc2b2010-10-21 16:55:35 +00001005if not sdir_name:
1006 import datetime
Johnny Chen41fae812010-10-29 22:26:38 +00001007 # The windows platforms don't like ':' in the pathname.
Johnny Chen76bd0102010-10-28 16:32:13 +00001008 timestamp = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
Johnny Chen125fc2b2010-10-21 16:55:35 +00001009 sdir_name = timestamp
Peter Collingbourne132476f2011-06-20 23:55:53 +00001010os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), sdir_name)
Johnny Chen067022b2011-01-19 19:31:46 +00001011
Johnny Chenfe5f1ed2011-10-21 18:33:27 +00001012if not noHeaders:
1013 sys.stderr.write("\nSession logs for test failures/errors/unexpected successes"
1014 " will go into directory '%s'\n" % sdir_name)
1015 sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
Johnny Chence681462010-10-19 00:25:01 +00001016
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001017if not os.path.isdir(sdir_name):
1018 os.mkdir(sdir_name)
1019fname = os.path.join(sdir_name, "svn-info")
1020with open(fname, "w") as f:
1021 print >> f, svn_info
1022 print >> f, "Command invoked: %s\n" % getMyCommandLine()
1023
Johnny Chenb40056b2010-09-21 00:09:27 +00001024#
Johnny Chen0f907b82012-01-31 00:38:03 +00001025# If we have environment variables to unset, do it here before we invoke the test runner.
1026#
1027for env_var in unsets :
1028 if env_var in os.environ:
1029 # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
Johnny Chen6346a292012-01-31 00:48:02 +00001030 # is automatically translated into a corresponding call to unsetenv().
Johnny Chen0f907b82012-01-31 00:38:03 +00001031 del os.environ[env_var]
1032 #os.unsetenv(env_var)
1033
1034#
Johnny Chenb40056b2010-09-21 00:09:27 +00001035# Invoke the default TextTestRunner to run the test suite, possibly iterating
1036# over different configurations.
1037#
1038
Johnny Chenb40056b2010-09-21 00:09:27 +00001039iterArchs = False
Johnny Chenf032d902010-09-21 00:16:09 +00001040iterCompilers = False
Johnny Chenb40056b2010-09-21 00:09:27 +00001041
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001042if not archs and "archs" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001043 archs = config["archs"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001044
1045if isinstance(archs, list) and len(archs) >= 1:
1046 iterArchs = True
1047
1048if not compilers and "compilers" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001049 compilers = config["compilers"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001050
Johnny Chen92693b52012-03-09 02:11:37 +00001051#
1052# Add some intervention here to sanity check that the compilers requested are sane.
1053# If found not to be an executable program, the invalid one is dropped from the list.
1054for i in range(len(compilers)):
1055 c = compilers[i]
1056 if which(c):
1057 continue
1058 else:
1059 if sys.platform.startswith("darwin"):
1060 pipe = subprocess.Popen(['xcrun', '-find', c], stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1061 cmd_output = pipe.stdout.read()
1062 if cmd_output:
1063 if "not found" in cmd_output:
1064 print "dropping %s from the compilers used" % c
1065 compilers.remove(i)
1066 else:
1067 compilers[i] = cmd_output.split('\n')[0]
1068 print "'xcrun -find %s' returning %s" % (c, compilers[i])
1069
1070print "compilers=%s" % str(compilers)
1071
1072if not compilers or len(compilers) == 0:
1073 print "No eligible compiler found, exiting."
1074 sys.exit(1)
1075
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001076if isinstance(compilers, list) and len(compilers) >= 1:
1077 iterCompilers = True
Johnny Chenb40056b2010-09-21 00:09:27 +00001078
Johnny Chen953864a2010-10-12 21:35:54 +00001079# Make a shallow copy of sys.path, we need to manipulate the search paths later.
1080# This is only necessary if we are relocated and with different configurations.
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001081if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001082 old_sys_path = sys.path[:]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001083# If we iterate on archs or compilers, there is a chance we want to split stderr/stdout.
1084if iterArchs or iterCompilers:
Johnny Chen953864a2010-10-12 21:35:54 +00001085 old_stderr = sys.stderr
1086 old_stdout = sys.stdout
1087 new_stderr = None
1088 new_stdout = None
1089
Johnny Chend96b5682010-11-05 17:30:53 +00001090# Iterating over all possible architecture and compiler combinations.
Johnny Chenb40056b2010-09-21 00:09:27 +00001091for ia in range(len(archs) if iterArchs else 1):
1092 archConfig = ""
1093 if iterArchs:
Johnny Chen18a921f2010-09-30 17:11:58 +00001094 os.environ["ARCH"] = archs[ia]
Johnny Chenb40056b2010-09-21 00:09:27 +00001095 archConfig = "arch=%s" % archs[ia]
1096 for ic in range(len(compilers) if iterCompilers else 1):
1097 if iterCompilers:
Johnny Chen18a921f2010-09-30 17:11:58 +00001098 os.environ["CC"] = compilers[ic]
Johnny Chenb40056b2010-09-21 00:09:27 +00001099 configString = "%s compiler=%s" % (archConfig, compilers[ic])
1100 else:
1101 configString = archConfig
1102
Johnny Chenb40056b2010-09-21 00:09:27 +00001103 if iterArchs or iterCompilers:
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001104 # Translate ' ' to '-' for pathname component.
1105 from string import maketrans
1106 tbl = maketrans(' ', '-')
1107 configPostfix = configString.translate(tbl)
1108
1109 # Check whether we need to split stderr/stdout into configuration
1110 # specific files.
1111 if old_stderr.name != '<stderr>' and config.get('split_stderr'):
1112 if new_stderr:
1113 new_stderr.close()
1114 new_stderr = open("%s.%s" % (old_stderr.name, configPostfix), "w")
1115 sys.stderr = new_stderr
1116 if old_stdout.name != '<stdout>' and config.get('split_stdout'):
1117 if new_stdout:
1118 new_stdout.close()
1119 new_stdout = open("%s.%s" % (old_stdout.name, configPostfix), "w")
1120 sys.stdout = new_stdout
1121
Johnny Chen953864a2010-10-12 21:35:54 +00001122 # If we specified a relocated directory to run the test suite, do
1123 # the extra housekeeping to copy the testdirs to a configStringified
1124 # directory and to update sys.path before invoking the test runner.
1125 # The purpose is to separate the configuration-specific directories
1126 # from each other.
1127 if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001128 from shutil import copytree, ignore_patterns
1129
Johnny Chen953864a2010-10-12 21:35:54 +00001130 newrdir = "%s.%s" % (rdir, configPostfix)
1131
1132 # Copy the tree to a new directory with postfix name configPostfix.
1133 copytree(rdir, newrdir, ignore=ignore_patterns('*.pyc', '*.o', '*.d'))
1134
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001135 # Update the LLDB_TEST environment variable to reflect new top
Johnny Chen953864a2010-10-12 21:35:54 +00001136 # level test directory.
1137 #
1138 # See also lldbtest.TestBase.setUpClass(cls).
1139 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
1140 os.environ["LLDB_TEST"] = os.path.join(newrdir, 'test')
1141 else:
1142 os.environ["LLDB_TEST"] = newrdir
1143
1144 # And update the Python search paths for modules.
1145 sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
1146
1147 # Output the configuration.
Johnny Chenb40056b2010-09-21 00:09:27 +00001148 sys.stderr.write("\nConfiguration: " + configString + "\n")
Johnny Chen953864a2010-10-12 21:35:54 +00001149
1150 #print "sys.stderr name is", sys.stderr.name
1151 #print "sys.stdout name is", sys.stdout.name
1152
1153 # First, write out the number of collected test cases.
Johnny Chen08967192011-11-18 00:19:29 +00001154 sys.stderr.write(separator + "\n")
1155 sys.stderr.write("Collected %d test%s\n\n"
1156 % (suite.countTestCases(),
1157 suite.countTestCases() != 1 and "s" or ""))
Johnny Chen953864a2010-10-12 21:35:54 +00001158
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001159 class LLDBTestResult(unittest2.TextTestResult):
1160 """
Johnny Chen26be4532010-11-09 23:56:14 +00001161 Enforce a singleton pattern to allow introspection of test progress.
1162
1163 Overwrite addError(), addFailure(), and addExpectedFailure() methods
1164 to enable each test instance to track its failure/error status. It
1165 is used in the LLDB test framework to emit detailed trace messages
1166 to a log file for easier human inspection of test failres/errors.
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001167 """
1168 __singleton__ = None
Johnny Chen360dd372010-11-29 17:50:10 +00001169 __ignore_singleton__ = False
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001170
1171 def __init__(self, *args):
Johnny Chen360dd372010-11-29 17:50:10 +00001172 if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
Johnny Chend2acdb32010-11-16 22:42:58 +00001173 raise Exception("LLDBTestResult instantiated more than once")
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001174 super(LLDBTestResult, self).__init__(*args)
1175 LLDBTestResult.__singleton__ = self
1176 # Now put this singleton into the lldb module namespace.
1177 lldb.test_result = self
Johnny Chen810042e2011-01-05 20:24:11 +00001178 # Computes the format string for displaying the counter.
1179 global suite
1180 counterWidth = len(str(suite.countTestCases()))
1181 self.fmt = "%" + str(counterWidth) + "d: "
Johnny Chenc87fd492011-01-05 22:50:11 +00001182 self.indentation = ' ' * (counterWidth + 2)
Johnny Chen810042e2011-01-05 20:24:11 +00001183 # This counts from 1 .. suite.countTestCases().
1184 self.counter = 0
1185
Johnny Chenc87fd492011-01-05 22:50:11 +00001186 def getDescription(self, test):
1187 doc_first_line = test.shortDescription()
1188 if self.descriptions and doc_first_line:
1189 return '\n'.join((str(test), self.indentation + doc_first_line))
1190 else:
1191 return str(test)
1192
Johnny Chen810042e2011-01-05 20:24:11 +00001193 def startTest(self, test):
1194 self.counter += 1
1195 if self.showAll:
1196 self.stream.write(self.fmt % self.counter)
1197 super(LLDBTestResult, self).startTest(test)
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001198
Johnny Chen08967192011-11-18 00:19:29 +00001199 def stopTest(self, test):
1200 """Called when the given test has been run"""
1201 if progress_bar:
1202 sys.__stdout__.write('.')
1203 sys.__stdout__.flush()
1204 if self.counter == suite.countTestCases():
1205 sys.__stdout__.write('\n')
1206
1207 super(LLDBTestResult, self).stopTest(test)
1208
Johnny Chence681462010-10-19 00:25:01 +00001209 def addError(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001210 global sdir_has_content
1211 sdir_has_content = True
Johnny Chence681462010-10-19 00:25:01 +00001212 super(LLDBTestResult, self).addError(test, err)
1213 method = getattr(test, "markError", None)
1214 if method:
1215 method()
1216
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001217 def addFailure(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001218 global sdir_has_content
1219 sdir_has_content = True
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001220 super(LLDBTestResult, self).addFailure(test, err)
1221 method = getattr(test, "markFailure", None)
1222 if method:
1223 method()
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001224
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001225 def addExpectedFailure(self, test, err):
1226 global sdir_has_content
1227 sdir_has_content = True
1228 super(LLDBTestResult, self).addExpectedFailure(test, err)
1229 method = getattr(test, "markExpectedFailure", None)
1230 if method:
1231 method()
1232
Johnny Chenf5b89092011-08-15 23:09:08 +00001233 def addSkip(self, test, reason):
1234 global sdir_has_content
1235 sdir_has_content = True
1236 super(LLDBTestResult, self).addSkip(test, reason)
1237 method = getattr(test, "markSkippedTest", None)
1238 if method:
1239 method()
1240
Johnny Chenab2f0662011-05-06 20:30:22 +00001241 def addUnexpectedSuccess(self, test):
1242 global sdir_has_content
1243 sdir_has_content = True
1244 super(LLDBTestResult, self).addUnexpectedSuccess(test)
1245 method = getattr(test, "markUnexpectedSuccess", None)
1246 if method:
1247 method()
1248
Johnny Chen26be4532010-11-09 23:56:14 +00001249 # Invoke the test runner.
Johnny Chend2acdb32010-11-16 22:42:58 +00001250 if count == 1:
Johnny Chen7d6d8442010-12-03 19:59:35 +00001251 result = unittest2.TextTestRunner(stream=sys.stderr,
1252 verbosity=verbose,
1253 failfast=failfast,
Johnny Chend2acdb32010-11-16 22:42:58 +00001254 resultclass=LLDBTestResult).run(suite)
1255 else:
Johnny Chend6e7ca22010-11-29 17:52:43 +00001256 # We are invoking the same test suite more than once. In this case,
1257 # mark __ignore_singleton__ flag as True so the signleton pattern is
1258 # not enforced.
Johnny Chen360dd372010-11-29 17:50:10 +00001259 LLDBTestResult.__ignore_singleton__ = True
Johnny Chend2acdb32010-11-16 22:42:58 +00001260 for i in range(count):
Johnny Chen7d6d8442010-12-03 19:59:35 +00001261 result = unittest2.TextTestRunner(stream=sys.stderr,
1262 verbosity=verbose,
1263 failfast=failfast,
Johnny Chen360dd372010-11-29 17:50:10 +00001264 resultclass=LLDBTestResult).run(suite)
Johnny Chenb40056b2010-09-21 00:09:27 +00001265
Johnny Chen1bfbd412010-06-29 19:44:16 +00001266
Johnny Chen63c2cba2010-10-29 22:20:36 +00001267if sdir_has_content:
Johnny Chenab2f0662011-05-06 20:30:22 +00001268 sys.stderr.write("Session logs for test failures/errors/unexpected successes"
1269 " can be found in directory '%s'\n" % sdir_name)
Johnny Chen63c2cba2010-10-29 22:20:36 +00001270
Johnny Chencd0279d2010-09-20 18:07:50 +00001271# Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1272# This should not be necessary now.
Johnny Chen83f6e512010-08-13 22:58:44 +00001273if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
Johnny Chen83f6e512010-08-13 22:58:44 +00001274 print "Terminating Test suite..."
1275 subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1276
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001277# Exiting.
1278sys.exit(not result.wasSuccessful)