blob: c01af3052f2c68190399eb24dd8564ecdffd5923 [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 Chena3ed7d82012-04-06 00:56:05 +000077# By default, both dsym and dwarf tests are performed.
78# Use @dsym_test or @dwarf_test decorators, defined in lldbtest.py, to mark a test
79# as a dsym or dwarf test. Use '-N dsym' or '-N dwarf' to exclude dsym or dwarf
80# tests from running.
81dont_do_dsym_test = False
82dont_do_dwarf_test = False
83
Johnny Chen82e6b1e2010-12-01 22:47:54 +000084# The blacklist is optional (-b blacklistFile) and allows a central place to skip
85# testclass's and/or testclass.testmethod's.
86blacklist = None
87
88# The dictionary as a result of sourcing blacklistFile.
89blacklistConfig = {}
90
Johnny Chen9fdb0a92010-09-18 00:16:47 +000091# The config file is optional.
92configFile = None
93
Johnny Chend2acdb32010-11-16 22:42:58 +000094# Test suite repeat count. Can be overwritten with '-# count'.
95count = 1
96
Johnny Chenb40056b2010-09-21 00:09:27 +000097# The dictionary as a result of sourcing configFile.
98config = {}
99
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000100# The 'archs' and 'compilers' can be specified via either command line or configFile,
101# with the command line overriding the configFile. When specified, they should be
102# of the list type. For example, "-A x86_64^i386" => archs=['x86_64', 'i386'] and
103# "-C gcc^clang" => compilers=['gcc', 'clang'].
Johnny Chenbb4800e2012-04-12 00:55:57 +0000104archs = ['x86_64', 'i386']
Johnny Chen92693b52012-03-09 02:11:37 +0000105compilers = ['clang']
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000106
Johnny Chen1abe4c02012-03-20 00:33:51 +0000107# The arch might dictate some specific CFLAGS to be passed to the toolchain to build
108# the inferior programs. The global variable cflags_extras provides a hook to do
109# just that.
110cflags_extras = ''
111
Johnny Chen91960d32010-09-08 20:56:16 +0000112# Delay startup in order for the debugger to attach.
113delay = False
114
Johnny Chend5362332011-01-29 01:21:04 +0000115# Dump the Python sys.path variable. Use '-D' to dump sys.path.
Johnny Chen50bc6382011-01-29 01:16:52 +0000116dumpSysPath = False
117
Johnny Chene00c9302011-10-10 22:03:44 +0000118# Full path of the benchmark executable, as specified by the '-e' option.
119bmExecutable = None
120# The breakpoint specification of bmExecutable, as specified by the '-x' option.
121bmBreakpointSpec = None
Johnny Chen5f2ed172011-10-20 18:43:28 +0000122# The benchamrk iteration count, as specified by the '-y' option.
123bmIterationCount = -1
Johnny Chene00c9302011-10-10 22:03:44 +0000124
Johnny Chene9eae812012-01-18 05:15:00 +0000125# By default, don't exclude any directories. Use '-X' to add one excluded directory.
126excluded = set(['.svn', '.git'])
127
Johnny Chen7d6d8442010-12-03 19:59:35 +0000128# By default, failfast is False. Use '-F' to overwrite it.
129failfast = False
130
Johnny Chenc5fa0052011-07-29 22:54:56 +0000131# The filters (testclass.testmethod) used to admit tests into our test suite.
132filters = []
Johnny Chenb62436b2010-10-06 20:40:56 +0000133
Johnny Chen38f823c2011-10-11 01:30:27 +0000134# The runhooks is a list of lldb commands specifically for the debugger.
135# Use '-k' to specify a runhook.
136runHooks = []
137
Johnny Chena224cd12010-11-08 01:21:03 +0000138# If '-g' is specified, the filterspec is not exclusive. If a test module does
139# not contain testclass.testmethod which matches the filterspec, the whole test
140# module is still admitted into our test suite. fs4all flag defaults to True.
141fs4all = True
Johnny Chenb62436b2010-10-06 20:40:56 +0000142
Johnny Chenaf149a02010-09-16 17:11:30 +0000143# Ignore the build search path relative to this script to locate the lldb.py module.
144ignore = False
145
Johnny Chen028d8eb2011-11-17 19:57:27 +0000146# By default, we do not skip build and cleanup. Use '-S' option to override.
147skip_build_and_cleanup = False
148
Johnny Chen548aefd2010-10-11 22:25:46 +0000149# By default, we skip long running test case. Use '-l' option to override.
Johnny Chen028d8eb2011-11-17 19:57:27 +0000150skip_long_running_test = True
Johnny Chen41998192010-10-01 22:59:49 +0000151
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000152# By default, we print the build dir, lldb version, and svn info. Use '-n' option to
153# turn it off.
154noHeaders = False
155
Johnny Chen7c52ff12010-09-27 23:29:54 +0000156# The regular expression pattern to match against eligible filenames as our test cases.
157regexp = None
158
Johnny Chen548aefd2010-10-11 22:25:46 +0000159# By default, tests are executed in place and cleanups are performed afterwards.
160# Use '-r dir' option to relocate the tests and their intermediate files to a
161# different directory and to forgo any cleanups. The directory specified must
162# not exist yet.
163rdir = None
164
Johnny Chen125fc2b2010-10-21 16:55:35 +0000165# By default, recorded session info for errored/failed test are dumped into its
166# own file under a session directory named after the timestamp of the test suite
167# run. Use '-s session-dir-name' to specify a specific dir name.
168sdir_name = None
169
Johnny Chen63c2cba2010-10-29 22:20:36 +0000170# Set this flag if there is any session info dumped during the test run.
171sdir_has_content = False
172
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000173# svn_info stores the output from 'svn info lldb.base.dir'.
174svn_info = ''
175
Johnny Chen0f907b82012-01-31 00:38:03 +0000176# The environment variables to unset before running the test cases.
177unsets = []
178
Johnny Chen9707bb62010-06-25 21:14:08 +0000179# Default verbosity is 0.
180verbose = 0
181
Johnny Chen08967192011-11-18 00:19:29 +0000182# Set to True only if verbose is 0 and LLDB trace mode is off.
183progress_bar = False
184
Peter Collingbourne61aca482011-06-20 19:06:29 +0000185# By default, search from the script directory.
186testdirs = [ sys.path[0] ]
Johnny Chen9707bb62010-06-25 21:14:08 +0000187
Johnny Chen877c7e42010-08-07 00:16:07 +0000188# Separator string.
189separator = '-' * 70
190
Johnny Chen9707bb62010-06-25 21:14:08 +0000191
192def usage():
193 print """
194Usage: dotest.py [option] [args]
195where options:
Jim Ingham4f347cb2011-04-13 21:11:41 +0000196-h : print this help message and exit. Add '-v' for more detailed help.
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000197-A : specify the architecture(s) to launch for the inferior process
198 -A i386 => launch inferior with i386 architecture
199 -A x86_64^i386 => launch inferior with x86_64 and i386 architectures
200-C : specify the compiler(s) used to build the inferior executable
201 -C clang => build debuggee using clang compiler
Johnny Chence9cf4e2012-01-17 01:26:06 +0000202 -C /my/full/path/to/clang => specify a full path to the clang binary
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000203 -C clang^gcc => build debuggee using clang and gcc compilers
Johnny Chen50bc6382011-01-29 01:16:52 +0000204-D : dump the Python sys.path variable
Johnny Chen1abe4c02012-03-20 00:33:51 +0000205-E : specify the extra flags to be passed to the toolchain when building the
206 inferior programs to be debugged
207 suggestions: do not lump the -A arch1^arch2 together such that the -E
208 option applies to only one of the architectures
Johnny Chena3ed7d82012-04-06 00:56:05 +0000209-N : don't do test cases marked with the @dsym decorator by passing 'dsym' as the option arg, or
210 don't do test cases marked with the @dwarf decorator by passing 'dwarf' as the option arg
Johnny Chen4f93bf12010-12-10 00:51:23 +0000211-a : don't do lldb Python API tests
212 use @python_api_test to decorate a test case as lldb Python API test
Johnny Chen3ebdacc2010-12-10 18:52:10 +0000213+a : just do lldb Python API tests
Johnny Chencc659ad2010-12-10 19:02:23 +0000214 do not specify both '-a' and '+a' at the same time
Johnny Chen82ccf402011-07-30 01:39:58 +0000215+b : just do benchmark tests
216 use @benchmark_test to decorate a test case as such
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000217-b : read a blacklist file specified after this option
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000218-c : read a config file specified after this option
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000219 the architectures and compilers (note the plurals) specified via '-A' and '-C'
220 will override those specified via a config file
Johnny Chenb40056b2010-09-21 00:09:27 +0000221 (see also lldb-trunk/example/test/usage-config)
Johnny Chen91960d32010-09-08 20:56:16 +0000222-d : delay startup for 10 seconds (in order for the debugger to attach)
Johnny Chene00c9302011-10-10 22:03:44 +0000223-e : specify the full path of an executable used for benchmark purpose;
224 see also '-x', which provides the breakpoint sepcification
Johnny Chen7d6d8442010-12-03 19:59:35 +0000225-F : failfast, stop the test suite on the first error/failure
Johnny Chen46be75d2010-10-11 16:19:48 +0000226-f : specify a filter, which consists of the test class name, a dot, followed by
Johnny Chen1a6e92a2010-11-08 20:17:04 +0000227 the test method, to only admit such test into the test suite
Johnny Chenb62436b2010-10-06 20:40:56 +0000228 e.g., -f 'ClassTypesTestCase.test_with_dwarf_and_python_api'
Johnny Chena224cd12010-11-08 01:21:03 +0000229-g : if specified, the filterspec by -f is not exclusive, i.e., if a test module
230 does not match the filterspec (testclass.testmethod), the whole module is
231 still admitted to the test suite
Johnny Chenaf149a02010-09-16 17:11:30 +0000232-i : ignore (don't bailout) if 'lldb.py' module cannot be located in the build
233 tree relative to this script; use PYTHONPATH to locate the module
Johnny Chen38f823c2011-10-11 01:30:27 +0000234-k : specify a runhook, which is an lldb command to be executed by the debugger;
235 '-k' option can occur multiple times, the commands are executed one after the
236 other to bring the debugger to a desired state, so that, for example, further
237 benchmarking can be done
Johnny Chen41998192010-10-01 22:59:49 +0000238-l : don't skip long running test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000239-n : don't print the headers like build dir, lldb version, and svn info at all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000240-p : specify a regexp filename pattern for inclusion in the test suite
Johnny Chen548aefd2010-10-11 22:25:46 +0000241-r : specify a dir to relocate the tests and their intermediate files to;
242 the directory must not exist before running this test driver;
243 no cleanup of intermediate test files is performed in this case
Johnny Chen028d8eb2011-11-17 19:57:27 +0000244-S : skip the build and cleanup while running the test
245 use this option with care as you would need to build the inferior(s) by hand
246 and build the executable(s) with the correct name(s)
247 this can be used with '-# n' to stress test certain test cases for n number of
248 times
Johnny Chen125fc2b2010-10-21 16:55:35 +0000249-s : specify the name of the dir created to store the session files of tests
250 with errored or failed status; if not specified, the test driver uses the
251 timestamp as the session dir name
Johnny Chena2486f22011-04-21 20:48:32 +0000252-t : turn on tracing of lldb command and other detailed test executions
Johnny Chen0f907b82012-01-31 00:38:03 +0000253-u : specify an environment variable to unset before running the test cases
254 e.g., -u DYLD_INSERT_LIBRARIES -u MallocScribble'
Johnny Chena2486f22011-04-21 20:48:32 +0000255-v : do verbose mode of unittest framework (print out each test case invocation)
Johnny Chene9eae812012-01-18 05:15:00 +0000256-X : exclude a directory from consideration for test discovery
257 -X types => if 'types' appear in the pathname components of a potential testfile
258 it will be ignored
Johnny Chene00c9302011-10-10 22:03:44 +0000259-x : specify the breakpoint specification for the benchmark executable;
260 see also '-e', which provides the full path of the executable
Johnny Chen5f2ed172011-10-20 18:43:28 +0000261-y : specify the iteration count used to collect our benchmarks; an example is
262 the number of times to do 'thread step-over' to measure stepping speed
263 see also '-e' and '-x' options
Johnny Chene47649c2010-10-07 02:04:14 +0000264-w : insert some wait time (currently 0.5 sec) between consecutive test cases
Johnny Chend2acdb32010-11-16 22:42:58 +0000265-# : Repeat the test suite for a specified number of times
Johnny Chen9707bb62010-06-25 21:14:08 +0000266
267and:
Johnny Chen9656ab22010-10-22 19:00:18 +0000268args : specify a list of directory names to search for test modules named after
269 Test*.py (test discovery)
Peter Collingbourne5f2b5d62011-06-14 03:55:45 +0000270 if empty, search from the current working directory, instead
Jim Ingham4f347cb2011-04-13 21:11:41 +0000271"""
Johnny Chen58f93922010-06-29 23:10:39 +0000272
Jim Ingham4f347cb2011-04-13 21:11:41 +0000273 if verbose > 0:
274 print """
Johnny Chen9656ab22010-10-22 19:00:18 +0000275Examples:
276
Johnny Chena224cd12010-11-08 01:21:03 +0000277This is an example of using the -f option to pinpoint to a specfic test class
278and test method to be run:
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000279
Johnny Chena224cd12010-11-08 01:21:03 +0000280$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000281----------------------------------------------------------------------
282Collected 1 test
283
284test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
285Test 'frame variable this' when stopped on a class constructor. ... ok
286
287----------------------------------------------------------------------
288Ran 1 test in 1.396s
289
290OK
Johnny Chen9656ab22010-10-22 19:00:18 +0000291
292And this is an example of using the -p option to run a single file (the filename
293matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
294
295$ ./dotest.py -v -p ObjC
296----------------------------------------------------------------------
297Collected 4 tests
298
299test_break_with_dsym (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000300Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000301test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000302Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000303test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
304Lookup objective-c data types and evaluate expressions. ... ok
305test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
306Lookup objective-c data types and evaluate expressions. ... ok
307
308----------------------------------------------------------------------
309Ran 4 tests in 16.661s
310
311OK
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000312
Johnny Chen58f93922010-06-29 23:10:39 +0000313Running of this script also sets up the LLDB_TEST environment variable so that
Johnny Chenaf149a02010-09-16 17:11:30 +0000314individual test cases can locate their supporting files correctly. The script
315tries to set up Python's search paths for modules by looking at the build tree
Johnny Chena85859f2010-11-11 22:14:56 +0000316relative to this script. See also the '-i' option in the following example.
317
318Finally, this is an example of using the lldb.py module distributed/installed by
319Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
320option to add some delay between two tests. It uses ARCH=x86_64 to specify that
321as the architecture and CC=clang to specify the compiler used for the test run:
322
323$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
324
325Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
326----------------------------------------------------------------------
327Collected 2 tests
328
329test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
330Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
331test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
332Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
333
334----------------------------------------------------------------------
335Ran 2 tests in 5.659s
336
337OK
338
339The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
340notify the directory containing the session logs for test failures or errors.
341In case there is any test failure/error, a similar message is appended at the
342end of the stderr output for your convenience.
Johnny Chenfde69bc2010-09-14 22:01:40 +0000343
344Environment variables related to loggings:
345
346o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
347 with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
348
349o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
350 'process.gdb-remote' subsystem with a default option of 'packets' if
351 GDB_REMOTE_LOG_OPTION is not defined.
Johnny Chen9707bb62010-06-25 21:14:08 +0000352"""
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000353 sys.exit(0)
Johnny Chen9707bb62010-06-25 21:14:08 +0000354
355
Johnny Chenaf149a02010-09-16 17:11:30 +0000356def parseOptionsAndInitTestdirs():
357 """Initialize the list of directories containing our unittest scripts.
358
359 '-h/--help as the first option prints out usage info and exit the program.
360 """
361
Johnny Chen4f93bf12010-12-10 00:51:23 +0000362 global dont_do_python_api_test
363 global just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000364 global just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +0000365 global dont_do_dsym_test
366 global dont_do_dwarf_test
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000367 global blacklist
368 global blacklistConfig
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000369 global configFile
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000370 global archs
371 global compilers
Johnny Chend2acdb32010-11-16 22:42:58 +0000372 global count
Johnny Chenaf149a02010-09-16 17:11:30 +0000373 global delay
Johnny Chen50bc6382011-01-29 01:16:52 +0000374 global dumpSysPath
Johnny Chene00c9302011-10-10 22:03:44 +0000375 global bmExecutable
376 global bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000377 global bmIterationCount
Johnny Chen7d6d8442010-12-03 19:59:35 +0000378 global failfast
Johnny Chenc5fa0052011-07-29 22:54:56 +0000379 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000380 global fs4all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000381 global ignore
Johnny Chen08967192011-11-18 00:19:29 +0000382 global progress_bar
Johnny Chen38f823c2011-10-11 01:30:27 +0000383 global runHooks
Johnny Chen028d8eb2011-11-17 19:57:27 +0000384 global skip_build_and_cleanup
385 global skip_long_running_test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000386 global noHeaders
Johnny Chen7c52ff12010-09-27 23:29:54 +0000387 global regexp
Johnny Chen548aefd2010-10-11 22:25:46 +0000388 global rdir
Johnny Chen125fc2b2010-10-21 16:55:35 +0000389 global sdir_name
Johnny Chen0f907b82012-01-31 00:38:03 +0000390 global unsets
Johnny Chenaf149a02010-09-16 17:11:30 +0000391 global verbose
392 global testdirs
393
Jim Ingham4f347cb2011-04-13 21:11:41 +0000394 do_help = False
395
Johnny Chenaf149a02010-09-16 17:11:30 +0000396 if len(sys.argv) == 1:
397 return
398
399 # Process possible trace and/or verbose flag, among other things.
400 index = 1
Johnny Chence2212c2010-10-07 15:41:55 +0000401 while index < len(sys.argv):
Johnny Chen4f93bf12010-12-10 00:51:23 +0000402 if sys.argv[index].startswith('-') or sys.argv[index].startswith('+'):
403 # We should continue processing...
404 pass
405 else:
Johnny Chenaf149a02010-09-16 17:11:30 +0000406 # End of option processing.
407 break
408
409 if sys.argv[index].find('-h') != -1:
Jim Ingham4f347cb2011-04-13 21:11:41 +0000410 index += 1
411 do_help = True
Johnny Chen012cba12011-01-26 19:07:42 +0000412 elif sys.argv[index].startswith('-A'):
413 # Increment by 1 to fetch the ARCH spec.
414 index += 1
415 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
416 usage()
Johnny Cheneee9b862011-04-26 20:45:00 +0000417 archs = sys.argv[index].split('^')
Johnny Chen012cba12011-01-26 19:07:42 +0000418 index += 1
419 elif sys.argv[index].startswith('-C'):
420 # Increment by 1 to fetch the CC spec.
421 index += 1
422 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
423 usage()
Johnny Cheneee9b862011-04-26 20:45:00 +0000424 compilers = sys.argv[index].split('^')
Johnny Chen012cba12011-01-26 19:07:42 +0000425 index += 1
Johnny Chen50bc6382011-01-29 01:16:52 +0000426 elif sys.argv[index].startswith('-D'):
427 dumpSysPath = True
428 index += 1
Johnny Chen1abe4c02012-03-20 00:33:51 +0000429 elif sys.argv[index].startswith('-E'):
430 # Increment by 1 to fetch the CFLAGS_EXTRAS spec.
431 index += 1
432 if index >= len(sys.argv):
433 usage()
434 cflags_extras = sys.argv[index]
435 os.environ["CFLAGS_EXTRAS"] = cflags_extras
436 index += 1
Johnny Chena3ed7d82012-04-06 00:56:05 +0000437 elif sys.argv[index].startswith('-N'):
438 # Increment by 1 to fetch 'dsym' or 'dwarf'.
439 index += 1
440 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
441 usage()
442 dont_do = sys.argv[index]
443 if dont_do.lower() == 'dsym':
444 dont_do_dsym_test = True
445 elif dont_do.lower() == 'dwarf':
446 dont_do_dwarf_test = True
447 else:
448 print "!!!"
449 print "Warning: -N only accepts either 'dsym' or 'dwarf' as the option arg; you passed in '%s'?" % dont_do
450 print "!!!"
451 index += 1
Johnny Chen4f93bf12010-12-10 00:51:23 +0000452 elif sys.argv[index].startswith('-a'):
453 dont_do_python_api_test = True
454 index += 1
455 elif sys.argv[index].startswith('+a'):
456 just_do_python_api_test = True
457 index += 1
Johnny Chen82ccf402011-07-30 01:39:58 +0000458 elif sys.argv[index].startswith('+b'):
459 just_do_benchmarks_test = True
460 index += 1
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000461 elif sys.argv[index].startswith('-b'):
462 # Increment by 1 to fetch the blacklist file name option argument.
463 index += 1
464 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
465 usage()
466 blacklistFile = sys.argv[index]
467 if not os.path.isfile(blacklistFile):
468 print "Blacklist file:", blacklistFile, "does not exist!"
469 usage()
470 index += 1
471 # Now read the blacklist contents and assign it to blacklist.
472 execfile(blacklistFile, globals(), blacklistConfig)
473 blacklist = blacklistConfig.get('blacklist')
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000474 elif sys.argv[index].startswith('-c'):
475 # Increment by 1 to fetch the config file name option argument.
476 index += 1
477 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
478 usage()
479 configFile = sys.argv[index]
480 if not os.path.isfile(configFile):
481 print "Config file:", configFile, "does not exist!"
482 usage()
483 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000484 elif sys.argv[index].startswith('-d'):
485 delay = True
486 index += 1
Johnny Chene00c9302011-10-10 22:03:44 +0000487 elif sys.argv[index].startswith('-e'):
488 # Increment by 1 to fetch the full path of the benchmark executable.
489 index += 1
490 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
491 usage()
492 bmExecutable = sys.argv[index]
493 if not is_exe(bmExecutable):
494 usage()
495 index += 1
Johnny Chen7d6d8442010-12-03 19:59:35 +0000496 elif sys.argv[index].startswith('-F'):
497 failfast = True
498 index += 1
Johnny Chenb62436b2010-10-06 20:40:56 +0000499 elif sys.argv[index].startswith('-f'):
500 # Increment by 1 to fetch the filter spec.
501 index += 1
502 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
503 usage()
Johnny Chenc5fa0052011-07-29 22:54:56 +0000504 filters.append(sys.argv[index])
Johnny Chenb62436b2010-10-06 20:40:56 +0000505 index += 1
506 elif sys.argv[index].startswith('-g'):
Johnny Chena224cd12010-11-08 01:21:03 +0000507 fs4all = False
Johnny Chenb62436b2010-10-06 20:40:56 +0000508 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000509 elif sys.argv[index].startswith('-i'):
510 ignore = True
511 index += 1
Johnny Chen38f823c2011-10-11 01:30:27 +0000512 elif sys.argv[index].startswith('-k'):
513 # Increment by 1 to fetch the runhook lldb command.
514 index += 1
515 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
516 usage()
517 runHooks.append(sys.argv[index])
518 index += 1
Johnny Chen41998192010-10-01 22:59:49 +0000519 elif sys.argv[index].startswith('-l'):
Johnny Chen028d8eb2011-11-17 19:57:27 +0000520 skip_long_running_test = False
Johnny Chen41998192010-10-01 22:59:49 +0000521 index += 1
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000522 elif sys.argv[index].startswith('-n'):
523 noHeaders = True
524 index += 1
Johnny Chen7c52ff12010-09-27 23:29:54 +0000525 elif sys.argv[index].startswith('-p'):
526 # Increment by 1 to fetch the reg exp pattern argument.
527 index += 1
528 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
529 usage()
530 regexp = sys.argv[index]
531 index += 1
Johnny Chen548aefd2010-10-11 22:25:46 +0000532 elif sys.argv[index].startswith('-r'):
533 # Increment by 1 to fetch the relocated directory argument.
534 index += 1
535 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
536 usage()
537 rdir = os.path.abspath(sys.argv[index])
538 if os.path.exists(rdir):
539 print "Relocated directory:", rdir, "must not exist!"
540 usage()
541 index += 1
Johnny Chen028d8eb2011-11-17 19:57:27 +0000542 elif sys.argv[index].startswith('-S'):
543 skip_build_and_cleanup = True
544 index += 1
Johnny Chen125fc2b2010-10-21 16:55:35 +0000545 elif sys.argv[index].startswith('-s'):
546 # Increment by 1 to fetch the session dir name.
547 index += 1
548 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
549 usage()
550 sdir_name = sys.argv[index]
551 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000552 elif sys.argv[index].startswith('-t'):
553 os.environ["LLDB_COMMAND_TRACE"] = "YES"
554 index += 1
Johnny Chen0f907b82012-01-31 00:38:03 +0000555 elif sys.argv[index].startswith('-u'):
556 # Increment by 1 to fetch the environment variable to unset.
557 index += 1
558 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
559 usage()
560 unsets.append(sys.argv[index])
561 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000562 elif sys.argv[index].startswith('-v'):
563 verbose = 2
564 index += 1
Johnny Chene47649c2010-10-07 02:04:14 +0000565 elif sys.argv[index].startswith('-w'):
566 os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] = 'YES'
567 index += 1
Johnny Chene9eae812012-01-18 05:15:00 +0000568 elif sys.argv[index].startswith('-X'):
569 # Increment by 1 to fetch an excluded directory.
570 index += 1
571 if index >= len(sys.argv):
572 usage()
573 excluded.add(sys.argv[index])
574 index += 1
Johnny Chene00c9302011-10-10 22:03:44 +0000575 elif sys.argv[index].startswith('-x'):
576 # Increment by 1 to fetch the breakpoint specification of the benchmark executable.
577 index += 1
Johnny Chen8a1b1222011-10-20 22:16:24 +0000578 if index >= len(sys.argv):
Johnny Chene00c9302011-10-10 22:03:44 +0000579 usage()
580 bmBreakpointSpec = sys.argv[index]
581 index += 1
Johnny Chen5f2ed172011-10-20 18:43:28 +0000582 elif sys.argv[index].startswith('-y'):
583 # Increment by 1 to fetch the the benchmark iteration count.
584 index += 1
585 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
586 usage()
587 bmIterationCount = int(sys.argv[index])
588 index += 1
Johnny Chend2acdb32010-11-16 22:42:58 +0000589 elif sys.argv[index].startswith('-#'):
590 # Increment by 1 to fetch the repeat count argument.
591 index += 1
592 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
593 usage()
594 count = int(sys.argv[index])
595 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000596 else:
597 print "Unknown option: ", sys.argv[index]
598 usage()
Johnny Chenaf149a02010-09-16 17:11:30 +0000599
Jim Ingham4f347cb2011-04-13 21:11:41 +0000600 if do_help == True:
601 usage()
602
Johnny Chencc659ad2010-12-10 19:02:23 +0000603 # Do not specify both '-a' and '+a' at the same time.
604 if dont_do_python_api_test and just_do_python_api_test:
605 usage()
606
Johnny Chen08967192011-11-18 00:19:29 +0000607 # The simple progress bar is turned on only if verbose == 0 and LLDB_COMMAND_TRACE is not 'YES'
608 if ("LLDB_COMMAND_TRACE" not in os.environ or os.environ["LLDB_COMMAND_TRACE"]!="YES") and verbose==0:
609 progress_bar = True
610
Johnny Chenaf149a02010-09-16 17:11:30 +0000611 # Gather all the dirs passed on the command line.
612 if len(sys.argv) > index:
613 testdirs = map(os.path.abspath, sys.argv[index:])
614
Johnny Chen548aefd2010-10-11 22:25:46 +0000615 # If '-r dir' is specified, the tests should be run under the relocated
616 # directory. Let's copy the testdirs over.
617 if rdir:
618 from shutil import copytree, ignore_patterns
619
620 tmpdirs = []
621 for srcdir in testdirs:
Johnny Chen1abe4c02012-03-20 00:33:51 +0000622 # For example, /Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/hello_watchpoint
623 # shall be split into ['/Volumes/data/lldb/svn/ToT/', 'functionalities/watchpoint/hello_watchpoint'].
624 # Utilize the relative path to the 'test' directory to make our destination dir path.
625 dstdir = os.path.join(rdir, srcdir.split("test"+os.sep)[1])
626 #print "(srcdir, dstdir)=(%s, %s)" % (srcdir, dstdir)
Johnny Chen548aefd2010-10-11 22:25:46 +0000627 # Don't copy the *.pyc and .svn stuffs.
628 copytree(srcdir, dstdir, ignore=ignore_patterns('*.pyc', '.svn'))
629 tmpdirs.append(dstdir)
630
631 # This will be our modified testdirs.
632 testdirs = tmpdirs
633
634 # With '-r dir' specified, there's no cleanup of intermediate test files.
635 os.environ["LLDB_DO_CLEANUP"] = 'NO'
636
637 # If testdirs is ['test'], the make directory has already been copied
638 # recursively and is contained within the rdir/test dir. For anything
639 # else, we would need to copy over the make directory and its contents,
640 # so that, os.listdir(rdir) looks like, for example:
641 #
642 # array_types conditional_break make
643 #
644 # where the make directory contains the Makefile.rules file.
645 if len(testdirs) != 1 or os.path.basename(testdirs[0]) != 'test':
646 # Don't copy the .svn stuffs.
647 copytree('make', os.path.join(rdir, 'make'),
648 ignore=ignore_patterns('.svn'))
649
650 #print "testdirs:", testdirs
651
Johnny Chenb40056b2010-09-21 00:09:27 +0000652 # Source the configFile if specified.
653 # The side effect, if any, will be felt from this point on. An example
654 # config file may be these simple two lines:
655 #
656 # sys.stderr = open("/tmp/lldbtest-stderr", "w")
657 # sys.stdout = open("/tmp/lldbtest-stdout", "w")
658 #
659 # which will reassign the two file objects to sys.stderr and sys.stdout,
660 # respectively.
661 #
662 # See also lldb-trunk/example/test/usage-config.
663 global config
664 if configFile:
665 # Pass config (a dictionary) as the locals namespace for side-effect.
666 execfile(configFile, globals(), config)
667 #print "config:", config
668 #print "sys.stderr:", sys.stderr
669 #print "sys.stdout:", sys.stdout
670
Johnny Chenaf149a02010-09-16 17:11:30 +0000671
Johnny Chen9707bb62010-06-25 21:14:08 +0000672def setupSysPath():
Johnny Chen8a3c0432011-03-11 20:13:06 +0000673 """
674 Add LLDB.framework/Resources/Python to the search paths for modules.
675 As a side effect, we also discover the 'lldb' executable and export it here.
676 """
Johnny Chen9707bb62010-06-25 21:14:08 +0000677
Johnny Chen548aefd2010-10-11 22:25:46 +0000678 global rdir
679 global testdirs
Johnny Chen50bc6382011-01-29 01:16:52 +0000680 global dumpSysPath
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000681 global noHeaders
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000682 global svn_info
Johnny Chen548aefd2010-10-11 22:25:46 +0000683
Johnny Chen9707bb62010-06-25 21:14:08 +0000684 # Get the directory containing the current script.
Johnny Chen4d162e52011-08-12 18:54:11 +0000685 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 +0000686 scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
687 else:
688 scriptPath = sys.path[0]
Johnny Chena1affab2010-07-03 03:41:59 +0000689 if not scriptPath.endswith('test'):
Johnny Chen9707bb62010-06-25 21:14:08 +0000690 print "This script expects to reside in lldb's test directory."
691 sys.exit(-1)
692
Johnny Chen548aefd2010-10-11 22:25:46 +0000693 if rdir:
694 # Set up the LLDB_TEST environment variable appropriately, so that the
695 # individual tests can be located relatively.
696 #
697 # See also lldbtest.TestBase.setUpClass(cls).
698 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
699 os.environ["LLDB_TEST"] = os.path.join(rdir, 'test')
700 else:
701 os.environ["LLDB_TEST"] = rdir
702 else:
703 os.environ["LLDB_TEST"] = scriptPath
Peter Collingbournef6c3de82011-06-20 19:06:45 +0000704
705 # Set up the LLDB_SRC environment variable, so that the tests can locate
706 # the LLDB source code.
707 os.environ["LLDB_SRC"] = os.path.join(sys.path[0], os.pardir)
708
Johnny Chen9de4ede2010-08-31 17:42:54 +0000709 pluginPath = os.path.join(scriptPath, 'plugins')
Johnny Chen8a3c0432011-03-11 20:13:06 +0000710 pexpectPath = os.path.join(scriptPath, 'pexpect-2.4')
Johnny Chen58f93922010-06-29 23:10:39 +0000711
Johnny Chen8a3c0432011-03-11 20:13:06 +0000712 # Append script dir, plugin dir, and pexpect dir to the sys.path.
Johnny Chenaf149a02010-09-16 17:11:30 +0000713 sys.path.append(scriptPath)
714 sys.path.append(pluginPath)
Johnny Chen8a3c0432011-03-11 20:13:06 +0000715 sys.path.append(pexpectPath)
Johnny Chenaf149a02010-09-16 17:11:30 +0000716
Johnny Chen26901c82011-03-11 19:47:23 +0000717 # This is our base name component.
Johnny Chena1affab2010-07-03 03:41:59 +0000718 base = os.path.abspath(os.path.join(scriptPath, os.pardir))
Johnny Chen6a564a42011-02-15 18:50:19 +0000719
Johnny Chen26901c82011-03-11 19:47:23 +0000720 # These are for xcode build directories.
Johnny Chen6a564a42011-02-15 18:50:19 +0000721 xcode3_build_dir = ['build']
722 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
723 dbg = ['Debug']
724 rel = ['Release']
725 bai = ['BuildAndIntegration']
726 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
Johnny Chen26901c82011-03-11 19:47:23 +0000727
728 # Some of the tests can invoke the 'lldb' command directly.
729 # We'll try to locate the appropriate executable right here.
730
Johnny Chen6033bed2011-08-26 00:00:01 +0000731 # First, you can define an environment variable LLDB_EXEC specifying the
732 # full pathname of the lldb executable.
733 if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
734 lldbExec = os.environ["LLDB_EXEC"]
735 else:
736 lldbExec = None
737
Johnny Chen26901c82011-03-11 19:47:23 +0000738 executable = ['lldb']
739 dbgExec = os.path.join(base, *(xcode3_build_dir + dbg + executable))
740 dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
741 relExec = os.path.join(base, *(xcode3_build_dir + rel + executable))
742 relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
743 baiExec = os.path.join(base, *(xcode3_build_dir + bai + executable))
744 baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
745
Johnny Chen6033bed2011-08-26 00:00:01 +0000746 # The 'lldb' executable built here in the source tree.
747 lldbHere = None
Johnny Chen26901c82011-03-11 19:47:23 +0000748 if is_exe(dbgExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000749 lldbHere = dbgExec
Johnny Chen26901c82011-03-11 19:47:23 +0000750 elif is_exe(dbgExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000751 lldbHere = dbgExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000752 elif is_exe(relExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000753 lldbHere = relExec
Johnny Chen26901c82011-03-11 19:47:23 +0000754 elif is_exe(relExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000755 lldbHere = relExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000756 elif is_exe(baiExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000757 lldbHere = baiExec
Johnny Chen26901c82011-03-11 19:47:23 +0000758 elif is_exe(baiExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000759 lldbHere = baiExec2
Daniel Dunbar2bd310c2011-10-31 23:27:06 +0000760 elif lldbExec:
761 lldbHere = lldbExec
Johnny Chen26901c82011-03-11 19:47:23 +0000762
Johnny Chen6033bed2011-08-26 00:00:01 +0000763 if lldbHere:
764 os.environ["LLDB_HERE"] = lldbHere
Johnny Chen0409d992011-10-25 20:08:03 +0000765 os.environ["LLDB_BUILD_DIR"] = os.path.split(lldbHere)[0]
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000766 if not noHeaders:
767 print "LLDB build dir:", os.environ["LLDB_BUILD_DIR"]
Johnny Chen91da0052011-10-28 17:56:02 +0000768 os.system('%s -v' % lldbHere)
Johnny Chen62d527e2011-08-04 18:17:16 +0000769
Johnny Chen6033bed2011-08-26 00:00:01 +0000770 # One last chance to locate the 'lldb' executable.
Johnny Chen26901c82011-03-11 19:47:23 +0000771 if not lldbExec:
Johnny Chen0409d992011-10-25 20:08:03 +0000772 lldbExec = which('lldb')
773 if lldbHere and not lldbExec:
Johnny Chen6033bed2011-08-26 00:00:01 +0000774 lldbExec = lldbHere
Johnny Chen0409d992011-10-25 20:08:03 +0000775
Johnny Chen26901c82011-03-11 19:47:23 +0000776
777 if not lldbExec:
778 print "The 'lldb' executable cannot be located. Some of the tests may not be run as a result."
779 else:
780 os.environ["LLDB_EXEC"] = lldbExec
Johnny Chen8904eb02011-10-28 00:59:00 +0000781 #print "The 'lldb' from PATH env variable", lldbExec
Johnny Chend7931462011-03-17 00:38:22 +0000782
Johnny Chenb264c9b2011-06-24 22:52:05 +0000783 if os.path.isdir(os.path.join(base, '.svn')):
784 pipe = subprocess.Popen(["svn", "info", base], stdout = subprocess.PIPE)
785 svn_info = pipe.stdout.read()
786 elif os.path.isdir(os.path.join(base, '.git')):
787 pipe = subprocess.Popen(["git", "svn", "info", base], stdout = subprocess.PIPE)
788 svn_info = pipe.stdout.read()
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000789 if not noHeaders:
790 print svn_info
Johnny Chen26901c82011-03-11 19:47:23 +0000791
792 global ignore
793
794 # The '-i' option is used to skip looking for lldb.py in the build tree.
795 if ignore:
796 return
797
Johnny Chen6a564a42011-02-15 18:50:19 +0000798 dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
799 dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
800 relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
801 relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
802 baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
803 baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
Johnny Chen9707bb62010-06-25 21:14:08 +0000804
805 lldbPath = None
806 if os.path.isfile(os.path.join(dbgPath, 'lldb.py')):
807 lldbPath = dbgPath
Greg Claytond9846b02011-02-14 21:17:06 +0000808 elif os.path.isfile(os.path.join(dbgPath2, 'lldb.py')):
809 lldbPath = dbgPath2
Johnny Chen9707bb62010-06-25 21:14:08 +0000810 elif os.path.isfile(os.path.join(relPath, 'lldb.py')):
811 lldbPath = relPath
Greg Claytond9846b02011-02-14 21:17:06 +0000812 elif os.path.isfile(os.path.join(relPath2, 'lldb.py')):
813 lldbPath = relPath2
Johnny Chenc202c462010-09-15 18:11:19 +0000814 elif os.path.isfile(os.path.join(baiPath, 'lldb.py')):
815 lldbPath = baiPath
Greg Claytond9846b02011-02-14 21:17:06 +0000816 elif os.path.isfile(os.path.join(baiPath2, 'lldb.py')):
817 lldbPath = baiPath2
Johnny Chen9707bb62010-06-25 21:14:08 +0000818
819 if not lldbPath:
Johnny Chenc202c462010-09-15 18:11:19 +0000820 print 'This script requires lldb.py to be in either ' + dbgPath + ',',
821 print relPath + ', or ' + baiPath
Johnny Chen9707bb62010-06-25 21:14:08 +0000822 sys.exit(-1)
823
Johnny Chenaf149a02010-09-16 17:11:30 +0000824 # This is to locate the lldb.py module. Insert it right after sys.path[0].
825 sys.path[1:1] = [lldbPath]
Johnny Chen50bc6382011-01-29 01:16:52 +0000826 if dumpSysPath:
827 print "sys.path:", sys.path
Johnny Chen9707bb62010-06-25 21:14:08 +0000828
Johnny Chen9707bb62010-06-25 21:14:08 +0000829
Johnny Chencd0279d2010-09-20 18:07:50 +0000830def doDelay(delta):
831 """Delaying startup for delta-seconds to facilitate debugger attachment."""
832 def alarm_handler(*args):
833 raise Exception("timeout")
834
835 signal.signal(signal.SIGALRM, alarm_handler)
836 signal.alarm(delta)
837 sys.stdout.write("pid=%d\n" % os.getpid())
838 sys.stdout.write("Enter RET to proceed (or timeout after %d seconds):" %
839 delta)
840 sys.stdout.flush()
841 try:
842 text = sys.stdin.readline()
843 except:
844 text = ""
845 signal.alarm(0)
846 sys.stdout.write("proceeding...\n")
847 pass
848
849
Johnny Chen9707bb62010-06-25 21:14:08 +0000850def visit(prefix, dir, names):
851 """Visitor function for os.path.walk(path, visit, arg)."""
852
853 global suite
Johnny Chen7c52ff12010-09-27 23:29:54 +0000854 global regexp
Johnny Chenc5fa0052011-07-29 22:54:56 +0000855 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000856 global fs4all
Johnny Chene9eae812012-01-18 05:15:00 +0000857 global excluded
858
859 if set(dir.split(os.sep)).intersection(excluded):
860 #print "Detected an excluded dir component: %s" % dir
861 return
Johnny Chen9707bb62010-06-25 21:14:08 +0000862
863 for name in names:
864 if os.path.isdir(os.path.join(dir, name)):
865 continue
866
867 if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
Johnny Chen7c52ff12010-09-27 23:29:54 +0000868 # Try to match the regexp pattern, if specified.
869 if regexp:
870 import re
871 if re.search(regexp, name):
872 #print "Filename: '%s' matches pattern: '%s'" % (name, regexp)
873 pass
874 else:
875 #print "Filename: '%s' does not match pattern: '%s'" % (name, regexp)
876 continue
877
Johnny Chen953864a2010-10-12 21:35:54 +0000878 # We found a match for our test. Add it to the suite.
Johnny Chen79723352010-10-12 15:53:22 +0000879
880 # Update the sys.path first.
Johnny Chena85d7ee2010-06-26 00:19:32 +0000881 if not sys.path.count(dir):
Johnny Chen548aefd2010-10-11 22:25:46 +0000882 sys.path.insert(0, dir)
Johnny Chen9707bb62010-06-25 21:14:08 +0000883 base = os.path.splitext(name)[0]
Johnny Chenb62436b2010-10-06 20:40:56 +0000884
885 # Thoroughly check the filterspec against the base module and admit
886 # the (base, filterspec) combination only when it makes sense.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000887 filterspec = None
888 for filterspec in filters:
Johnny Chenb62436b2010-10-06 20:40:56 +0000889 # Optimistically set the flag to True.
890 filtered = True
891 module = __import__(base)
892 parts = filterspec.split('.')
893 obj = module
894 for part in parts:
895 try:
896 parent, obj = obj, getattr(obj, part)
897 except AttributeError:
898 # The filterspec has failed.
899 filtered = False
900 break
Johnny Chenc5fa0052011-07-29 22:54:56 +0000901
Johnny Chendb4be602011-08-12 23:55:07 +0000902 # If filtered, we have a good filterspec. Add it.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000903 if filtered:
Johnny Chendb4be602011-08-12 23:55:07 +0000904 #print "adding filter spec %s to module %s" % (filterspec, module)
905 suite.addTests(
906 unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
907 continue
Johnny Chenc5fa0052011-07-29 22:54:56 +0000908
909 # Forgo this module if the (base, filterspec) combo is invalid
910 # and no '-g' option is specified
911 if filters and fs4all and not filtered:
912 continue
Johnny Chenb62436b2010-10-06 20:40:56 +0000913
Johnny Chendb4be602011-08-12 23:55:07 +0000914 # Add either the filtered test case(s) (which is done before) or the entire test class.
915 if not filterspec or not filtered:
Johnny Chenb62436b2010-10-06 20:40:56 +0000916 # A simple case of just the module name. Also the failover case
917 # from the filterspec branch when the (base, filterspec) combo
918 # doesn't make sense.
919 suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
Johnny Chen9707bb62010-06-25 21:14:08 +0000920
921
Johnny Chencd0279d2010-09-20 18:07:50 +0000922def lldbLoggings():
923 """Check and do lldb loggings if necessary."""
924
925 # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
926 # defined. Use ${LLDB_LOG} to specify the log file.
927 ci = lldb.DBG.GetCommandInterpreter()
928 res = lldb.SBCommandReturnObject()
929 if ("LLDB_LOG" in os.environ):
930 if ("LLDB_LOG_OPTION" in os.environ):
931 lldb_log_option = os.environ["LLDB_LOG_OPTION"]
932 else:
Johnny Chen8fd886c2010-12-08 01:25:21 +0000933 lldb_log_option = "event process expr state api"
Johnny Chencd0279d2010-09-20 18:07:50 +0000934 ci.HandleCommand(
Greg Clayton940b1032011-02-23 00:35:02 +0000935 "log enable -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option,
Johnny Chencd0279d2010-09-20 18:07:50 +0000936 res)
937 if not res.Succeeded():
938 raise Exception('log enable failed (check LLDB_LOG env variable.')
939 # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
940 # Use ${GDB_REMOTE_LOG} to specify the log file.
941 if ("GDB_REMOTE_LOG" in os.environ):
942 if ("GDB_REMOTE_LOG_OPTION" in os.environ):
943 gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
944 else:
Johnny Chen7ab8c852010-12-02 18:35:13 +0000945 gdb_remote_log_option = "packets process"
Johnny Chencd0279d2010-09-20 18:07:50 +0000946 ci.HandleCommand(
Johnny Chenc935a892011-06-21 19:25:45 +0000947 "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
Johnny Chencd0279d2010-09-20 18:07:50 +0000948 + gdb_remote_log_option,
949 res)
950 if not res.Succeeded():
951 raise Exception('log enable failed (check GDB_REMOTE_LOG env variable.')
952
Johnny Chen067022b2011-01-19 19:31:46 +0000953def getMyCommandLine():
Johnny Chen067022b2011-01-19 19:31:46 +0000954 ps = subprocess.Popen(['ps', '-o', "command=CMD", str(os.getpid())], stdout=subprocess.PIPE).communicate()[0]
955 lines = ps.split('\n')
956 cmd_line = lines[1]
957 return cmd_line
Johnny Chencd0279d2010-09-20 18:07:50 +0000958
Johnny Chend96b5682010-11-05 17:30:53 +0000959# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +0000960# #
961# Execution of the test driver starts here #
962# #
Johnny Chend96b5682010-11-05 17:30:53 +0000963# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +0000964
Johnny Chen2891bb02011-09-16 01:04:26 +0000965def checkDsymForUUIDIsNotOn():
Johnny Chen6a4e0872011-09-16 17:50:44 +0000966 cmd = ["defaults", "read", "com.apple.DebugSymbols"]
967 pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
968 cmd_output = pipe.stdout.read()
Johnny Chen178c8d92011-09-16 18:03:19 +0000969 if cmd_output and "DBGFileMappedPaths = " in cmd_output:
Johnny Chen6a451482011-09-16 18:09:45 +0000970 print "%s =>" % ' '.join(cmd)
Johnny Chen6a4e0872011-09-16 17:50:44 +0000971 print cmd_output
Johnny Chen2891bb02011-09-16 01:04:26 +0000972 print "Disable automatic lookup and caching of dSYMs before running the test suite!"
973 print "Exiting..."
974 sys.exit(0)
975
976# On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
977# does not exist before proceeding to running the test suite.
978if sys.platform.startswith("darwin"):
979 checkDsymForUUIDIsNotOn()
980
Johnny Chen9707bb62010-06-25 21:14:08 +0000981#
Johnny Chenaf149a02010-09-16 17:11:30 +0000982# Start the actions by first parsing the options while setting up the test
983# directories, followed by setting up the search paths for lldb utilities;
984# then, we walk the directory trees and collect the tests into our test suite.
Johnny Chen9707bb62010-06-25 21:14:08 +0000985#
Johnny Chenaf149a02010-09-16 17:11:30 +0000986parseOptionsAndInitTestdirs()
Johnny Chen9707bb62010-06-25 21:14:08 +0000987setupSysPath()
Johnny Chen91960d32010-09-08 20:56:16 +0000988
989#
990# If '-d' is specified, do a delay of 10 seconds for the debugger to attach.
991#
992if delay:
Johnny Chencd0279d2010-09-20 18:07:50 +0000993 doDelay(10)
Johnny Chen91960d32010-09-08 20:56:16 +0000994
Johnny Chen49f2f7a2010-09-20 17:25:45 +0000995#
Johnny Chen41998192010-10-01 22:59:49 +0000996# If '-l' is specified, do not skip the long running tests.
Johnny Chen028d8eb2011-11-17 19:57:27 +0000997if not skip_long_running_test:
Johnny Chen41998192010-10-01 22:59:49 +0000998 os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
999
1000#
Johnny Chen79723352010-10-12 15:53:22 +00001001# Walk through the testdirs while collecting tests.
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001002#
Johnny Chen9707bb62010-06-25 21:14:08 +00001003for testdir in testdirs:
1004 os.path.walk(testdir, visit, 'Test')
1005
Johnny Chenb40056b2010-09-21 00:09:27 +00001006#
Johnny Chen9707bb62010-06-25 21:14:08 +00001007# Now that we have loaded all the test cases, run the whole test suite.
Johnny Chenb40056b2010-09-21 00:09:27 +00001008#
Johnny Chencd0279d2010-09-20 18:07:50 +00001009
Johnny Chen1bfbd412010-06-29 19:44:16 +00001010# For the time being, let's bracket the test runner within the
1011# lldb.SBDebugger.Initialize()/Terminate() pair.
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001012import lldb, atexit
Johnny Chen6b6f5ba2010-10-14 16:36:49 +00001013# Update: the act of importing lldb now executes lldb.SBDebugger.Initialize(),
1014# there's no need to call it a second time.
1015#lldb.SBDebugger.Initialize()
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001016atexit.register(lambda: lldb.SBDebugger.Terminate())
Johnny Chen1bfbd412010-06-29 19:44:16 +00001017
Johnny Chen909e5a62010-07-01 22:52:57 +00001018# Create a singleton SBDebugger in the lldb namespace.
1019lldb.DBG = lldb.SBDebugger.Create()
1020
Johnny Chen4f93bf12010-12-10 00:51:23 +00001021# Put the blacklist in the lldb namespace, to be used by lldb.TestBase.
Johnny Chen82e6b1e2010-12-01 22:47:54 +00001022lldb.blacklist = blacklist
1023
Johnny Chena3ed7d82012-04-06 00:56:05 +00001024# Put all these test decorators in the lldb namespace.
Johnny Chen4f93bf12010-12-10 00:51:23 +00001025lldb.dont_do_python_api_test = dont_do_python_api_test
1026lldb.just_do_python_api_test = just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +00001027lldb.just_do_benchmarks_test = just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +00001028lldb.dont_do_dsym_test = dont_do_dsym_test
1029lldb.dont_do_dwarf_test = dont_do_dwarf_test
Johnny Chen4f93bf12010-12-10 00:51:23 +00001030
Johnny Chen028d8eb2011-11-17 19:57:27 +00001031# Do we need to skip build and cleanup?
1032lldb.skip_build_and_cleanup = skip_build_and_cleanup
1033
Johnny Chen5f2ed172011-10-20 18:43:28 +00001034# Put bmExecutable, bmBreakpointSpec, and bmIterationCount into the lldb namespace, too.
Johnny Chene00c9302011-10-10 22:03:44 +00001035lldb.bmExecutable = bmExecutable
1036lldb.bmBreakpointSpec = bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +00001037lldb.bmIterationCount = bmIterationCount
Johnny Chene00c9302011-10-10 22:03:44 +00001038
Johnny Chen38f823c2011-10-11 01:30:27 +00001039# And don't forget the runHooks!
1040lldb.runHooks = runHooks
1041
Johnny Chencd0279d2010-09-20 18:07:50 +00001042# Turn on lldb loggings if necessary.
1043lldbLoggings()
Johnny Chen909e5a62010-07-01 22:52:57 +00001044
Johnny Chen7987ac92010-08-09 20:40:52 +00001045# Install the control-c handler.
1046unittest2.signals.installHandler()
1047
Johnny Chen125fc2b2010-10-21 16:55:35 +00001048# If sdir_name is not specified through the '-s sdir_name' option, get a
1049# timestamp string and export it as LLDB_SESSION_DIR environment var. This will
1050# be used when/if we want to dump the session info of individual test cases
1051# later on.
Johnny Chence681462010-10-19 00:25:01 +00001052#
1053# See also TestBase.dumpSessionInfo() in lldbtest.py.
Johnny Chen125fc2b2010-10-21 16:55:35 +00001054if not sdir_name:
1055 import datetime
Johnny Chen41fae812010-10-29 22:26:38 +00001056 # The windows platforms don't like ':' in the pathname.
Johnny Chen76bd0102010-10-28 16:32:13 +00001057 timestamp = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
Johnny Chen125fc2b2010-10-21 16:55:35 +00001058 sdir_name = timestamp
Peter Collingbourne132476f2011-06-20 23:55:53 +00001059os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), sdir_name)
Johnny Chen067022b2011-01-19 19:31:46 +00001060
Johnny Chenfe5f1ed2011-10-21 18:33:27 +00001061if not noHeaders:
1062 sys.stderr.write("\nSession logs for test failures/errors/unexpected successes"
1063 " will go into directory '%s'\n" % sdir_name)
1064 sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
Johnny Chence681462010-10-19 00:25:01 +00001065
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001066if not os.path.isdir(sdir_name):
1067 os.mkdir(sdir_name)
1068fname = os.path.join(sdir_name, "svn-info")
1069with open(fname, "w") as f:
1070 print >> f, svn_info
1071 print >> f, "Command invoked: %s\n" % getMyCommandLine()
1072
Johnny Chenb40056b2010-09-21 00:09:27 +00001073#
Johnny Chen0f907b82012-01-31 00:38:03 +00001074# If we have environment variables to unset, do it here before we invoke the test runner.
1075#
1076for env_var in unsets :
1077 if env_var in os.environ:
1078 # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
Johnny Chen6346a292012-01-31 00:48:02 +00001079 # is automatically translated into a corresponding call to unsetenv().
Johnny Chen0f907b82012-01-31 00:38:03 +00001080 del os.environ[env_var]
1081 #os.unsetenv(env_var)
1082
1083#
Johnny Chenb40056b2010-09-21 00:09:27 +00001084# Invoke the default TextTestRunner to run the test suite, possibly iterating
1085# over different configurations.
1086#
1087
Johnny Chenb40056b2010-09-21 00:09:27 +00001088iterArchs = False
Johnny Chenf032d902010-09-21 00:16:09 +00001089iterCompilers = False
Johnny Chenb40056b2010-09-21 00:09:27 +00001090
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001091if not archs and "archs" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001092 archs = config["archs"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001093
1094if isinstance(archs, list) and len(archs) >= 1:
1095 iterArchs = True
1096
1097if not compilers and "compilers" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001098 compilers = config["compilers"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001099
Johnny Chen92693b52012-03-09 02:11:37 +00001100#
1101# Add some intervention here to sanity check that the compilers requested are sane.
1102# If found not to be an executable program, the invalid one is dropped from the list.
1103for i in range(len(compilers)):
1104 c = compilers[i]
1105 if which(c):
1106 continue
1107 else:
1108 if sys.platform.startswith("darwin"):
1109 pipe = subprocess.Popen(['xcrun', '-find', c], stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1110 cmd_output = pipe.stdout.read()
1111 if cmd_output:
1112 if "not found" in cmd_output:
1113 print "dropping %s from the compilers used" % c
1114 compilers.remove(i)
1115 else:
1116 compilers[i] = cmd_output.split('\n')[0]
1117 print "'xcrun -find %s' returning %s" % (c, compilers[i])
1118
1119print "compilers=%s" % str(compilers)
1120
1121if not compilers or len(compilers) == 0:
1122 print "No eligible compiler found, exiting."
1123 sys.exit(1)
1124
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001125if isinstance(compilers, list) and len(compilers) >= 1:
1126 iterCompilers = True
Johnny Chenb40056b2010-09-21 00:09:27 +00001127
Johnny Chen953864a2010-10-12 21:35:54 +00001128# Make a shallow copy of sys.path, we need to manipulate the search paths later.
1129# This is only necessary if we are relocated and with different configurations.
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001130if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001131 old_sys_path = sys.path[:]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001132# If we iterate on archs or compilers, there is a chance we want to split stderr/stdout.
1133if iterArchs or iterCompilers:
Johnny Chen953864a2010-10-12 21:35:54 +00001134 old_stderr = sys.stderr
1135 old_stdout = sys.stdout
1136 new_stderr = None
1137 new_stdout = None
1138
Johnny Chend96b5682010-11-05 17:30:53 +00001139# Iterating over all possible architecture and compiler combinations.
Johnny Chenb40056b2010-09-21 00:09:27 +00001140for ia in range(len(archs) if iterArchs else 1):
1141 archConfig = ""
1142 if iterArchs:
Johnny Chen18a921f2010-09-30 17:11:58 +00001143 os.environ["ARCH"] = archs[ia]
Johnny Chenb40056b2010-09-21 00:09:27 +00001144 archConfig = "arch=%s" % archs[ia]
1145 for ic in range(len(compilers) if iterCompilers else 1):
1146 if iterCompilers:
Johnny Chen18a921f2010-09-30 17:11:58 +00001147 os.environ["CC"] = compilers[ic]
Johnny Chenb40056b2010-09-21 00:09:27 +00001148 configString = "%s compiler=%s" % (archConfig, compilers[ic])
1149 else:
1150 configString = archConfig
1151
Johnny Chenb40056b2010-09-21 00:09:27 +00001152 if iterArchs or iterCompilers:
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001153 # Translate ' ' to '-' for pathname component.
1154 from string import maketrans
1155 tbl = maketrans(' ', '-')
1156 configPostfix = configString.translate(tbl)
1157
1158 # Check whether we need to split stderr/stdout into configuration
1159 # specific files.
1160 if old_stderr.name != '<stderr>' and config.get('split_stderr'):
1161 if new_stderr:
1162 new_stderr.close()
1163 new_stderr = open("%s.%s" % (old_stderr.name, configPostfix), "w")
1164 sys.stderr = new_stderr
1165 if old_stdout.name != '<stdout>' and config.get('split_stdout'):
1166 if new_stdout:
1167 new_stdout.close()
1168 new_stdout = open("%s.%s" % (old_stdout.name, configPostfix), "w")
1169 sys.stdout = new_stdout
1170
Johnny Chen953864a2010-10-12 21:35:54 +00001171 # If we specified a relocated directory to run the test suite, do
1172 # the extra housekeeping to copy the testdirs to a configStringified
1173 # directory and to update sys.path before invoking the test runner.
1174 # The purpose is to separate the configuration-specific directories
1175 # from each other.
1176 if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001177 from shutil import copytree, ignore_patterns
1178
Johnny Chen953864a2010-10-12 21:35:54 +00001179 newrdir = "%s.%s" % (rdir, configPostfix)
1180
1181 # Copy the tree to a new directory with postfix name configPostfix.
1182 copytree(rdir, newrdir, ignore=ignore_patterns('*.pyc', '*.o', '*.d'))
1183
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001184 # Update the LLDB_TEST environment variable to reflect new top
Johnny Chen953864a2010-10-12 21:35:54 +00001185 # level test directory.
1186 #
1187 # See also lldbtest.TestBase.setUpClass(cls).
1188 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
1189 os.environ["LLDB_TEST"] = os.path.join(newrdir, 'test')
1190 else:
1191 os.environ["LLDB_TEST"] = newrdir
1192
1193 # And update the Python search paths for modules.
1194 sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
1195
1196 # Output the configuration.
Johnny Chenb40056b2010-09-21 00:09:27 +00001197 sys.stderr.write("\nConfiguration: " + configString + "\n")
Johnny Chen953864a2010-10-12 21:35:54 +00001198
1199 #print "sys.stderr name is", sys.stderr.name
1200 #print "sys.stdout name is", sys.stdout.name
1201
1202 # First, write out the number of collected test cases.
Johnny Chen08967192011-11-18 00:19:29 +00001203 sys.stderr.write(separator + "\n")
1204 sys.stderr.write("Collected %d test%s\n\n"
1205 % (suite.countTestCases(),
1206 suite.countTestCases() != 1 and "s" or ""))
Johnny Chen953864a2010-10-12 21:35:54 +00001207
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001208 class LLDBTestResult(unittest2.TextTestResult):
1209 """
Johnny Chen26be4532010-11-09 23:56:14 +00001210 Enforce a singleton pattern to allow introspection of test progress.
1211
1212 Overwrite addError(), addFailure(), and addExpectedFailure() methods
1213 to enable each test instance to track its failure/error status. It
1214 is used in the LLDB test framework to emit detailed trace messages
1215 to a log file for easier human inspection of test failres/errors.
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001216 """
1217 __singleton__ = None
Johnny Chen360dd372010-11-29 17:50:10 +00001218 __ignore_singleton__ = False
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001219
1220 def __init__(self, *args):
Johnny Chen360dd372010-11-29 17:50:10 +00001221 if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
Johnny Chend2acdb32010-11-16 22:42:58 +00001222 raise Exception("LLDBTestResult instantiated more than once")
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001223 super(LLDBTestResult, self).__init__(*args)
1224 LLDBTestResult.__singleton__ = self
1225 # Now put this singleton into the lldb module namespace.
1226 lldb.test_result = self
Johnny Chen810042e2011-01-05 20:24:11 +00001227 # Computes the format string for displaying the counter.
1228 global suite
1229 counterWidth = len(str(suite.countTestCases()))
1230 self.fmt = "%" + str(counterWidth) + "d: "
Johnny Chenc87fd492011-01-05 22:50:11 +00001231 self.indentation = ' ' * (counterWidth + 2)
Johnny Chen810042e2011-01-05 20:24:11 +00001232 # This counts from 1 .. suite.countTestCases().
1233 self.counter = 0
1234
Johnny Chenc87fd492011-01-05 22:50:11 +00001235 def getDescription(self, test):
1236 doc_first_line = test.shortDescription()
1237 if self.descriptions and doc_first_line:
1238 return '\n'.join((str(test), self.indentation + doc_first_line))
1239 else:
1240 return str(test)
1241
Johnny Chen810042e2011-01-05 20:24:11 +00001242 def startTest(self, test):
1243 self.counter += 1
1244 if self.showAll:
1245 self.stream.write(self.fmt % self.counter)
1246 super(LLDBTestResult, self).startTest(test)
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001247
Johnny Chen08967192011-11-18 00:19:29 +00001248 def stopTest(self, test):
1249 """Called when the given test has been run"""
1250 if progress_bar:
1251 sys.__stdout__.write('.')
1252 sys.__stdout__.flush()
1253 if self.counter == suite.countTestCases():
1254 sys.__stdout__.write('\n')
1255
1256 super(LLDBTestResult, self).stopTest(test)
1257
Johnny Chence681462010-10-19 00:25:01 +00001258 def addError(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001259 global sdir_has_content
1260 sdir_has_content = True
Johnny Chence681462010-10-19 00:25:01 +00001261 super(LLDBTestResult, self).addError(test, err)
1262 method = getattr(test, "markError", None)
1263 if method:
1264 method()
1265
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001266 def addFailure(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001267 global sdir_has_content
1268 sdir_has_content = True
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001269 super(LLDBTestResult, self).addFailure(test, err)
1270 method = getattr(test, "markFailure", None)
1271 if method:
1272 method()
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001273
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001274 def addExpectedFailure(self, test, err):
1275 global sdir_has_content
1276 sdir_has_content = True
1277 super(LLDBTestResult, self).addExpectedFailure(test, err)
1278 method = getattr(test, "markExpectedFailure", None)
1279 if method:
1280 method()
1281
Johnny Chenf5b89092011-08-15 23:09:08 +00001282 def addSkip(self, test, reason):
1283 global sdir_has_content
1284 sdir_has_content = True
1285 super(LLDBTestResult, self).addSkip(test, reason)
1286 method = getattr(test, "markSkippedTest", None)
1287 if method:
1288 method()
1289
Johnny Chenab2f0662011-05-06 20:30:22 +00001290 def addUnexpectedSuccess(self, test):
1291 global sdir_has_content
1292 sdir_has_content = True
1293 super(LLDBTestResult, self).addUnexpectedSuccess(test)
1294 method = getattr(test, "markUnexpectedSuccess", None)
1295 if method:
1296 method()
1297
Johnny Chen26be4532010-11-09 23:56:14 +00001298 # Invoke the test runner.
Johnny Chend2acdb32010-11-16 22:42:58 +00001299 if count == 1:
Johnny Chen7d6d8442010-12-03 19:59:35 +00001300 result = unittest2.TextTestRunner(stream=sys.stderr,
1301 verbosity=verbose,
1302 failfast=failfast,
Johnny Chend2acdb32010-11-16 22:42:58 +00001303 resultclass=LLDBTestResult).run(suite)
1304 else:
Johnny Chend6e7ca22010-11-29 17:52:43 +00001305 # We are invoking the same test suite more than once. In this case,
1306 # mark __ignore_singleton__ flag as True so the signleton pattern is
1307 # not enforced.
Johnny Chen360dd372010-11-29 17:50:10 +00001308 LLDBTestResult.__ignore_singleton__ = True
Johnny Chend2acdb32010-11-16 22:42:58 +00001309 for i in range(count):
Johnny Chen7d6d8442010-12-03 19:59:35 +00001310 result = unittest2.TextTestRunner(stream=sys.stderr,
1311 verbosity=verbose,
1312 failfast=failfast,
Johnny Chen360dd372010-11-29 17:50:10 +00001313 resultclass=LLDBTestResult).run(suite)
Johnny Chenb40056b2010-09-21 00:09:27 +00001314
Johnny Chen1bfbd412010-06-29 19:44:16 +00001315
Johnny Chen63c2cba2010-10-29 22:20:36 +00001316if sdir_has_content:
Johnny Chenab2f0662011-05-06 20:30:22 +00001317 sys.stderr.write("Session logs for test failures/errors/unexpected successes"
1318 " can be found in directory '%s'\n" % sdir_name)
Johnny Chen63c2cba2010-10-29 22:20:36 +00001319
Johnny Chencd0279d2010-09-20 18:07:50 +00001320# Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1321# This should not be necessary now.
Johnny Chen83f6e512010-08-13 22:58:44 +00001322if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
Johnny Chen83f6e512010-08-13 22:58:44 +00001323 print "Terminating Test suite..."
1324 subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1325
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001326# Exiting.
1327sys.exit(not result.wasSuccessful)