blob: be548fb5b4c0a61e0c11ee0127e81239e1253dfc [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 = {}
Johnny Chenac97a6b2012-04-16 18:55:15 +000099# The pre_flight and post_flight functions come from reading a config file.
100pre_flight = None
101post_flight = None
Johnny Chenb40056b2010-09-21 00:09:27 +0000102
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000103# The 'archs' and 'compilers' can be specified via either command line or configFile,
104# with the command line overriding the configFile. When specified, they should be
105# of the list type. For example, "-A x86_64^i386" => archs=['x86_64', 'i386'] and
106# "-C gcc^clang" => compilers=['gcc', 'clang'].
Johnny Chenbb4800e2012-04-12 00:55:57 +0000107archs = ['x86_64', 'i386']
Johnny Chen92693b52012-03-09 02:11:37 +0000108compilers = ['clang']
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000109
Johnny Chen1abe4c02012-03-20 00:33:51 +0000110# The arch might dictate some specific CFLAGS to be passed to the toolchain to build
111# the inferior programs. The global variable cflags_extras provides a hook to do
112# just that.
113cflags_extras = ''
114
Johnny Chen91960d32010-09-08 20:56:16 +0000115# Delay startup in order for the debugger to attach.
116delay = False
117
Johnny Chend5362332011-01-29 01:21:04 +0000118# Dump the Python sys.path variable. Use '-D' to dump sys.path.
Johnny Chen50bc6382011-01-29 01:16:52 +0000119dumpSysPath = False
120
Johnny Chene00c9302011-10-10 22:03:44 +0000121# Full path of the benchmark executable, as specified by the '-e' option.
122bmExecutable = None
123# The breakpoint specification of bmExecutable, as specified by the '-x' option.
124bmBreakpointSpec = None
Johnny Chen5f2ed172011-10-20 18:43:28 +0000125# The benchamrk iteration count, as specified by the '-y' option.
126bmIterationCount = -1
Johnny Chene00c9302011-10-10 22:03:44 +0000127
Johnny Chene9eae812012-01-18 05:15:00 +0000128# By default, don't exclude any directories. Use '-X' to add one excluded directory.
129excluded = set(['.svn', '.git'])
130
Johnny Chen7d6d8442010-12-03 19:59:35 +0000131# By default, failfast is False. Use '-F' to overwrite it.
132failfast = False
133
Johnny Chenc5fa0052011-07-29 22:54:56 +0000134# The filters (testclass.testmethod) used to admit tests into our test suite.
135filters = []
Johnny Chenb62436b2010-10-06 20:40:56 +0000136
Johnny Chen38f823c2011-10-11 01:30:27 +0000137# The runhooks is a list of lldb commands specifically for the debugger.
138# Use '-k' to specify a runhook.
139runHooks = []
140
Johnny Chena224cd12010-11-08 01:21:03 +0000141# If '-g' is specified, the filterspec is not exclusive. If a test module does
142# not contain testclass.testmethod which matches the filterspec, the whole test
143# module is still admitted into our test suite. fs4all flag defaults to True.
144fs4all = True
Johnny Chenb62436b2010-10-06 20:40:56 +0000145
Johnny Chenaf149a02010-09-16 17:11:30 +0000146# Ignore the build search path relative to this script to locate the lldb.py module.
147ignore = False
148
Johnny Chen028d8eb2011-11-17 19:57:27 +0000149# By default, we do not skip build and cleanup. Use '-S' option to override.
150skip_build_and_cleanup = False
151
Johnny Chen548aefd2010-10-11 22:25:46 +0000152# By default, we skip long running test case. Use '-l' option to override.
Johnny Chen028d8eb2011-11-17 19:57:27 +0000153skip_long_running_test = True
Johnny Chen41998192010-10-01 22:59:49 +0000154
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000155# By default, we print the build dir, lldb version, and svn info. Use '-n' option to
156# turn it off.
157noHeaders = False
158
Johnny Chen7c52ff12010-09-27 23:29:54 +0000159# The regular expression pattern to match against eligible filenames as our test cases.
160regexp = None
161
Johnny Chen548aefd2010-10-11 22:25:46 +0000162# By default, tests are executed in place and cleanups are performed afterwards.
163# Use '-r dir' option to relocate the tests and their intermediate files to a
164# different directory and to forgo any cleanups. The directory specified must
165# not exist yet.
166rdir = None
167
Johnny Chen125fc2b2010-10-21 16:55:35 +0000168# By default, recorded session info for errored/failed test are dumped into its
169# own file under a session directory named after the timestamp of the test suite
170# run. Use '-s session-dir-name' to specify a specific dir name.
171sdir_name = None
172
Johnny Chen63c2cba2010-10-29 22:20:36 +0000173# Set this flag if there is any session info dumped during the test run.
174sdir_has_content = False
175
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000176# svn_info stores the output from 'svn info lldb.base.dir'.
177svn_info = ''
178
Johnny Chen0f907b82012-01-31 00:38:03 +0000179# The environment variables to unset before running the test cases.
180unsets = []
181
Johnny Chen9707bb62010-06-25 21:14:08 +0000182# Default verbosity is 0.
183verbose = 0
184
Johnny Chen08967192011-11-18 00:19:29 +0000185# Set to True only if verbose is 0 and LLDB trace mode is off.
186progress_bar = False
187
Peter Collingbourne61aca482011-06-20 19:06:29 +0000188# By default, search from the script directory.
189testdirs = [ sys.path[0] ]
Johnny Chen9707bb62010-06-25 21:14:08 +0000190
Johnny Chen877c7e42010-08-07 00:16:07 +0000191# Separator string.
192separator = '-' * 70
193
Johnny Chen9707bb62010-06-25 21:14:08 +0000194
195def usage():
196 print """
197Usage: dotest.py [option] [args]
198where options:
Jim Ingham4f347cb2011-04-13 21:11:41 +0000199-h : print this help message and exit. Add '-v' for more detailed help.
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000200-A : specify the architecture(s) to launch for the inferior process
201 -A i386 => launch inferior with i386 architecture
202 -A x86_64^i386 => launch inferior with x86_64 and i386 architectures
203-C : specify the compiler(s) used to build the inferior executable
204 -C clang => build debuggee using clang compiler
Johnny Chence9cf4e2012-01-17 01:26:06 +0000205 -C /my/full/path/to/clang => specify a full path to the clang binary
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000206 -C clang^gcc => build debuggee using clang and gcc compilers
Johnny Chen50bc6382011-01-29 01:16:52 +0000207-D : dump the Python sys.path variable
Johnny Chen1abe4c02012-03-20 00:33:51 +0000208-E : specify the extra flags to be passed to the toolchain when building the
209 inferior programs to be debugged
210 suggestions: do not lump the -A arch1^arch2 together such that the -E
211 option applies to only one of the architectures
Johnny Chena3ed7d82012-04-06 00:56:05 +0000212-N : don't do test cases marked with the @dsym decorator by passing 'dsym' as the option arg, or
213 don't do test cases marked with the @dwarf decorator by passing 'dwarf' as the option arg
Johnny Chen4f93bf12010-12-10 00:51:23 +0000214-a : don't do lldb Python API tests
215 use @python_api_test to decorate a test case as lldb Python API test
Johnny Chen3ebdacc2010-12-10 18:52:10 +0000216+a : just do lldb Python API tests
Johnny Chencc659ad2010-12-10 19:02:23 +0000217 do not specify both '-a' and '+a' at the same time
Johnny Chen82ccf402011-07-30 01:39:58 +0000218+b : just do benchmark tests
219 use @benchmark_test to decorate a test case as such
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000220-b : read a blacklist file specified after this option
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000221-c : read a config file specified after this option
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000222 the architectures and compilers (note the plurals) specified via '-A' and '-C'
223 will override those specified via a config file
Johnny Chenb40056b2010-09-21 00:09:27 +0000224 (see also lldb-trunk/example/test/usage-config)
Johnny Chen91960d32010-09-08 20:56:16 +0000225-d : delay startup for 10 seconds (in order for the debugger to attach)
Johnny Chene00c9302011-10-10 22:03:44 +0000226-e : specify the full path of an executable used for benchmark purpose;
227 see also '-x', which provides the breakpoint sepcification
Johnny Chen7d6d8442010-12-03 19:59:35 +0000228-F : failfast, stop the test suite on the first error/failure
Johnny Chen46be75d2010-10-11 16:19:48 +0000229-f : specify a filter, which consists of the test class name, a dot, followed by
Johnny Chen1a6e92a2010-11-08 20:17:04 +0000230 the test method, to only admit such test into the test suite
Johnny Chenb62436b2010-10-06 20:40:56 +0000231 e.g., -f 'ClassTypesTestCase.test_with_dwarf_and_python_api'
Johnny Chena224cd12010-11-08 01:21:03 +0000232-g : if specified, the filterspec by -f is not exclusive, i.e., if a test module
233 does not match the filterspec (testclass.testmethod), the whole module is
234 still admitted to the test suite
Johnny Chenaf149a02010-09-16 17:11:30 +0000235-i : ignore (don't bailout) if 'lldb.py' module cannot be located in the build
236 tree relative to this script; use PYTHONPATH to locate the module
Johnny Chen38f823c2011-10-11 01:30:27 +0000237-k : specify a runhook, which is an lldb command to be executed by the debugger;
238 '-k' option can occur multiple times, the commands are executed one after the
239 other to bring the debugger to a desired state, so that, for example, further
240 benchmarking can be done
Johnny Chen41998192010-10-01 22:59:49 +0000241-l : don't skip long running test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000242-n : don't print the headers like build dir, lldb version, and svn info at all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000243-p : specify a regexp filename pattern for inclusion in the test suite
Johnny Chen548aefd2010-10-11 22:25:46 +0000244-r : specify a dir to relocate the tests and their intermediate files to;
245 the directory must not exist before running this test driver;
246 no cleanup of intermediate test files is performed in this case
Johnny Chen028d8eb2011-11-17 19:57:27 +0000247-S : skip the build and cleanup while running the test
248 use this option with care as you would need to build the inferior(s) by hand
249 and build the executable(s) with the correct name(s)
250 this can be used with '-# n' to stress test certain test cases for n number of
251 times
Johnny Chen125fc2b2010-10-21 16:55:35 +0000252-s : specify the name of the dir created to store the session files of tests
253 with errored or failed status; if not specified, the test driver uses the
254 timestamp as the session dir name
Johnny Chena2486f22011-04-21 20:48:32 +0000255-t : turn on tracing of lldb command and other detailed test executions
Johnny Chen0f907b82012-01-31 00:38:03 +0000256-u : specify an environment variable to unset before running the test cases
257 e.g., -u DYLD_INSERT_LIBRARIES -u MallocScribble'
Johnny Chena2486f22011-04-21 20:48:32 +0000258-v : do verbose mode of unittest framework (print out each test case invocation)
Johnny Chene9eae812012-01-18 05:15:00 +0000259-X : exclude a directory from consideration for test discovery
260 -X types => if 'types' appear in the pathname components of a potential testfile
261 it will be ignored
Johnny Chene00c9302011-10-10 22:03:44 +0000262-x : specify the breakpoint specification for the benchmark executable;
263 see also '-e', which provides the full path of the executable
Johnny Chen5f2ed172011-10-20 18:43:28 +0000264-y : specify the iteration count used to collect our benchmarks; an example is
265 the number of times to do 'thread step-over' to measure stepping speed
266 see also '-e' and '-x' options
Johnny Chene47649c2010-10-07 02:04:14 +0000267-w : insert some wait time (currently 0.5 sec) between consecutive test cases
Johnny Chend2acdb32010-11-16 22:42:58 +0000268-# : Repeat the test suite for a specified number of times
Johnny Chen9707bb62010-06-25 21:14:08 +0000269
270and:
Johnny Chen9656ab22010-10-22 19:00:18 +0000271args : specify a list of directory names to search for test modules named after
272 Test*.py (test discovery)
Peter Collingbourne5f2b5d62011-06-14 03:55:45 +0000273 if empty, search from the current working directory, instead
Jim Ingham4f347cb2011-04-13 21:11:41 +0000274"""
Johnny Chen58f93922010-06-29 23:10:39 +0000275
Jim Ingham4f347cb2011-04-13 21:11:41 +0000276 if verbose > 0:
277 print """
Johnny Chen9656ab22010-10-22 19:00:18 +0000278Examples:
279
Johnny Chena224cd12010-11-08 01:21:03 +0000280This is an example of using the -f option to pinpoint to a specfic test class
281and test method to be run:
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000282
Johnny Chena224cd12010-11-08 01:21:03 +0000283$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000284----------------------------------------------------------------------
285Collected 1 test
286
287test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
288Test 'frame variable this' when stopped on a class constructor. ... ok
289
290----------------------------------------------------------------------
291Ran 1 test in 1.396s
292
293OK
Johnny Chen9656ab22010-10-22 19:00:18 +0000294
295And this is an example of using the -p option to run a single file (the filename
296matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
297
298$ ./dotest.py -v -p ObjC
299----------------------------------------------------------------------
300Collected 4 tests
301
302test_break_with_dsym (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000303Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000304test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000305Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000306test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
307Lookup objective-c data types and evaluate expressions. ... ok
308test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
309Lookup objective-c data types and evaluate expressions. ... ok
310
311----------------------------------------------------------------------
312Ran 4 tests in 16.661s
313
314OK
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000315
Johnny Chen58f93922010-06-29 23:10:39 +0000316Running of this script also sets up the LLDB_TEST environment variable so that
Johnny Chenaf149a02010-09-16 17:11:30 +0000317individual test cases can locate their supporting files correctly. The script
318tries to set up Python's search paths for modules by looking at the build tree
Johnny Chena85859f2010-11-11 22:14:56 +0000319relative to this script. See also the '-i' option in the following example.
320
321Finally, this is an example of using the lldb.py module distributed/installed by
322Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
323option to add some delay between two tests. It uses ARCH=x86_64 to specify that
324as the architecture and CC=clang to specify the compiler used for the test run:
325
326$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
327
328Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
329----------------------------------------------------------------------
330Collected 2 tests
331
332test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
333Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
334test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
335Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
336
337----------------------------------------------------------------------
338Ran 2 tests in 5.659s
339
340OK
341
342The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
343notify the directory containing the session logs for test failures or errors.
344In case there is any test failure/error, a similar message is appended at the
345end of the stderr output for your convenience.
Johnny Chenfde69bc2010-09-14 22:01:40 +0000346
347Environment variables related to loggings:
348
349o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
350 with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
351
352o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
353 'process.gdb-remote' subsystem with a default option of 'packets' if
354 GDB_REMOTE_LOG_OPTION is not defined.
Johnny Chen9707bb62010-06-25 21:14:08 +0000355"""
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000356 sys.exit(0)
Johnny Chen9707bb62010-06-25 21:14:08 +0000357
358
Johnny Chenaf149a02010-09-16 17:11:30 +0000359def parseOptionsAndInitTestdirs():
360 """Initialize the list of directories containing our unittest scripts.
361
362 '-h/--help as the first option prints out usage info and exit the program.
363 """
364
Johnny Chen4f93bf12010-12-10 00:51:23 +0000365 global dont_do_python_api_test
366 global just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000367 global just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +0000368 global dont_do_dsym_test
369 global dont_do_dwarf_test
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000370 global blacklist
371 global blacklistConfig
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000372 global configFile
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000373 global archs
374 global compilers
Johnny Chend2acdb32010-11-16 22:42:58 +0000375 global count
Johnny Chenaf149a02010-09-16 17:11:30 +0000376 global delay
Johnny Chen50bc6382011-01-29 01:16:52 +0000377 global dumpSysPath
Johnny Chene00c9302011-10-10 22:03:44 +0000378 global bmExecutable
379 global bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000380 global bmIterationCount
Johnny Chen7d6d8442010-12-03 19:59:35 +0000381 global failfast
Johnny Chenc5fa0052011-07-29 22:54:56 +0000382 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000383 global fs4all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000384 global ignore
Johnny Chen08967192011-11-18 00:19:29 +0000385 global progress_bar
Johnny Chen38f823c2011-10-11 01:30:27 +0000386 global runHooks
Johnny Chen028d8eb2011-11-17 19:57:27 +0000387 global skip_build_and_cleanup
388 global skip_long_running_test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000389 global noHeaders
Johnny Chen7c52ff12010-09-27 23:29:54 +0000390 global regexp
Johnny Chen548aefd2010-10-11 22:25:46 +0000391 global rdir
Johnny Chen125fc2b2010-10-21 16:55:35 +0000392 global sdir_name
Johnny Chen0f907b82012-01-31 00:38:03 +0000393 global unsets
Johnny Chenaf149a02010-09-16 17:11:30 +0000394 global verbose
395 global testdirs
396
Jim Ingham4f347cb2011-04-13 21:11:41 +0000397 do_help = False
398
Johnny Chenaf149a02010-09-16 17:11:30 +0000399 if len(sys.argv) == 1:
400 return
401
402 # Process possible trace and/or verbose flag, among other things.
403 index = 1
Johnny Chence2212c2010-10-07 15:41:55 +0000404 while index < len(sys.argv):
Johnny Chen4f93bf12010-12-10 00:51:23 +0000405 if sys.argv[index].startswith('-') or sys.argv[index].startswith('+'):
406 # We should continue processing...
407 pass
408 else:
Johnny Chenaf149a02010-09-16 17:11:30 +0000409 # End of option processing.
410 break
411
412 if sys.argv[index].find('-h') != -1:
Jim Ingham4f347cb2011-04-13 21:11:41 +0000413 index += 1
414 do_help = True
Johnny Chen012cba12011-01-26 19:07:42 +0000415 elif sys.argv[index].startswith('-A'):
416 # Increment by 1 to fetch the ARCH spec.
417 index += 1
418 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
419 usage()
Johnny Cheneee9b862011-04-26 20:45:00 +0000420 archs = sys.argv[index].split('^')
Johnny Chen012cba12011-01-26 19:07:42 +0000421 index += 1
422 elif sys.argv[index].startswith('-C'):
423 # Increment by 1 to fetch the CC spec.
424 index += 1
425 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
426 usage()
Johnny Cheneee9b862011-04-26 20:45:00 +0000427 compilers = sys.argv[index].split('^')
Johnny Chen012cba12011-01-26 19:07:42 +0000428 index += 1
Johnny Chen50bc6382011-01-29 01:16:52 +0000429 elif sys.argv[index].startswith('-D'):
430 dumpSysPath = True
431 index += 1
Johnny Chen1abe4c02012-03-20 00:33:51 +0000432 elif sys.argv[index].startswith('-E'):
433 # Increment by 1 to fetch the CFLAGS_EXTRAS spec.
434 index += 1
435 if index >= len(sys.argv):
436 usage()
437 cflags_extras = sys.argv[index]
438 os.environ["CFLAGS_EXTRAS"] = cflags_extras
439 index += 1
Johnny Chena3ed7d82012-04-06 00:56:05 +0000440 elif sys.argv[index].startswith('-N'):
441 # Increment by 1 to fetch 'dsym' or 'dwarf'.
442 index += 1
443 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
444 usage()
445 dont_do = sys.argv[index]
446 if dont_do.lower() == 'dsym':
447 dont_do_dsym_test = True
448 elif dont_do.lower() == 'dwarf':
449 dont_do_dwarf_test = True
450 else:
451 print "!!!"
452 print "Warning: -N only accepts either 'dsym' or 'dwarf' as the option arg; you passed in '%s'?" % dont_do
453 print "!!!"
454 index += 1
Johnny Chen4f93bf12010-12-10 00:51:23 +0000455 elif sys.argv[index].startswith('-a'):
456 dont_do_python_api_test = True
457 index += 1
458 elif sys.argv[index].startswith('+a'):
459 just_do_python_api_test = True
460 index += 1
Johnny Chen82ccf402011-07-30 01:39:58 +0000461 elif sys.argv[index].startswith('+b'):
462 just_do_benchmarks_test = True
463 index += 1
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000464 elif sys.argv[index].startswith('-b'):
465 # Increment by 1 to fetch the blacklist file name option argument.
466 index += 1
467 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
468 usage()
469 blacklistFile = sys.argv[index]
470 if not os.path.isfile(blacklistFile):
471 print "Blacklist file:", blacklistFile, "does not exist!"
472 usage()
473 index += 1
474 # Now read the blacklist contents and assign it to blacklist.
475 execfile(blacklistFile, globals(), blacklistConfig)
476 blacklist = blacklistConfig.get('blacklist')
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000477 elif sys.argv[index].startswith('-c'):
478 # Increment by 1 to fetch the config file name option argument.
479 index += 1
480 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
481 usage()
482 configFile = sys.argv[index]
483 if not os.path.isfile(configFile):
484 print "Config file:", configFile, "does not exist!"
485 usage()
486 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000487 elif sys.argv[index].startswith('-d'):
488 delay = True
489 index += 1
Johnny Chene00c9302011-10-10 22:03:44 +0000490 elif sys.argv[index].startswith('-e'):
491 # Increment by 1 to fetch the full path of the benchmark executable.
492 index += 1
493 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
494 usage()
495 bmExecutable = sys.argv[index]
496 if not is_exe(bmExecutable):
497 usage()
498 index += 1
Johnny Chen7d6d8442010-12-03 19:59:35 +0000499 elif sys.argv[index].startswith('-F'):
500 failfast = True
501 index += 1
Johnny Chenb62436b2010-10-06 20:40:56 +0000502 elif sys.argv[index].startswith('-f'):
503 # Increment by 1 to fetch the filter spec.
504 index += 1
505 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
506 usage()
Johnny Chenc5fa0052011-07-29 22:54:56 +0000507 filters.append(sys.argv[index])
Johnny Chenb62436b2010-10-06 20:40:56 +0000508 index += 1
509 elif sys.argv[index].startswith('-g'):
Johnny Chena224cd12010-11-08 01:21:03 +0000510 fs4all = False
Johnny Chenb62436b2010-10-06 20:40:56 +0000511 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000512 elif sys.argv[index].startswith('-i'):
513 ignore = True
514 index += 1
Johnny Chen38f823c2011-10-11 01:30:27 +0000515 elif sys.argv[index].startswith('-k'):
516 # Increment by 1 to fetch the runhook lldb command.
517 index += 1
518 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
519 usage()
520 runHooks.append(sys.argv[index])
521 index += 1
Johnny Chen41998192010-10-01 22:59:49 +0000522 elif sys.argv[index].startswith('-l'):
Johnny Chen028d8eb2011-11-17 19:57:27 +0000523 skip_long_running_test = False
Johnny Chen41998192010-10-01 22:59:49 +0000524 index += 1
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000525 elif sys.argv[index].startswith('-n'):
526 noHeaders = True
527 index += 1
Johnny Chen7c52ff12010-09-27 23:29:54 +0000528 elif sys.argv[index].startswith('-p'):
529 # Increment by 1 to fetch the reg exp pattern argument.
530 index += 1
531 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
532 usage()
533 regexp = sys.argv[index]
534 index += 1
Johnny Chen548aefd2010-10-11 22:25:46 +0000535 elif sys.argv[index].startswith('-r'):
536 # Increment by 1 to fetch the relocated directory argument.
537 index += 1
538 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
539 usage()
540 rdir = os.path.abspath(sys.argv[index])
541 if os.path.exists(rdir):
542 print "Relocated directory:", rdir, "must not exist!"
543 usage()
544 index += 1
Johnny Chen028d8eb2011-11-17 19:57:27 +0000545 elif sys.argv[index].startswith('-S'):
546 skip_build_and_cleanup = True
547 index += 1
Johnny Chen125fc2b2010-10-21 16:55:35 +0000548 elif sys.argv[index].startswith('-s'):
549 # Increment by 1 to fetch the session dir name.
550 index += 1
551 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
552 usage()
553 sdir_name = sys.argv[index]
554 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000555 elif sys.argv[index].startswith('-t'):
556 os.environ["LLDB_COMMAND_TRACE"] = "YES"
557 index += 1
Johnny Chen0f907b82012-01-31 00:38:03 +0000558 elif sys.argv[index].startswith('-u'):
559 # Increment by 1 to fetch the environment variable to unset.
560 index += 1
561 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
562 usage()
563 unsets.append(sys.argv[index])
564 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000565 elif sys.argv[index].startswith('-v'):
566 verbose = 2
567 index += 1
Johnny Chene47649c2010-10-07 02:04:14 +0000568 elif sys.argv[index].startswith('-w'):
569 os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] = 'YES'
570 index += 1
Johnny Chene9eae812012-01-18 05:15:00 +0000571 elif sys.argv[index].startswith('-X'):
572 # Increment by 1 to fetch an excluded directory.
573 index += 1
574 if index >= len(sys.argv):
575 usage()
576 excluded.add(sys.argv[index])
577 index += 1
Johnny Chene00c9302011-10-10 22:03:44 +0000578 elif sys.argv[index].startswith('-x'):
579 # Increment by 1 to fetch the breakpoint specification of the benchmark executable.
580 index += 1
Johnny Chen8a1b1222011-10-20 22:16:24 +0000581 if index >= len(sys.argv):
Johnny Chene00c9302011-10-10 22:03:44 +0000582 usage()
583 bmBreakpointSpec = sys.argv[index]
584 index += 1
Johnny Chen5f2ed172011-10-20 18:43:28 +0000585 elif sys.argv[index].startswith('-y'):
586 # Increment by 1 to fetch the the benchmark iteration count.
587 index += 1
588 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
589 usage()
590 bmIterationCount = int(sys.argv[index])
591 index += 1
Johnny Chend2acdb32010-11-16 22:42:58 +0000592 elif sys.argv[index].startswith('-#'):
593 # Increment by 1 to fetch the repeat count argument.
594 index += 1
595 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
596 usage()
597 count = int(sys.argv[index])
598 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000599 else:
600 print "Unknown option: ", sys.argv[index]
601 usage()
Johnny Chenaf149a02010-09-16 17:11:30 +0000602
Jim Ingham4f347cb2011-04-13 21:11:41 +0000603 if do_help == True:
604 usage()
605
Johnny Chencc659ad2010-12-10 19:02:23 +0000606 # Do not specify both '-a' and '+a' at the same time.
607 if dont_do_python_api_test and just_do_python_api_test:
608 usage()
609
Johnny Chen08967192011-11-18 00:19:29 +0000610 # The simple progress bar is turned on only if verbose == 0 and LLDB_COMMAND_TRACE is not 'YES'
611 if ("LLDB_COMMAND_TRACE" not in os.environ or os.environ["LLDB_COMMAND_TRACE"]!="YES") and verbose==0:
612 progress_bar = True
613
Johnny Chenaf149a02010-09-16 17:11:30 +0000614 # Gather all the dirs passed on the command line.
615 if len(sys.argv) > index:
616 testdirs = map(os.path.abspath, sys.argv[index:])
617
Johnny Chen548aefd2010-10-11 22:25:46 +0000618 # If '-r dir' is specified, the tests should be run under the relocated
619 # directory. Let's copy the testdirs over.
620 if rdir:
621 from shutil import copytree, ignore_patterns
622
623 tmpdirs = []
624 for srcdir in testdirs:
Johnny Chen1abe4c02012-03-20 00:33:51 +0000625 # For example, /Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/hello_watchpoint
626 # shall be split into ['/Volumes/data/lldb/svn/ToT/', 'functionalities/watchpoint/hello_watchpoint'].
627 # Utilize the relative path to the 'test' directory to make our destination dir path.
628 dstdir = os.path.join(rdir, srcdir.split("test"+os.sep)[1])
629 #print "(srcdir, dstdir)=(%s, %s)" % (srcdir, dstdir)
Johnny Chen548aefd2010-10-11 22:25:46 +0000630 # Don't copy the *.pyc and .svn stuffs.
631 copytree(srcdir, dstdir, ignore=ignore_patterns('*.pyc', '.svn'))
632 tmpdirs.append(dstdir)
633
634 # This will be our modified testdirs.
635 testdirs = tmpdirs
636
637 # With '-r dir' specified, there's no cleanup of intermediate test files.
638 os.environ["LLDB_DO_CLEANUP"] = 'NO'
639
640 # If testdirs is ['test'], the make directory has already been copied
641 # recursively and is contained within the rdir/test dir. For anything
642 # else, we would need to copy over the make directory and its contents,
643 # so that, os.listdir(rdir) looks like, for example:
644 #
645 # array_types conditional_break make
646 #
647 # where the make directory contains the Makefile.rules file.
648 if len(testdirs) != 1 or os.path.basename(testdirs[0]) != 'test':
649 # Don't copy the .svn stuffs.
650 copytree('make', os.path.join(rdir, 'make'),
651 ignore=ignore_patterns('.svn'))
652
653 #print "testdirs:", testdirs
654
Johnny Chenb40056b2010-09-21 00:09:27 +0000655 # Source the configFile if specified.
656 # The side effect, if any, will be felt from this point on. An example
657 # config file may be these simple two lines:
658 #
659 # sys.stderr = open("/tmp/lldbtest-stderr", "w")
660 # sys.stdout = open("/tmp/lldbtest-stdout", "w")
661 #
662 # which will reassign the two file objects to sys.stderr and sys.stdout,
663 # respectively.
664 #
665 # See also lldb-trunk/example/test/usage-config.
Johnny Chenac97a6b2012-04-16 18:55:15 +0000666 global config, pre_flight, post_flight
Johnny Chenb40056b2010-09-21 00:09:27 +0000667 if configFile:
668 # Pass config (a dictionary) as the locals namespace for side-effect.
669 execfile(configFile, globals(), config)
Johnny Chenac97a6b2012-04-16 18:55:15 +0000670 print "config:", config
671 if "pre_flight" in config:
672 pre_flight = config["pre_flight"]
673 if not callable(pre_flight):
674 print "fatal error: pre_flight is not callable, exiting."
675 sys.exit(1)
676 if "post_flight" in config:
677 post_flight = config["post_flight"]
678 if not callable(post_flight):
679 print "fatal error: post_flight is not callable, exiting."
680 sys.exit(1)
Johnny Chenb40056b2010-09-21 00:09:27 +0000681 #print "sys.stderr:", sys.stderr
682 #print "sys.stdout:", sys.stdout
683
Johnny Chenaf149a02010-09-16 17:11:30 +0000684
Johnny Chen9707bb62010-06-25 21:14:08 +0000685def setupSysPath():
Johnny Chen8a3c0432011-03-11 20:13:06 +0000686 """
687 Add LLDB.framework/Resources/Python to the search paths for modules.
688 As a side effect, we also discover the 'lldb' executable and export it here.
689 """
Johnny Chen9707bb62010-06-25 21:14:08 +0000690
Johnny Chen548aefd2010-10-11 22:25:46 +0000691 global rdir
692 global testdirs
Johnny Chen50bc6382011-01-29 01:16:52 +0000693 global dumpSysPath
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000694 global noHeaders
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000695 global svn_info
Johnny Chen548aefd2010-10-11 22:25:46 +0000696
Johnny Chen9707bb62010-06-25 21:14:08 +0000697 # Get the directory containing the current script.
Johnny Chen4d162e52011-08-12 18:54:11 +0000698 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 +0000699 scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
700 else:
701 scriptPath = sys.path[0]
Johnny Chena1affab2010-07-03 03:41:59 +0000702 if not scriptPath.endswith('test'):
Johnny Chen9707bb62010-06-25 21:14:08 +0000703 print "This script expects to reside in lldb's test directory."
704 sys.exit(-1)
705
Johnny Chen548aefd2010-10-11 22:25:46 +0000706 if rdir:
707 # Set up the LLDB_TEST environment variable appropriately, so that the
708 # individual tests can be located relatively.
709 #
710 # See also lldbtest.TestBase.setUpClass(cls).
711 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
712 os.environ["LLDB_TEST"] = os.path.join(rdir, 'test')
713 else:
714 os.environ["LLDB_TEST"] = rdir
715 else:
716 os.environ["LLDB_TEST"] = scriptPath
Peter Collingbournef6c3de82011-06-20 19:06:45 +0000717
718 # Set up the LLDB_SRC environment variable, so that the tests can locate
719 # the LLDB source code.
720 os.environ["LLDB_SRC"] = os.path.join(sys.path[0], os.pardir)
721
Johnny Chen9de4ede2010-08-31 17:42:54 +0000722 pluginPath = os.path.join(scriptPath, 'plugins')
Johnny Chen8a3c0432011-03-11 20:13:06 +0000723 pexpectPath = os.path.join(scriptPath, 'pexpect-2.4')
Johnny Chen58f93922010-06-29 23:10:39 +0000724
Johnny Chen8a3c0432011-03-11 20:13:06 +0000725 # Append script dir, plugin dir, and pexpect dir to the sys.path.
Johnny Chenaf149a02010-09-16 17:11:30 +0000726 sys.path.append(scriptPath)
727 sys.path.append(pluginPath)
Johnny Chen8a3c0432011-03-11 20:13:06 +0000728 sys.path.append(pexpectPath)
Johnny Chenaf149a02010-09-16 17:11:30 +0000729
Johnny Chen26901c82011-03-11 19:47:23 +0000730 # This is our base name component.
Johnny Chena1affab2010-07-03 03:41:59 +0000731 base = os.path.abspath(os.path.join(scriptPath, os.pardir))
Johnny Chen6a564a42011-02-15 18:50:19 +0000732
Johnny Chen26901c82011-03-11 19:47:23 +0000733 # These are for xcode build directories.
Johnny Chen6a564a42011-02-15 18:50:19 +0000734 xcode3_build_dir = ['build']
735 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
736 dbg = ['Debug']
737 rel = ['Release']
738 bai = ['BuildAndIntegration']
739 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
Johnny Chen26901c82011-03-11 19:47:23 +0000740
741 # Some of the tests can invoke the 'lldb' command directly.
742 # We'll try to locate the appropriate executable right here.
743
Johnny Chen6033bed2011-08-26 00:00:01 +0000744 # First, you can define an environment variable LLDB_EXEC specifying the
745 # full pathname of the lldb executable.
746 if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
747 lldbExec = os.environ["LLDB_EXEC"]
748 else:
749 lldbExec = None
750
Johnny Chen26901c82011-03-11 19:47:23 +0000751 executable = ['lldb']
752 dbgExec = os.path.join(base, *(xcode3_build_dir + dbg + executable))
753 dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
754 relExec = os.path.join(base, *(xcode3_build_dir + rel + executable))
755 relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
756 baiExec = os.path.join(base, *(xcode3_build_dir + bai + executable))
757 baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
758
Johnny Chen6033bed2011-08-26 00:00:01 +0000759 # The 'lldb' executable built here in the source tree.
760 lldbHere = None
Johnny Chen26901c82011-03-11 19:47:23 +0000761 if is_exe(dbgExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000762 lldbHere = dbgExec
Johnny Chen26901c82011-03-11 19:47:23 +0000763 elif is_exe(dbgExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000764 lldbHere = dbgExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000765 elif is_exe(relExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000766 lldbHere = relExec
Johnny Chen26901c82011-03-11 19:47:23 +0000767 elif is_exe(relExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000768 lldbHere = relExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000769 elif is_exe(baiExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000770 lldbHere = baiExec
Johnny Chen26901c82011-03-11 19:47:23 +0000771 elif is_exe(baiExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000772 lldbHere = baiExec2
Daniel Dunbar2bd310c2011-10-31 23:27:06 +0000773 elif lldbExec:
774 lldbHere = lldbExec
Johnny Chen26901c82011-03-11 19:47:23 +0000775
Johnny Chen6033bed2011-08-26 00:00:01 +0000776 if lldbHere:
777 os.environ["LLDB_HERE"] = lldbHere
Johnny Chen0409d992011-10-25 20:08:03 +0000778 os.environ["LLDB_BUILD_DIR"] = os.path.split(lldbHere)[0]
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000779 if not noHeaders:
780 print "LLDB build dir:", os.environ["LLDB_BUILD_DIR"]
Johnny Chen91da0052011-10-28 17:56:02 +0000781 os.system('%s -v' % lldbHere)
Johnny Chen62d527e2011-08-04 18:17:16 +0000782
Johnny Chen6033bed2011-08-26 00:00:01 +0000783 # One last chance to locate the 'lldb' executable.
Johnny Chen26901c82011-03-11 19:47:23 +0000784 if not lldbExec:
Johnny Chen0409d992011-10-25 20:08:03 +0000785 lldbExec = which('lldb')
786 if lldbHere and not lldbExec:
Johnny Chen6033bed2011-08-26 00:00:01 +0000787 lldbExec = lldbHere
Johnny Chen0409d992011-10-25 20:08:03 +0000788
Johnny Chen26901c82011-03-11 19:47:23 +0000789
790 if not lldbExec:
791 print "The 'lldb' executable cannot be located. Some of the tests may not be run as a result."
792 else:
793 os.environ["LLDB_EXEC"] = lldbExec
Johnny Chen8904eb02011-10-28 00:59:00 +0000794 #print "The 'lldb' from PATH env variable", lldbExec
Johnny Chend7931462011-03-17 00:38:22 +0000795
Johnny Chenb264c9b2011-06-24 22:52:05 +0000796 if os.path.isdir(os.path.join(base, '.svn')):
797 pipe = subprocess.Popen(["svn", "info", base], stdout = subprocess.PIPE)
798 svn_info = pipe.stdout.read()
799 elif os.path.isdir(os.path.join(base, '.git')):
800 pipe = subprocess.Popen(["git", "svn", "info", base], stdout = subprocess.PIPE)
801 svn_info = pipe.stdout.read()
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000802 if not noHeaders:
803 print svn_info
Johnny Chen26901c82011-03-11 19:47:23 +0000804
805 global ignore
806
807 # The '-i' option is used to skip looking for lldb.py in the build tree.
808 if ignore:
809 return
810
Johnny Chen6a564a42011-02-15 18:50:19 +0000811 dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
812 dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
813 relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
814 relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
815 baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
816 baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
Johnny Chen9707bb62010-06-25 21:14:08 +0000817
818 lldbPath = None
819 if os.path.isfile(os.path.join(dbgPath, 'lldb.py')):
820 lldbPath = dbgPath
Greg Claytond9846b02011-02-14 21:17:06 +0000821 elif os.path.isfile(os.path.join(dbgPath2, 'lldb.py')):
822 lldbPath = dbgPath2
Johnny Chen9707bb62010-06-25 21:14:08 +0000823 elif os.path.isfile(os.path.join(relPath, 'lldb.py')):
824 lldbPath = relPath
Greg Claytond9846b02011-02-14 21:17:06 +0000825 elif os.path.isfile(os.path.join(relPath2, 'lldb.py')):
826 lldbPath = relPath2
Johnny Chenc202c462010-09-15 18:11:19 +0000827 elif os.path.isfile(os.path.join(baiPath, 'lldb.py')):
828 lldbPath = baiPath
Greg Claytond9846b02011-02-14 21:17:06 +0000829 elif os.path.isfile(os.path.join(baiPath2, 'lldb.py')):
830 lldbPath = baiPath2
Johnny Chen9707bb62010-06-25 21:14:08 +0000831
832 if not lldbPath:
Johnny Chenc202c462010-09-15 18:11:19 +0000833 print 'This script requires lldb.py to be in either ' + dbgPath + ',',
834 print relPath + ', or ' + baiPath
Johnny Chen9707bb62010-06-25 21:14:08 +0000835 sys.exit(-1)
836
Johnny Chenaf149a02010-09-16 17:11:30 +0000837 # This is to locate the lldb.py module. Insert it right after sys.path[0].
838 sys.path[1:1] = [lldbPath]
Johnny Chen50bc6382011-01-29 01:16:52 +0000839 if dumpSysPath:
840 print "sys.path:", sys.path
Johnny Chen9707bb62010-06-25 21:14:08 +0000841
Johnny Chen9707bb62010-06-25 21:14:08 +0000842
Johnny Chencd0279d2010-09-20 18:07:50 +0000843def doDelay(delta):
844 """Delaying startup for delta-seconds to facilitate debugger attachment."""
845 def alarm_handler(*args):
846 raise Exception("timeout")
847
848 signal.signal(signal.SIGALRM, alarm_handler)
849 signal.alarm(delta)
850 sys.stdout.write("pid=%d\n" % os.getpid())
851 sys.stdout.write("Enter RET to proceed (or timeout after %d seconds):" %
852 delta)
853 sys.stdout.flush()
854 try:
855 text = sys.stdin.readline()
856 except:
857 text = ""
858 signal.alarm(0)
859 sys.stdout.write("proceeding...\n")
860 pass
861
862
Johnny Chen9707bb62010-06-25 21:14:08 +0000863def visit(prefix, dir, names):
864 """Visitor function for os.path.walk(path, visit, arg)."""
865
866 global suite
Johnny Chen7c52ff12010-09-27 23:29:54 +0000867 global regexp
Johnny Chenc5fa0052011-07-29 22:54:56 +0000868 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000869 global fs4all
Johnny Chene9eae812012-01-18 05:15:00 +0000870 global excluded
871
872 if set(dir.split(os.sep)).intersection(excluded):
873 #print "Detected an excluded dir component: %s" % dir
874 return
Johnny Chen9707bb62010-06-25 21:14:08 +0000875
876 for name in names:
877 if os.path.isdir(os.path.join(dir, name)):
878 continue
879
880 if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
Johnny Chen7c52ff12010-09-27 23:29:54 +0000881 # Try to match the regexp pattern, if specified.
882 if regexp:
883 import re
884 if re.search(regexp, name):
885 #print "Filename: '%s' matches pattern: '%s'" % (name, regexp)
886 pass
887 else:
888 #print "Filename: '%s' does not match pattern: '%s'" % (name, regexp)
889 continue
890
Johnny Chen953864a2010-10-12 21:35:54 +0000891 # We found a match for our test. Add it to the suite.
Johnny Chen79723352010-10-12 15:53:22 +0000892
893 # Update the sys.path first.
Johnny Chena85d7ee2010-06-26 00:19:32 +0000894 if not sys.path.count(dir):
Johnny Chen548aefd2010-10-11 22:25:46 +0000895 sys.path.insert(0, dir)
Johnny Chen9707bb62010-06-25 21:14:08 +0000896 base = os.path.splitext(name)[0]
Johnny Chenb62436b2010-10-06 20:40:56 +0000897
898 # Thoroughly check the filterspec against the base module and admit
899 # the (base, filterspec) combination only when it makes sense.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000900 filterspec = None
901 for filterspec in filters:
Johnny Chenb62436b2010-10-06 20:40:56 +0000902 # Optimistically set the flag to True.
903 filtered = True
904 module = __import__(base)
905 parts = filterspec.split('.')
906 obj = module
907 for part in parts:
908 try:
909 parent, obj = obj, getattr(obj, part)
910 except AttributeError:
911 # The filterspec has failed.
912 filtered = False
913 break
Johnny Chenc5fa0052011-07-29 22:54:56 +0000914
Johnny Chendb4be602011-08-12 23:55:07 +0000915 # If filtered, we have a good filterspec. Add it.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000916 if filtered:
Johnny Chendb4be602011-08-12 23:55:07 +0000917 #print "adding filter spec %s to module %s" % (filterspec, module)
918 suite.addTests(
919 unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
920 continue
Johnny Chenc5fa0052011-07-29 22:54:56 +0000921
922 # Forgo this module if the (base, filterspec) combo is invalid
923 # and no '-g' option is specified
924 if filters and fs4all and not filtered:
925 continue
Johnny Chenb62436b2010-10-06 20:40:56 +0000926
Johnny Chendb4be602011-08-12 23:55:07 +0000927 # Add either the filtered test case(s) (which is done before) or the entire test class.
928 if not filterspec or not filtered:
Johnny Chenb62436b2010-10-06 20:40:56 +0000929 # A simple case of just the module name. Also the failover case
930 # from the filterspec branch when the (base, filterspec) combo
931 # doesn't make sense.
932 suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
Johnny Chen9707bb62010-06-25 21:14:08 +0000933
934
Johnny Chencd0279d2010-09-20 18:07:50 +0000935def lldbLoggings():
936 """Check and do lldb loggings if necessary."""
937
938 # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
939 # defined. Use ${LLDB_LOG} to specify the log file.
940 ci = lldb.DBG.GetCommandInterpreter()
941 res = lldb.SBCommandReturnObject()
942 if ("LLDB_LOG" in os.environ):
943 if ("LLDB_LOG_OPTION" in os.environ):
944 lldb_log_option = os.environ["LLDB_LOG_OPTION"]
945 else:
Johnny Chen8fd886c2010-12-08 01:25:21 +0000946 lldb_log_option = "event process expr state api"
Johnny Chencd0279d2010-09-20 18:07:50 +0000947 ci.HandleCommand(
Greg Clayton940b1032011-02-23 00:35:02 +0000948 "log enable -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option,
Johnny Chencd0279d2010-09-20 18:07:50 +0000949 res)
950 if not res.Succeeded():
951 raise Exception('log enable failed (check LLDB_LOG env variable.')
952 # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
953 # Use ${GDB_REMOTE_LOG} to specify the log file.
954 if ("GDB_REMOTE_LOG" in os.environ):
955 if ("GDB_REMOTE_LOG_OPTION" in os.environ):
956 gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
957 else:
Johnny Chen7ab8c852010-12-02 18:35:13 +0000958 gdb_remote_log_option = "packets process"
Johnny Chencd0279d2010-09-20 18:07:50 +0000959 ci.HandleCommand(
Johnny Chenc935a892011-06-21 19:25:45 +0000960 "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
Johnny Chencd0279d2010-09-20 18:07:50 +0000961 + gdb_remote_log_option,
962 res)
963 if not res.Succeeded():
964 raise Exception('log enable failed (check GDB_REMOTE_LOG env variable.')
965
Johnny Chen067022b2011-01-19 19:31:46 +0000966def getMyCommandLine():
Johnny Chen067022b2011-01-19 19:31:46 +0000967 ps = subprocess.Popen(['ps', '-o', "command=CMD", str(os.getpid())], stdout=subprocess.PIPE).communicate()[0]
968 lines = ps.split('\n')
969 cmd_line = lines[1]
970 return cmd_line
Johnny Chencd0279d2010-09-20 18:07:50 +0000971
Johnny Chend96b5682010-11-05 17:30:53 +0000972# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +0000973# #
974# Execution of the test driver starts here #
975# #
Johnny Chend96b5682010-11-05 17:30:53 +0000976# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +0000977
Johnny Chen2891bb02011-09-16 01:04:26 +0000978def checkDsymForUUIDIsNotOn():
Johnny Chen6a4e0872011-09-16 17:50:44 +0000979 cmd = ["defaults", "read", "com.apple.DebugSymbols"]
980 pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
981 cmd_output = pipe.stdout.read()
Johnny Chen178c8d92011-09-16 18:03:19 +0000982 if cmd_output and "DBGFileMappedPaths = " in cmd_output:
Johnny Chen6a451482011-09-16 18:09:45 +0000983 print "%s =>" % ' '.join(cmd)
Johnny Chen6a4e0872011-09-16 17:50:44 +0000984 print cmd_output
Johnny Chen2891bb02011-09-16 01:04:26 +0000985 print "Disable automatic lookup and caching of dSYMs before running the test suite!"
986 print "Exiting..."
987 sys.exit(0)
988
989# On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
990# does not exist before proceeding to running the test suite.
991if sys.platform.startswith("darwin"):
992 checkDsymForUUIDIsNotOn()
993
Johnny Chen9707bb62010-06-25 21:14:08 +0000994#
Johnny Chenaf149a02010-09-16 17:11:30 +0000995# Start the actions by first parsing the options while setting up the test
996# directories, followed by setting up the search paths for lldb utilities;
997# then, we walk the directory trees and collect the tests into our test suite.
Johnny Chen9707bb62010-06-25 21:14:08 +0000998#
Johnny Chenaf149a02010-09-16 17:11:30 +0000999parseOptionsAndInitTestdirs()
Johnny Chen9707bb62010-06-25 21:14:08 +00001000setupSysPath()
Johnny Chen91960d32010-09-08 20:56:16 +00001001
1002#
1003# If '-d' is specified, do a delay of 10 seconds for the debugger to attach.
1004#
1005if delay:
Johnny Chencd0279d2010-09-20 18:07:50 +00001006 doDelay(10)
Johnny Chen91960d32010-09-08 20:56:16 +00001007
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001008#
Johnny Chen41998192010-10-01 22:59:49 +00001009# If '-l' is specified, do not skip the long running tests.
Johnny Chen028d8eb2011-11-17 19:57:27 +00001010if not skip_long_running_test:
Johnny Chen41998192010-10-01 22:59:49 +00001011 os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
1012
1013#
Johnny Chen79723352010-10-12 15:53:22 +00001014# Walk through the testdirs while collecting tests.
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001015#
Johnny Chen9707bb62010-06-25 21:14:08 +00001016for testdir in testdirs:
1017 os.path.walk(testdir, visit, 'Test')
1018
Johnny Chenb40056b2010-09-21 00:09:27 +00001019#
Johnny Chen9707bb62010-06-25 21:14:08 +00001020# Now that we have loaded all the test cases, run the whole test suite.
Johnny Chenb40056b2010-09-21 00:09:27 +00001021#
Johnny Chencd0279d2010-09-20 18:07:50 +00001022
Johnny Chen1bfbd412010-06-29 19:44:16 +00001023# For the time being, let's bracket the test runner within the
1024# lldb.SBDebugger.Initialize()/Terminate() pair.
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001025import lldb, atexit
Johnny Chen6b6f5ba2010-10-14 16:36:49 +00001026# Update: the act of importing lldb now executes lldb.SBDebugger.Initialize(),
1027# there's no need to call it a second time.
1028#lldb.SBDebugger.Initialize()
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001029atexit.register(lambda: lldb.SBDebugger.Terminate())
Johnny Chen1bfbd412010-06-29 19:44:16 +00001030
Johnny Chen909e5a62010-07-01 22:52:57 +00001031# Create a singleton SBDebugger in the lldb namespace.
1032lldb.DBG = lldb.SBDebugger.Create()
1033
Johnny Chen4f93bf12010-12-10 00:51:23 +00001034# Put the blacklist in the lldb namespace, to be used by lldb.TestBase.
Johnny Chen82e6b1e2010-12-01 22:47:54 +00001035lldb.blacklist = blacklist
1036
Johnny Chenac97a6b2012-04-16 18:55:15 +00001037# The pre_flight and post_flight come from reading a config file.
1038lldb.pre_flight = pre_flight
1039lldb.post_flight = post_flight
1040def getsource_if_available(obj):
1041 """
1042 Return the text of the source code for an object if available. Otherwise,
1043 a print representation is returned.
1044 """
1045 import inspect
1046 try:
1047 return inspect.getsource(obj)
1048 except:
1049 return repr(obj)
1050
1051print "lldb.pre_flight:", getsource_if_available(lldb.pre_flight)
1052print "lldb.post_flight:", getsource_if_available(lldb.post_flight)
1053
Johnny Chena3ed7d82012-04-06 00:56:05 +00001054# Put all these test decorators in the lldb namespace.
Johnny Chen4f93bf12010-12-10 00:51:23 +00001055lldb.dont_do_python_api_test = dont_do_python_api_test
1056lldb.just_do_python_api_test = just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +00001057lldb.just_do_benchmarks_test = just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +00001058lldb.dont_do_dsym_test = dont_do_dsym_test
1059lldb.dont_do_dwarf_test = dont_do_dwarf_test
Johnny Chen4f93bf12010-12-10 00:51:23 +00001060
Johnny Chen028d8eb2011-11-17 19:57:27 +00001061# Do we need to skip build and cleanup?
1062lldb.skip_build_and_cleanup = skip_build_and_cleanup
1063
Johnny Chen5f2ed172011-10-20 18:43:28 +00001064# Put bmExecutable, bmBreakpointSpec, and bmIterationCount into the lldb namespace, too.
Johnny Chene00c9302011-10-10 22:03:44 +00001065lldb.bmExecutable = bmExecutable
1066lldb.bmBreakpointSpec = bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +00001067lldb.bmIterationCount = bmIterationCount
Johnny Chene00c9302011-10-10 22:03:44 +00001068
Johnny Chen38f823c2011-10-11 01:30:27 +00001069# And don't forget the runHooks!
1070lldb.runHooks = runHooks
1071
Johnny Chencd0279d2010-09-20 18:07:50 +00001072# Turn on lldb loggings if necessary.
1073lldbLoggings()
Johnny Chen909e5a62010-07-01 22:52:57 +00001074
Johnny Chen7987ac92010-08-09 20:40:52 +00001075# Install the control-c handler.
1076unittest2.signals.installHandler()
1077
Johnny Chen125fc2b2010-10-21 16:55:35 +00001078# If sdir_name is not specified through the '-s sdir_name' option, get a
1079# timestamp string and export it as LLDB_SESSION_DIR environment var. This will
1080# be used when/if we want to dump the session info of individual test cases
1081# later on.
Johnny Chence681462010-10-19 00:25:01 +00001082#
1083# See also TestBase.dumpSessionInfo() in lldbtest.py.
Johnny Chen125fc2b2010-10-21 16:55:35 +00001084if not sdir_name:
1085 import datetime
Johnny Chen41fae812010-10-29 22:26:38 +00001086 # The windows platforms don't like ':' in the pathname.
Johnny Chen76bd0102010-10-28 16:32:13 +00001087 timestamp = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
Johnny Chen125fc2b2010-10-21 16:55:35 +00001088 sdir_name = timestamp
Peter Collingbourne132476f2011-06-20 23:55:53 +00001089os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), sdir_name)
Johnny Chen067022b2011-01-19 19:31:46 +00001090
Johnny Chenfe5f1ed2011-10-21 18:33:27 +00001091if not noHeaders:
1092 sys.stderr.write("\nSession logs for test failures/errors/unexpected successes"
1093 " will go into directory '%s'\n" % sdir_name)
1094 sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
Johnny Chence681462010-10-19 00:25:01 +00001095
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001096if not os.path.isdir(sdir_name):
1097 os.mkdir(sdir_name)
1098fname = os.path.join(sdir_name, "svn-info")
1099with open(fname, "w") as f:
1100 print >> f, svn_info
1101 print >> f, "Command invoked: %s\n" % getMyCommandLine()
1102
Johnny Chenb40056b2010-09-21 00:09:27 +00001103#
Johnny Chen0f907b82012-01-31 00:38:03 +00001104# If we have environment variables to unset, do it here before we invoke the test runner.
1105#
1106for env_var in unsets :
1107 if env_var in os.environ:
1108 # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
Johnny Chen6346a292012-01-31 00:48:02 +00001109 # is automatically translated into a corresponding call to unsetenv().
Johnny Chen0f907b82012-01-31 00:38:03 +00001110 del os.environ[env_var]
1111 #os.unsetenv(env_var)
1112
1113#
Johnny Chenb40056b2010-09-21 00:09:27 +00001114# Invoke the default TextTestRunner to run the test suite, possibly iterating
1115# over different configurations.
1116#
1117
Johnny Chenb40056b2010-09-21 00:09:27 +00001118iterArchs = False
Johnny Chenf032d902010-09-21 00:16:09 +00001119iterCompilers = False
Johnny Chenb40056b2010-09-21 00:09:27 +00001120
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001121if not archs and "archs" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001122 archs = config["archs"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001123
1124if isinstance(archs, list) and len(archs) >= 1:
1125 iterArchs = True
1126
1127if not compilers and "compilers" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001128 compilers = config["compilers"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001129
Johnny Chen92693b52012-03-09 02:11:37 +00001130#
1131# Add some intervention here to sanity check that the compilers requested are sane.
1132# If found not to be an executable program, the invalid one is dropped from the list.
1133for i in range(len(compilers)):
1134 c = compilers[i]
1135 if which(c):
1136 continue
1137 else:
1138 if sys.platform.startswith("darwin"):
1139 pipe = subprocess.Popen(['xcrun', '-find', c], stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1140 cmd_output = pipe.stdout.read()
1141 if cmd_output:
1142 if "not found" in cmd_output:
1143 print "dropping %s from the compilers used" % c
1144 compilers.remove(i)
1145 else:
1146 compilers[i] = cmd_output.split('\n')[0]
1147 print "'xcrun -find %s' returning %s" % (c, compilers[i])
1148
1149print "compilers=%s" % str(compilers)
1150
1151if not compilers or len(compilers) == 0:
1152 print "No eligible compiler found, exiting."
1153 sys.exit(1)
1154
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001155if isinstance(compilers, list) and len(compilers) >= 1:
1156 iterCompilers = True
Johnny Chenb40056b2010-09-21 00:09:27 +00001157
Johnny Chen953864a2010-10-12 21:35:54 +00001158# Make a shallow copy of sys.path, we need to manipulate the search paths later.
1159# This is only necessary if we are relocated and with different configurations.
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001160if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001161 old_sys_path = sys.path[:]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001162# If we iterate on archs or compilers, there is a chance we want to split stderr/stdout.
1163if iterArchs or iterCompilers:
Johnny Chen953864a2010-10-12 21:35:54 +00001164 old_stderr = sys.stderr
1165 old_stdout = sys.stdout
1166 new_stderr = None
1167 new_stdout = None
1168
Johnny Chend96b5682010-11-05 17:30:53 +00001169# Iterating over all possible architecture and compiler combinations.
Johnny Chenb40056b2010-09-21 00:09:27 +00001170for ia in range(len(archs) if iterArchs else 1):
1171 archConfig = ""
1172 if iterArchs:
Johnny Chen18a921f2010-09-30 17:11:58 +00001173 os.environ["ARCH"] = archs[ia]
Johnny Chenb40056b2010-09-21 00:09:27 +00001174 archConfig = "arch=%s" % archs[ia]
1175 for ic in range(len(compilers) if iterCompilers else 1):
1176 if iterCompilers:
Johnny Chen18a921f2010-09-30 17:11:58 +00001177 os.environ["CC"] = compilers[ic]
Johnny Chenb40056b2010-09-21 00:09:27 +00001178 configString = "%s compiler=%s" % (archConfig, compilers[ic])
1179 else:
1180 configString = archConfig
1181
Johnny Chenb40056b2010-09-21 00:09:27 +00001182 if iterArchs or iterCompilers:
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001183 # Translate ' ' to '-' for pathname component.
1184 from string import maketrans
1185 tbl = maketrans(' ', '-')
1186 configPostfix = configString.translate(tbl)
1187
1188 # Check whether we need to split stderr/stdout into configuration
1189 # specific files.
1190 if old_stderr.name != '<stderr>' and config.get('split_stderr'):
1191 if new_stderr:
1192 new_stderr.close()
1193 new_stderr = open("%s.%s" % (old_stderr.name, configPostfix), "w")
1194 sys.stderr = new_stderr
1195 if old_stdout.name != '<stdout>' and config.get('split_stdout'):
1196 if new_stdout:
1197 new_stdout.close()
1198 new_stdout = open("%s.%s" % (old_stdout.name, configPostfix), "w")
1199 sys.stdout = new_stdout
1200
Johnny Chen953864a2010-10-12 21:35:54 +00001201 # If we specified a relocated directory to run the test suite, do
1202 # the extra housekeeping to copy the testdirs to a configStringified
1203 # directory and to update sys.path before invoking the test runner.
1204 # The purpose is to separate the configuration-specific directories
1205 # from each other.
1206 if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001207 from shutil import copytree, ignore_patterns
1208
Johnny Chen953864a2010-10-12 21:35:54 +00001209 newrdir = "%s.%s" % (rdir, configPostfix)
1210
1211 # Copy the tree to a new directory with postfix name configPostfix.
1212 copytree(rdir, newrdir, ignore=ignore_patterns('*.pyc', '*.o', '*.d'))
1213
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001214 # Update the LLDB_TEST environment variable to reflect new top
Johnny Chen953864a2010-10-12 21:35:54 +00001215 # level test directory.
1216 #
1217 # See also lldbtest.TestBase.setUpClass(cls).
1218 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
1219 os.environ["LLDB_TEST"] = os.path.join(newrdir, 'test')
1220 else:
1221 os.environ["LLDB_TEST"] = newrdir
1222
1223 # And update the Python search paths for modules.
1224 sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
1225
1226 # Output the configuration.
Johnny Chenb40056b2010-09-21 00:09:27 +00001227 sys.stderr.write("\nConfiguration: " + configString + "\n")
Johnny Chen953864a2010-10-12 21:35:54 +00001228
1229 #print "sys.stderr name is", sys.stderr.name
1230 #print "sys.stdout name is", sys.stdout.name
1231
1232 # First, write out the number of collected test cases.
Johnny Chen08967192011-11-18 00:19:29 +00001233 sys.stderr.write(separator + "\n")
1234 sys.stderr.write("Collected %d test%s\n\n"
1235 % (suite.countTestCases(),
1236 suite.countTestCases() != 1 and "s" or ""))
Johnny Chen953864a2010-10-12 21:35:54 +00001237
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001238 class LLDBTestResult(unittest2.TextTestResult):
1239 """
Johnny Chen26be4532010-11-09 23:56:14 +00001240 Enforce a singleton pattern to allow introspection of test progress.
1241
1242 Overwrite addError(), addFailure(), and addExpectedFailure() methods
1243 to enable each test instance to track its failure/error status. It
1244 is used in the LLDB test framework to emit detailed trace messages
1245 to a log file for easier human inspection of test failres/errors.
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001246 """
1247 __singleton__ = None
Johnny Chen360dd372010-11-29 17:50:10 +00001248 __ignore_singleton__ = False
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001249
1250 def __init__(self, *args):
Johnny Chen360dd372010-11-29 17:50:10 +00001251 if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
Johnny Chend2acdb32010-11-16 22:42:58 +00001252 raise Exception("LLDBTestResult instantiated more than once")
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001253 super(LLDBTestResult, self).__init__(*args)
1254 LLDBTestResult.__singleton__ = self
1255 # Now put this singleton into the lldb module namespace.
1256 lldb.test_result = self
Johnny Chen810042e2011-01-05 20:24:11 +00001257 # Computes the format string for displaying the counter.
1258 global suite
1259 counterWidth = len(str(suite.countTestCases()))
1260 self.fmt = "%" + str(counterWidth) + "d: "
Johnny Chenc87fd492011-01-05 22:50:11 +00001261 self.indentation = ' ' * (counterWidth + 2)
Johnny Chen810042e2011-01-05 20:24:11 +00001262 # This counts from 1 .. suite.countTestCases().
1263 self.counter = 0
1264
Johnny Chenc87fd492011-01-05 22:50:11 +00001265 def getDescription(self, test):
1266 doc_first_line = test.shortDescription()
1267 if self.descriptions and doc_first_line:
1268 return '\n'.join((str(test), self.indentation + doc_first_line))
1269 else:
1270 return str(test)
1271
Johnny Chen810042e2011-01-05 20:24:11 +00001272 def startTest(self, test):
1273 self.counter += 1
1274 if self.showAll:
1275 self.stream.write(self.fmt % self.counter)
1276 super(LLDBTestResult, self).startTest(test)
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001277
Johnny Chen08967192011-11-18 00:19:29 +00001278 def stopTest(self, test):
1279 """Called when the given test has been run"""
1280 if progress_bar:
1281 sys.__stdout__.write('.')
1282 sys.__stdout__.flush()
1283 if self.counter == suite.countTestCases():
1284 sys.__stdout__.write('\n')
1285
1286 super(LLDBTestResult, self).stopTest(test)
1287
Johnny Chence681462010-10-19 00:25:01 +00001288 def addError(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001289 global sdir_has_content
1290 sdir_has_content = True
Johnny Chence681462010-10-19 00:25:01 +00001291 super(LLDBTestResult, self).addError(test, err)
1292 method = getattr(test, "markError", None)
1293 if method:
1294 method()
1295
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001296 def addFailure(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001297 global sdir_has_content
1298 sdir_has_content = True
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001299 super(LLDBTestResult, self).addFailure(test, err)
1300 method = getattr(test, "markFailure", None)
1301 if method:
1302 method()
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001303
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001304 def addExpectedFailure(self, test, err):
1305 global sdir_has_content
1306 sdir_has_content = True
1307 super(LLDBTestResult, self).addExpectedFailure(test, err)
1308 method = getattr(test, "markExpectedFailure", None)
1309 if method:
1310 method()
1311
Johnny Chenf5b89092011-08-15 23:09:08 +00001312 def addSkip(self, test, reason):
1313 global sdir_has_content
1314 sdir_has_content = True
1315 super(LLDBTestResult, self).addSkip(test, reason)
1316 method = getattr(test, "markSkippedTest", None)
1317 if method:
1318 method()
1319
Johnny Chenab2f0662011-05-06 20:30:22 +00001320 def addUnexpectedSuccess(self, test):
1321 global sdir_has_content
1322 sdir_has_content = True
1323 super(LLDBTestResult, self).addUnexpectedSuccess(test)
1324 method = getattr(test, "markUnexpectedSuccess", None)
1325 if method:
1326 method()
1327
Johnny Chen26be4532010-11-09 23:56:14 +00001328 # Invoke the test runner.
Johnny Chend2acdb32010-11-16 22:42:58 +00001329 if count == 1:
Johnny Chen7d6d8442010-12-03 19:59:35 +00001330 result = unittest2.TextTestRunner(stream=sys.stderr,
1331 verbosity=verbose,
1332 failfast=failfast,
Johnny Chend2acdb32010-11-16 22:42:58 +00001333 resultclass=LLDBTestResult).run(suite)
1334 else:
Johnny Chend6e7ca22010-11-29 17:52:43 +00001335 # We are invoking the same test suite more than once. In this case,
1336 # mark __ignore_singleton__ flag as True so the signleton pattern is
1337 # not enforced.
Johnny Chen360dd372010-11-29 17:50:10 +00001338 LLDBTestResult.__ignore_singleton__ = True
Johnny Chend2acdb32010-11-16 22:42:58 +00001339 for i in range(count):
Johnny Chen7d6d8442010-12-03 19:59:35 +00001340 result = unittest2.TextTestRunner(stream=sys.stderr,
1341 verbosity=verbose,
1342 failfast=failfast,
Johnny Chen360dd372010-11-29 17:50:10 +00001343 resultclass=LLDBTestResult).run(suite)
Johnny Chenb40056b2010-09-21 00:09:27 +00001344
Johnny Chen1bfbd412010-06-29 19:44:16 +00001345
Johnny Chen63c2cba2010-10-29 22:20:36 +00001346if sdir_has_content:
Johnny Chenab2f0662011-05-06 20:30:22 +00001347 sys.stderr.write("Session logs for test failures/errors/unexpected successes"
1348 " can be found in directory '%s'\n" % sdir_name)
Johnny Chen63c2cba2010-10-29 22:20:36 +00001349
Johnny Chencd0279d2010-09-20 18:07:50 +00001350# Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1351# This should not be necessary now.
Johnny Chen83f6e512010-08-13 22:58:44 +00001352if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
Johnny Chen83f6e512010-08-13 22:58:44 +00001353 print "Terminating Test suite..."
1354 subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1355
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001356# Exiting.
1357sys.exit(not result.wasSuccessful)