blob: ef4e12997f5c2fa1d7a69a3709784b9750827c3d [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 Chen3bc7e5e2012-04-24 21:44:10 +0000244-R : specify a dir to relocate the tests and their intermediate files to;
245 BE WARNED THAT the directory, if exists, will be deleted before running this test driver;
Johnny Chen548aefd2010-10-11 22:25:46 +0000246 no cleanup of intermediate test files is performed in this case
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000247-r : similar to '-R',
248 except that the directory must not exist before running this test driver
Johnny Chen028d8eb2011-11-17 19:57:27 +0000249-S : skip the build and cleanup while running the test
250 use this option with care as you would need to build the inferior(s) by hand
251 and build the executable(s) with the correct name(s)
252 this can be used with '-# n' to stress test certain test cases for n number of
253 times
Johnny Chen125fc2b2010-10-21 16:55:35 +0000254-s : specify the name of the dir created to store the session files of tests
255 with errored or failed status; if not specified, the test driver uses the
256 timestamp as the session dir name
Johnny Chena2486f22011-04-21 20:48:32 +0000257-t : turn on tracing of lldb command and other detailed test executions
Johnny Chen0f907b82012-01-31 00:38:03 +0000258-u : specify an environment variable to unset before running the test cases
259 e.g., -u DYLD_INSERT_LIBRARIES -u MallocScribble'
Johnny Chena2486f22011-04-21 20:48:32 +0000260-v : do verbose mode of unittest framework (print out each test case invocation)
Johnny Chene9eae812012-01-18 05:15:00 +0000261-X : exclude a directory from consideration for test discovery
262 -X types => if 'types' appear in the pathname components of a potential testfile
263 it will be ignored
Johnny Chene00c9302011-10-10 22:03:44 +0000264-x : specify the breakpoint specification for the benchmark executable;
265 see also '-e', which provides the full path of the executable
Johnny Chen5f2ed172011-10-20 18:43:28 +0000266-y : specify the iteration count used to collect our benchmarks; an example is
267 the number of times to do 'thread step-over' to measure stepping speed
268 see also '-e' and '-x' options
Johnny Chene47649c2010-10-07 02:04:14 +0000269-w : insert some wait time (currently 0.5 sec) between consecutive test cases
Johnny Chend2acdb32010-11-16 22:42:58 +0000270-# : Repeat the test suite for a specified number of times
Johnny Chen9707bb62010-06-25 21:14:08 +0000271
272and:
Johnny Chen9656ab22010-10-22 19:00:18 +0000273args : specify a list of directory names to search for test modules named after
274 Test*.py (test discovery)
Peter Collingbourne5f2b5d62011-06-14 03:55:45 +0000275 if empty, search from the current working directory, instead
Jim Ingham4f347cb2011-04-13 21:11:41 +0000276"""
Johnny Chen58f93922010-06-29 23:10:39 +0000277
Jim Ingham4f347cb2011-04-13 21:11:41 +0000278 if verbose > 0:
279 print """
Johnny Chen9656ab22010-10-22 19:00:18 +0000280Examples:
281
Johnny Chena224cd12010-11-08 01:21:03 +0000282This is an example of using the -f option to pinpoint to a specfic test class
283and test method to be run:
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000284
Johnny Chena224cd12010-11-08 01:21:03 +0000285$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000286----------------------------------------------------------------------
287Collected 1 test
288
289test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
290Test 'frame variable this' when stopped on a class constructor. ... ok
291
292----------------------------------------------------------------------
293Ran 1 test in 1.396s
294
295OK
Johnny Chen9656ab22010-10-22 19:00:18 +0000296
297And this is an example of using the -p option to run a single file (the filename
298matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
299
300$ ./dotest.py -v -p ObjC
301----------------------------------------------------------------------
302Collected 4 tests
303
304test_break_with_dsym (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_break_with_dwarf (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000307Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000308test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
309Lookup objective-c data types and evaluate expressions. ... ok
310test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
311Lookup objective-c data types and evaluate expressions. ... ok
312
313----------------------------------------------------------------------
314Ran 4 tests in 16.661s
315
316OK
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000317
Johnny Chen58f93922010-06-29 23:10:39 +0000318Running of this script also sets up the LLDB_TEST environment variable so that
Johnny Chenaf149a02010-09-16 17:11:30 +0000319individual test cases can locate their supporting files correctly. The script
320tries to set up Python's search paths for modules by looking at the build tree
Johnny Chena85859f2010-11-11 22:14:56 +0000321relative to this script. See also the '-i' option in the following example.
322
323Finally, this is an example of using the lldb.py module distributed/installed by
324Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
325option to add some delay between two tests. It uses ARCH=x86_64 to specify that
326as the architecture and CC=clang to specify the compiler used for the test run:
327
328$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
329
330Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
331----------------------------------------------------------------------
332Collected 2 tests
333
334test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
335Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
336test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
337Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
338
339----------------------------------------------------------------------
340Ran 2 tests in 5.659s
341
342OK
343
344The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
345notify the directory containing the session logs for test failures or errors.
346In case there is any test failure/error, a similar message is appended at the
347end of the stderr output for your convenience.
Johnny Chenfde69bc2010-09-14 22:01:40 +0000348
349Environment variables related to loggings:
350
351o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
352 with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
353
354o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
355 'process.gdb-remote' subsystem with a default option of 'packets' if
356 GDB_REMOTE_LOG_OPTION is not defined.
Johnny Chen9707bb62010-06-25 21:14:08 +0000357"""
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000358 sys.exit(0)
Johnny Chen9707bb62010-06-25 21:14:08 +0000359
360
Johnny Chenaf149a02010-09-16 17:11:30 +0000361def parseOptionsAndInitTestdirs():
362 """Initialize the list of directories containing our unittest scripts.
363
364 '-h/--help as the first option prints out usage info and exit the program.
365 """
366
Johnny Chen4f93bf12010-12-10 00:51:23 +0000367 global dont_do_python_api_test
368 global just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000369 global just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +0000370 global dont_do_dsym_test
371 global dont_do_dwarf_test
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000372 global blacklist
373 global blacklistConfig
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000374 global configFile
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000375 global archs
376 global compilers
Johnny Chend2acdb32010-11-16 22:42:58 +0000377 global count
Johnny Chenaf149a02010-09-16 17:11:30 +0000378 global delay
Johnny Chen50bc6382011-01-29 01:16:52 +0000379 global dumpSysPath
Johnny Chene00c9302011-10-10 22:03:44 +0000380 global bmExecutable
381 global bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000382 global bmIterationCount
Johnny Chen7d6d8442010-12-03 19:59:35 +0000383 global failfast
Johnny Chenc5fa0052011-07-29 22:54:56 +0000384 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000385 global fs4all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000386 global ignore
Johnny Chen08967192011-11-18 00:19:29 +0000387 global progress_bar
Johnny Chen38f823c2011-10-11 01:30:27 +0000388 global runHooks
Johnny Chen028d8eb2011-11-17 19:57:27 +0000389 global skip_build_and_cleanup
390 global skip_long_running_test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000391 global noHeaders
Johnny Chen7c52ff12010-09-27 23:29:54 +0000392 global regexp
Johnny Chen548aefd2010-10-11 22:25:46 +0000393 global rdir
Johnny Chen125fc2b2010-10-21 16:55:35 +0000394 global sdir_name
Johnny Chen0f907b82012-01-31 00:38:03 +0000395 global unsets
Johnny Chenaf149a02010-09-16 17:11:30 +0000396 global verbose
397 global testdirs
398
Jim Ingham4f347cb2011-04-13 21:11:41 +0000399 do_help = False
400
Johnny Chenaf149a02010-09-16 17:11:30 +0000401 # Process possible trace and/or verbose flag, among other things.
402 index = 1
Johnny Chence2212c2010-10-07 15:41:55 +0000403 while index < len(sys.argv):
Johnny Chen4f93bf12010-12-10 00:51:23 +0000404 if sys.argv[index].startswith('-') or sys.argv[index].startswith('+'):
405 # We should continue processing...
406 pass
407 else:
Johnny Chenaf149a02010-09-16 17:11:30 +0000408 # End of option processing.
409 break
410
411 if sys.argv[index].find('-h') != -1:
Jim Ingham4f347cb2011-04-13 21:11:41 +0000412 index += 1
413 do_help = True
Johnny Chen012cba12011-01-26 19:07:42 +0000414 elif sys.argv[index].startswith('-A'):
415 # Increment by 1 to fetch the ARCH spec.
416 index += 1
417 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
418 usage()
Johnny Cheneee9b862011-04-26 20:45:00 +0000419 archs = sys.argv[index].split('^')
Johnny Chen012cba12011-01-26 19:07:42 +0000420 index += 1
421 elif sys.argv[index].startswith('-C'):
422 # Increment by 1 to fetch the CC spec.
423 index += 1
424 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
425 usage()
Johnny Cheneee9b862011-04-26 20:45:00 +0000426 compilers = sys.argv[index].split('^')
Johnny Chen012cba12011-01-26 19:07:42 +0000427 index += 1
Johnny Chen50bc6382011-01-29 01:16:52 +0000428 elif sys.argv[index].startswith('-D'):
429 dumpSysPath = True
430 index += 1
Johnny Chen1abe4c02012-03-20 00:33:51 +0000431 elif sys.argv[index].startswith('-E'):
432 # Increment by 1 to fetch the CFLAGS_EXTRAS spec.
433 index += 1
434 if index >= len(sys.argv):
435 usage()
436 cflags_extras = sys.argv[index]
437 os.environ["CFLAGS_EXTRAS"] = cflags_extras
438 index += 1
Johnny Chena3ed7d82012-04-06 00:56:05 +0000439 elif sys.argv[index].startswith('-N'):
440 # Increment by 1 to fetch 'dsym' or 'dwarf'.
441 index += 1
442 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
443 usage()
444 dont_do = sys.argv[index]
445 if dont_do.lower() == 'dsym':
446 dont_do_dsym_test = True
447 elif dont_do.lower() == 'dwarf':
448 dont_do_dwarf_test = True
449 else:
450 print "!!!"
451 print "Warning: -N only accepts either 'dsym' or 'dwarf' as the option arg; you passed in '%s'?" % dont_do
452 print "!!!"
453 index += 1
Johnny Chen4f93bf12010-12-10 00:51:23 +0000454 elif sys.argv[index].startswith('-a'):
455 dont_do_python_api_test = True
456 index += 1
457 elif sys.argv[index].startswith('+a'):
458 just_do_python_api_test = True
459 index += 1
Johnny Chen82ccf402011-07-30 01:39:58 +0000460 elif sys.argv[index].startswith('+b'):
461 just_do_benchmarks_test = True
462 index += 1
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000463 elif sys.argv[index].startswith('-b'):
464 # Increment by 1 to fetch the blacklist file name option argument.
465 index += 1
466 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
467 usage()
468 blacklistFile = sys.argv[index]
469 if not os.path.isfile(blacklistFile):
470 print "Blacklist file:", blacklistFile, "does not exist!"
471 usage()
472 index += 1
473 # Now read the blacklist contents and assign it to blacklist.
474 execfile(blacklistFile, globals(), blacklistConfig)
475 blacklist = blacklistConfig.get('blacklist')
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000476 elif sys.argv[index].startswith('-c'):
477 # Increment by 1 to fetch the config file name option argument.
478 index += 1
479 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
480 usage()
481 configFile = sys.argv[index]
482 if not os.path.isfile(configFile):
483 print "Config file:", configFile, "does not exist!"
484 usage()
485 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000486 elif sys.argv[index].startswith('-d'):
487 delay = True
488 index += 1
Johnny Chene00c9302011-10-10 22:03:44 +0000489 elif sys.argv[index].startswith('-e'):
490 # Increment by 1 to fetch the full path of the benchmark executable.
491 index += 1
492 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
493 usage()
494 bmExecutable = sys.argv[index]
495 if not is_exe(bmExecutable):
496 usage()
497 index += 1
Johnny Chen7d6d8442010-12-03 19:59:35 +0000498 elif sys.argv[index].startswith('-F'):
499 failfast = True
500 index += 1
Johnny Chenb62436b2010-10-06 20:40:56 +0000501 elif sys.argv[index].startswith('-f'):
502 # Increment by 1 to fetch the filter spec.
503 index += 1
504 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
505 usage()
Johnny Chenc5fa0052011-07-29 22:54:56 +0000506 filters.append(sys.argv[index])
Johnny Chenb62436b2010-10-06 20:40:56 +0000507 index += 1
508 elif sys.argv[index].startswith('-g'):
Johnny Chena224cd12010-11-08 01:21:03 +0000509 fs4all = False
Johnny Chenb62436b2010-10-06 20:40:56 +0000510 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000511 elif sys.argv[index].startswith('-i'):
512 ignore = True
513 index += 1
Johnny Chen38f823c2011-10-11 01:30:27 +0000514 elif sys.argv[index].startswith('-k'):
515 # Increment by 1 to fetch the runhook lldb command.
516 index += 1
517 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
518 usage()
519 runHooks.append(sys.argv[index])
520 index += 1
Johnny Chen41998192010-10-01 22:59:49 +0000521 elif sys.argv[index].startswith('-l'):
Johnny Chen028d8eb2011-11-17 19:57:27 +0000522 skip_long_running_test = False
Johnny Chen41998192010-10-01 22:59:49 +0000523 index += 1
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000524 elif sys.argv[index].startswith('-n'):
525 noHeaders = True
526 index += 1
Johnny Chen7c52ff12010-09-27 23:29:54 +0000527 elif sys.argv[index].startswith('-p'):
528 # Increment by 1 to fetch the reg exp pattern argument.
529 index += 1
530 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
531 usage()
532 regexp = sys.argv[index]
533 index += 1
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000534 elif sys.argv[index].startswith('-R'):
535 # Increment by 1 to fetch the relocated directory argument.
536 index += 1
537 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
538 usage()
539 rdir = os.path.abspath(sys.argv[index])
540 if os.path.exists(rdir):
541 import shutil
542 print "Removing tree:", rdir
543 shutil.rmtree(rdir)
544 index += 1
Johnny Chen548aefd2010-10-11 22:25:46 +0000545 elif sys.argv[index].startswith('-r'):
546 # Increment by 1 to fetch the relocated directory argument.
547 index += 1
548 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
549 usage()
550 rdir = os.path.abspath(sys.argv[index])
551 if os.path.exists(rdir):
552 print "Relocated directory:", rdir, "must not exist!"
553 usage()
554 index += 1
Johnny Chen028d8eb2011-11-17 19:57:27 +0000555 elif sys.argv[index].startswith('-S'):
556 skip_build_and_cleanup = True
557 index += 1
Johnny Chen125fc2b2010-10-21 16:55:35 +0000558 elif sys.argv[index].startswith('-s'):
559 # Increment by 1 to fetch the session dir name.
560 index += 1
561 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
562 usage()
563 sdir_name = sys.argv[index]
564 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000565 elif sys.argv[index].startswith('-t'):
566 os.environ["LLDB_COMMAND_TRACE"] = "YES"
567 index += 1
Johnny Chen0f907b82012-01-31 00:38:03 +0000568 elif sys.argv[index].startswith('-u'):
569 # Increment by 1 to fetch the environment variable to unset.
570 index += 1
571 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
572 usage()
573 unsets.append(sys.argv[index])
574 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000575 elif sys.argv[index].startswith('-v'):
576 verbose = 2
577 index += 1
Johnny Chene47649c2010-10-07 02:04:14 +0000578 elif sys.argv[index].startswith('-w'):
579 os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] = 'YES'
580 index += 1
Johnny Chene9eae812012-01-18 05:15:00 +0000581 elif sys.argv[index].startswith('-X'):
582 # Increment by 1 to fetch an excluded directory.
583 index += 1
584 if index >= len(sys.argv):
585 usage()
586 excluded.add(sys.argv[index])
587 index += 1
Johnny Chene00c9302011-10-10 22:03:44 +0000588 elif sys.argv[index].startswith('-x'):
589 # Increment by 1 to fetch the breakpoint specification of the benchmark executable.
590 index += 1
Johnny Chen8a1b1222011-10-20 22:16:24 +0000591 if index >= len(sys.argv):
Johnny Chene00c9302011-10-10 22:03:44 +0000592 usage()
593 bmBreakpointSpec = sys.argv[index]
594 index += 1
Johnny Chen5f2ed172011-10-20 18:43:28 +0000595 elif sys.argv[index].startswith('-y'):
596 # Increment by 1 to fetch the the benchmark iteration count.
597 index += 1
598 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
599 usage()
600 bmIterationCount = int(sys.argv[index])
601 index += 1
Johnny Chend2acdb32010-11-16 22:42:58 +0000602 elif sys.argv[index].startswith('-#'):
603 # Increment by 1 to fetch the repeat count argument.
604 index += 1
605 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
606 usage()
607 count = int(sys.argv[index])
608 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000609 else:
610 print "Unknown option: ", sys.argv[index]
611 usage()
Johnny Chenaf149a02010-09-16 17:11:30 +0000612
Jim Ingham4f347cb2011-04-13 21:11:41 +0000613 if do_help == True:
614 usage()
615
Johnny Chencc659ad2010-12-10 19:02:23 +0000616 # Do not specify both '-a' and '+a' at the same time.
617 if dont_do_python_api_test and just_do_python_api_test:
618 usage()
619
Johnny Chen08967192011-11-18 00:19:29 +0000620 # The simple progress bar is turned on only if verbose == 0 and LLDB_COMMAND_TRACE is not 'YES'
621 if ("LLDB_COMMAND_TRACE" not in os.environ or os.environ["LLDB_COMMAND_TRACE"]!="YES") and verbose==0:
622 progress_bar = True
623
Johnny Chenaf149a02010-09-16 17:11:30 +0000624 # Gather all the dirs passed on the command line.
625 if len(sys.argv) > index:
626 testdirs = map(os.path.abspath, sys.argv[index:])
627
Johnny Chen548aefd2010-10-11 22:25:46 +0000628 # If '-r dir' is specified, the tests should be run under the relocated
629 # directory. Let's copy the testdirs over.
630 if rdir:
631 from shutil import copytree, ignore_patterns
632
633 tmpdirs = []
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000634 orig_testdirs = testdirs[:]
Johnny Chen548aefd2010-10-11 22:25:46 +0000635 for srcdir in testdirs:
Johnny Chen1abe4c02012-03-20 00:33:51 +0000636 # For example, /Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/hello_watchpoint
637 # shall be split into ['/Volumes/data/lldb/svn/ToT/', 'functionalities/watchpoint/hello_watchpoint'].
638 # Utilize the relative path to the 'test' directory to make our destination dir path.
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000639 if ("test"+os.sep) in srcdir:
640 to_split_on = "test"+os.sep
641 else:
642 to_split_on = "test"
643 dstdir = os.path.join(rdir, srcdir.split(to_split_on)[1])
644 dstdir = dstdir.rstrip(os.sep)
Johnny Chen548aefd2010-10-11 22:25:46 +0000645 # Don't copy the *.pyc and .svn stuffs.
646 copytree(srcdir, dstdir, ignore=ignore_patterns('*.pyc', '.svn'))
647 tmpdirs.append(dstdir)
648
649 # This will be our modified testdirs.
650 testdirs = tmpdirs
651
652 # With '-r dir' specified, there's no cleanup of intermediate test files.
653 os.environ["LLDB_DO_CLEANUP"] = 'NO'
654
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000655 # If the original testdirs is ['test'], the make directory has already been copied
Johnny Chen548aefd2010-10-11 22:25:46 +0000656 # recursively and is contained within the rdir/test dir. For anything
657 # else, we would need to copy over the make directory and its contents,
658 # so that, os.listdir(rdir) looks like, for example:
659 #
660 # array_types conditional_break make
661 #
662 # where the make directory contains the Makefile.rules file.
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000663 if len(testdirs) != 1 or os.path.basename(orig_testdirs[0]) != 'test':
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000664 scriptdir = os.path.dirname(__file__)
Johnny Chen548aefd2010-10-11 22:25:46 +0000665 # Don't copy the .svn stuffs.
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000666 copytree(os.path.join(scriptdir, 'make'), os.path.join(rdir, 'make'),
Johnny Chen548aefd2010-10-11 22:25:46 +0000667 ignore=ignore_patterns('.svn'))
668
669 #print "testdirs:", testdirs
670
Johnny Chenb40056b2010-09-21 00:09:27 +0000671 # Source the configFile if specified.
672 # The side effect, if any, will be felt from this point on. An example
673 # config file may be these simple two lines:
674 #
675 # sys.stderr = open("/tmp/lldbtest-stderr", "w")
676 # sys.stdout = open("/tmp/lldbtest-stdout", "w")
677 #
678 # which will reassign the two file objects to sys.stderr and sys.stdout,
679 # respectively.
680 #
681 # See also lldb-trunk/example/test/usage-config.
Johnny Chenac97a6b2012-04-16 18:55:15 +0000682 global config, pre_flight, post_flight
Johnny Chenb40056b2010-09-21 00:09:27 +0000683 if configFile:
684 # Pass config (a dictionary) as the locals namespace for side-effect.
685 execfile(configFile, globals(), config)
Johnny Chenac97a6b2012-04-16 18:55:15 +0000686 print "config:", config
687 if "pre_flight" in config:
688 pre_flight = config["pre_flight"]
689 if not callable(pre_flight):
690 print "fatal error: pre_flight is not callable, exiting."
691 sys.exit(1)
692 if "post_flight" in config:
693 post_flight = config["post_flight"]
694 if not callable(post_flight):
695 print "fatal error: post_flight is not callable, exiting."
696 sys.exit(1)
Johnny Chenb40056b2010-09-21 00:09:27 +0000697 #print "sys.stderr:", sys.stderr
698 #print "sys.stdout:", sys.stdout
699
Johnny Chenaf149a02010-09-16 17:11:30 +0000700
Johnny Chen9707bb62010-06-25 21:14:08 +0000701def setupSysPath():
Johnny Chen8a3c0432011-03-11 20:13:06 +0000702 """
703 Add LLDB.framework/Resources/Python to the search paths for modules.
704 As a side effect, we also discover the 'lldb' executable and export it here.
705 """
Johnny Chen9707bb62010-06-25 21:14:08 +0000706
Johnny Chen548aefd2010-10-11 22:25:46 +0000707 global rdir
708 global testdirs
Johnny Chen50bc6382011-01-29 01:16:52 +0000709 global dumpSysPath
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000710 global noHeaders
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000711 global svn_info
Johnny Chen548aefd2010-10-11 22:25:46 +0000712
Johnny Chen9707bb62010-06-25 21:14:08 +0000713 # Get the directory containing the current script.
Johnny Chen4d162e52011-08-12 18:54:11 +0000714 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 +0000715 scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
716 else:
717 scriptPath = sys.path[0]
Johnny Chena1affab2010-07-03 03:41:59 +0000718 if not scriptPath.endswith('test'):
Johnny Chen9707bb62010-06-25 21:14:08 +0000719 print "This script expects to reside in lldb's test directory."
720 sys.exit(-1)
721
Johnny Chen548aefd2010-10-11 22:25:46 +0000722 if rdir:
723 # Set up the LLDB_TEST environment variable appropriately, so that the
724 # individual tests can be located relatively.
725 #
726 # See also lldbtest.TestBase.setUpClass(cls).
727 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
728 os.environ["LLDB_TEST"] = os.path.join(rdir, 'test')
729 else:
730 os.environ["LLDB_TEST"] = rdir
731 else:
732 os.environ["LLDB_TEST"] = scriptPath
Peter Collingbournef6c3de82011-06-20 19:06:45 +0000733
734 # Set up the LLDB_SRC environment variable, so that the tests can locate
735 # the LLDB source code.
736 os.environ["LLDB_SRC"] = os.path.join(sys.path[0], os.pardir)
737
Johnny Chen9de4ede2010-08-31 17:42:54 +0000738 pluginPath = os.path.join(scriptPath, 'plugins')
Johnny Chen8a3c0432011-03-11 20:13:06 +0000739 pexpectPath = os.path.join(scriptPath, 'pexpect-2.4')
Johnny Chen58f93922010-06-29 23:10:39 +0000740
Johnny Chen8a3c0432011-03-11 20:13:06 +0000741 # Append script dir, plugin dir, and pexpect dir to the sys.path.
Johnny Chenaf149a02010-09-16 17:11:30 +0000742 sys.path.append(scriptPath)
743 sys.path.append(pluginPath)
Johnny Chen8a3c0432011-03-11 20:13:06 +0000744 sys.path.append(pexpectPath)
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000745
Johnny Chen26901c82011-03-11 19:47:23 +0000746 # This is our base name component.
Johnny Chena1affab2010-07-03 03:41:59 +0000747 base = os.path.abspath(os.path.join(scriptPath, os.pardir))
Johnny Chen6a564a42011-02-15 18:50:19 +0000748
Johnny Chen26901c82011-03-11 19:47:23 +0000749 # These are for xcode build directories.
Johnny Chen6a564a42011-02-15 18:50:19 +0000750 xcode3_build_dir = ['build']
751 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
752 dbg = ['Debug']
753 rel = ['Release']
754 bai = ['BuildAndIntegration']
755 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
Johnny Chen26901c82011-03-11 19:47:23 +0000756
757 # Some of the tests can invoke the 'lldb' command directly.
758 # We'll try to locate the appropriate executable right here.
759
Johnny Chen6033bed2011-08-26 00:00:01 +0000760 # First, you can define an environment variable LLDB_EXEC specifying the
761 # full pathname of the lldb executable.
762 if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
763 lldbExec = os.environ["LLDB_EXEC"]
764 else:
765 lldbExec = None
766
Johnny Chen26901c82011-03-11 19:47:23 +0000767 executable = ['lldb']
768 dbgExec = os.path.join(base, *(xcode3_build_dir + dbg + executable))
769 dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
770 relExec = os.path.join(base, *(xcode3_build_dir + rel + executable))
771 relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
772 baiExec = os.path.join(base, *(xcode3_build_dir + bai + executable))
773 baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
774
Johnny Chen6033bed2011-08-26 00:00:01 +0000775 # The 'lldb' executable built here in the source tree.
776 lldbHere = None
Johnny Chen26901c82011-03-11 19:47:23 +0000777 if is_exe(dbgExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000778 lldbHere = dbgExec
Johnny Chen26901c82011-03-11 19:47:23 +0000779 elif is_exe(dbgExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000780 lldbHere = dbgExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000781 elif is_exe(relExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000782 lldbHere = relExec
Johnny Chen26901c82011-03-11 19:47:23 +0000783 elif is_exe(relExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000784 lldbHere = relExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000785 elif is_exe(baiExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000786 lldbHere = baiExec
Johnny Chen26901c82011-03-11 19:47:23 +0000787 elif is_exe(baiExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000788 lldbHere = baiExec2
Daniel Dunbar2bd310c2011-10-31 23:27:06 +0000789 elif lldbExec:
790 lldbHere = lldbExec
Johnny Chen26901c82011-03-11 19:47:23 +0000791
Johnny Chen6033bed2011-08-26 00:00:01 +0000792 if lldbHere:
793 os.environ["LLDB_HERE"] = lldbHere
Johnny Chen0409d992011-10-25 20:08:03 +0000794 os.environ["LLDB_BUILD_DIR"] = os.path.split(lldbHere)[0]
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000795 if not noHeaders:
796 print "LLDB build dir:", os.environ["LLDB_BUILD_DIR"]
Johnny Chen91da0052011-10-28 17:56:02 +0000797 os.system('%s -v' % lldbHere)
Johnny Chen62d527e2011-08-04 18:17:16 +0000798
Johnny Chen6033bed2011-08-26 00:00:01 +0000799 # One last chance to locate the 'lldb' executable.
Johnny Chen26901c82011-03-11 19:47:23 +0000800 if not lldbExec:
Johnny Chen0409d992011-10-25 20:08:03 +0000801 lldbExec = which('lldb')
802 if lldbHere and not lldbExec:
Johnny Chen6033bed2011-08-26 00:00:01 +0000803 lldbExec = lldbHere
Johnny Chen0409d992011-10-25 20:08:03 +0000804
Johnny Chen26901c82011-03-11 19:47:23 +0000805
806 if not lldbExec:
807 print "The 'lldb' executable cannot be located. Some of the tests may not be run as a result."
808 else:
809 os.environ["LLDB_EXEC"] = lldbExec
Johnny Chen8904eb02011-10-28 00:59:00 +0000810 #print "The 'lldb' from PATH env variable", lldbExec
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000811
Johnny Chenb264c9b2011-06-24 22:52:05 +0000812 if os.path.isdir(os.path.join(base, '.svn')):
813 pipe = subprocess.Popen(["svn", "info", base], stdout = subprocess.PIPE)
814 svn_info = pipe.stdout.read()
815 elif os.path.isdir(os.path.join(base, '.git')):
816 pipe = subprocess.Popen(["git", "svn", "info", base], stdout = subprocess.PIPE)
817 svn_info = pipe.stdout.read()
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000818 if not noHeaders:
819 print svn_info
Johnny Chen26901c82011-03-11 19:47:23 +0000820
821 global ignore
822
823 # The '-i' option is used to skip looking for lldb.py in the build tree.
824 if ignore:
825 return
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000826
Johnny Chen6a564a42011-02-15 18:50:19 +0000827 dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
828 dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
829 relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
830 relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
831 baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
832 baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
Johnny Chen9707bb62010-06-25 21:14:08 +0000833
834 lldbPath = None
Greg Clayton4e651b12012-04-25 00:58:03 +0000835 if os.path.isfile(os.path.join(dbgPath, 'lldb/__init__.py')):
Johnny Chen9707bb62010-06-25 21:14:08 +0000836 lldbPath = dbgPath
Greg Clayton4e651b12012-04-25 00:58:03 +0000837 elif os.path.isfile(os.path.join(dbgPath2, 'lldb/__init__.py')):
Greg Claytond9846b02011-02-14 21:17:06 +0000838 lldbPath = dbgPath2
Greg Clayton4e651b12012-04-25 00:58:03 +0000839 elif os.path.isfile(os.path.join(relPath, 'lldb/__init__.py')):
Johnny Chen9707bb62010-06-25 21:14:08 +0000840 lldbPath = relPath
Greg Clayton4e651b12012-04-25 00:58:03 +0000841 elif os.path.isfile(os.path.join(relPath2, 'lldb/__init__.py')):
Greg Claytond9846b02011-02-14 21:17:06 +0000842 lldbPath = relPath2
Greg Clayton4e651b12012-04-25 00:58:03 +0000843 elif os.path.isfile(os.path.join(baiPath, 'lldb/__init__.py')):
Johnny Chenc202c462010-09-15 18:11:19 +0000844 lldbPath = baiPath
Greg Clayton4e651b12012-04-25 00:58:03 +0000845 elif os.path.isfile(os.path.join(baiPath2, 'lldb/__init__.py')):
Greg Claytond9846b02011-02-14 21:17:06 +0000846 lldbPath = baiPath2
Johnny Chen9707bb62010-06-25 21:14:08 +0000847
848 if not lldbPath:
Johnny Chenc202c462010-09-15 18:11:19 +0000849 print 'This script requires lldb.py to be in either ' + dbgPath + ',',
850 print relPath + ', or ' + baiPath
Johnny Chen9707bb62010-06-25 21:14:08 +0000851 sys.exit(-1)
852
Johnny Chenaf149a02010-09-16 17:11:30 +0000853 # This is to locate the lldb.py module. Insert it right after sys.path[0].
854 sys.path[1:1] = [lldbPath]
Johnny Chen50bc6382011-01-29 01:16:52 +0000855 if dumpSysPath:
856 print "sys.path:", sys.path
Johnny Chen9707bb62010-06-25 21:14:08 +0000857
Johnny Chen9707bb62010-06-25 21:14:08 +0000858
Johnny Chencd0279d2010-09-20 18:07:50 +0000859def doDelay(delta):
860 """Delaying startup for delta-seconds to facilitate debugger attachment."""
861 def alarm_handler(*args):
862 raise Exception("timeout")
863
864 signal.signal(signal.SIGALRM, alarm_handler)
865 signal.alarm(delta)
866 sys.stdout.write("pid=%d\n" % os.getpid())
867 sys.stdout.write("Enter RET to proceed (or timeout after %d seconds):" %
868 delta)
869 sys.stdout.flush()
870 try:
871 text = sys.stdin.readline()
872 except:
873 text = ""
874 signal.alarm(0)
875 sys.stdout.write("proceeding...\n")
876 pass
877
878
Johnny Chen9707bb62010-06-25 21:14:08 +0000879def visit(prefix, dir, names):
880 """Visitor function for os.path.walk(path, visit, arg)."""
881
882 global suite
Johnny Chen7c52ff12010-09-27 23:29:54 +0000883 global regexp
Johnny Chenc5fa0052011-07-29 22:54:56 +0000884 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000885 global fs4all
Johnny Chene9eae812012-01-18 05:15:00 +0000886 global excluded
887
888 if set(dir.split(os.sep)).intersection(excluded):
889 #print "Detected an excluded dir component: %s" % dir
890 return
Johnny Chen9707bb62010-06-25 21:14:08 +0000891
892 for name in names:
893 if os.path.isdir(os.path.join(dir, name)):
894 continue
895
896 if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
Johnny Chen7c52ff12010-09-27 23:29:54 +0000897 # Try to match the regexp pattern, if specified.
898 if regexp:
899 import re
900 if re.search(regexp, name):
901 #print "Filename: '%s' matches pattern: '%s'" % (name, regexp)
902 pass
903 else:
904 #print "Filename: '%s' does not match pattern: '%s'" % (name, regexp)
905 continue
906
Johnny Chen953864a2010-10-12 21:35:54 +0000907 # We found a match for our test. Add it to the suite.
Johnny Chen79723352010-10-12 15:53:22 +0000908
909 # Update the sys.path first.
Johnny Chena85d7ee2010-06-26 00:19:32 +0000910 if not sys.path.count(dir):
Johnny Chen548aefd2010-10-11 22:25:46 +0000911 sys.path.insert(0, dir)
Johnny Chen9707bb62010-06-25 21:14:08 +0000912 base = os.path.splitext(name)[0]
Johnny Chenb62436b2010-10-06 20:40:56 +0000913
914 # Thoroughly check the filterspec against the base module and admit
915 # the (base, filterspec) combination only when it makes sense.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000916 filterspec = None
917 for filterspec in filters:
Johnny Chenb62436b2010-10-06 20:40:56 +0000918 # Optimistically set the flag to True.
919 filtered = True
920 module = __import__(base)
921 parts = filterspec.split('.')
922 obj = module
923 for part in parts:
924 try:
925 parent, obj = obj, getattr(obj, part)
926 except AttributeError:
927 # The filterspec has failed.
928 filtered = False
929 break
Johnny Chenc5fa0052011-07-29 22:54:56 +0000930
Johnny Chendb4be602011-08-12 23:55:07 +0000931 # If filtered, we have a good filterspec. Add it.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000932 if filtered:
Johnny Chendb4be602011-08-12 23:55:07 +0000933 #print "adding filter spec %s to module %s" % (filterspec, module)
934 suite.addTests(
935 unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
936 continue
Johnny Chenc5fa0052011-07-29 22:54:56 +0000937
938 # Forgo this module if the (base, filterspec) combo is invalid
939 # and no '-g' option is specified
940 if filters and fs4all and not filtered:
941 continue
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000942
Johnny Chendb4be602011-08-12 23:55:07 +0000943 # Add either the filtered test case(s) (which is done before) or the entire test class.
944 if not filterspec or not filtered:
Johnny Chenb62436b2010-10-06 20:40:56 +0000945 # A simple case of just the module name. Also the failover case
946 # from the filterspec branch when the (base, filterspec) combo
947 # doesn't make sense.
948 suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
Johnny Chen9707bb62010-06-25 21:14:08 +0000949
950
Johnny Chencd0279d2010-09-20 18:07:50 +0000951def lldbLoggings():
952 """Check and do lldb loggings if necessary."""
953
954 # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
955 # defined. Use ${LLDB_LOG} to specify the log file.
956 ci = lldb.DBG.GetCommandInterpreter()
957 res = lldb.SBCommandReturnObject()
958 if ("LLDB_LOG" in os.environ):
959 if ("LLDB_LOG_OPTION" in os.environ):
960 lldb_log_option = os.environ["LLDB_LOG_OPTION"]
961 else:
Johnny Chen8fd886c2010-12-08 01:25:21 +0000962 lldb_log_option = "event process expr state api"
Johnny Chencd0279d2010-09-20 18:07:50 +0000963 ci.HandleCommand(
Greg Clayton940b1032011-02-23 00:35:02 +0000964 "log enable -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option,
Johnny Chencd0279d2010-09-20 18:07:50 +0000965 res)
966 if not res.Succeeded():
967 raise Exception('log enable failed (check LLDB_LOG env variable.')
968 # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
969 # Use ${GDB_REMOTE_LOG} to specify the log file.
970 if ("GDB_REMOTE_LOG" in os.environ):
971 if ("GDB_REMOTE_LOG_OPTION" in os.environ):
972 gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
973 else:
Johnny Chen7ab8c852010-12-02 18:35:13 +0000974 gdb_remote_log_option = "packets process"
Johnny Chencd0279d2010-09-20 18:07:50 +0000975 ci.HandleCommand(
Johnny Chenc935a892011-06-21 19:25:45 +0000976 "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
Johnny Chencd0279d2010-09-20 18:07:50 +0000977 + gdb_remote_log_option,
978 res)
979 if not res.Succeeded():
980 raise Exception('log enable failed (check GDB_REMOTE_LOG env variable.')
981
Johnny Chen067022b2011-01-19 19:31:46 +0000982def getMyCommandLine():
Johnny Chen067022b2011-01-19 19:31:46 +0000983 ps = subprocess.Popen(['ps', '-o', "command=CMD", str(os.getpid())], stdout=subprocess.PIPE).communicate()[0]
984 lines = ps.split('\n')
985 cmd_line = lines[1]
986 return cmd_line
Johnny Chencd0279d2010-09-20 18:07:50 +0000987
Johnny Chend96b5682010-11-05 17:30:53 +0000988# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +0000989# #
990# Execution of the test driver starts here #
991# #
Johnny Chend96b5682010-11-05 17:30:53 +0000992# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +0000993
Johnny Chen2891bb02011-09-16 01:04:26 +0000994def checkDsymForUUIDIsNotOn():
Johnny Chen6a4e0872011-09-16 17:50:44 +0000995 cmd = ["defaults", "read", "com.apple.DebugSymbols"]
996 pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
997 cmd_output = pipe.stdout.read()
Johnny Chen178c8d92011-09-16 18:03:19 +0000998 if cmd_output and "DBGFileMappedPaths = " in cmd_output:
Johnny Chen6a451482011-09-16 18:09:45 +0000999 print "%s =>" % ' '.join(cmd)
Johnny Chen6a4e0872011-09-16 17:50:44 +00001000 print cmd_output
Johnny Chen2891bb02011-09-16 01:04:26 +00001001 print "Disable automatic lookup and caching of dSYMs before running the test suite!"
1002 print "Exiting..."
1003 sys.exit(0)
1004
1005# On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
1006# does not exist before proceeding to running the test suite.
1007if sys.platform.startswith("darwin"):
1008 checkDsymForUUIDIsNotOn()
1009
Johnny Chen9707bb62010-06-25 21:14:08 +00001010#
Johnny Chenaf149a02010-09-16 17:11:30 +00001011# Start the actions by first parsing the options while setting up the test
1012# directories, followed by setting up the search paths for lldb utilities;
1013# then, we walk the directory trees and collect the tests into our test suite.
Johnny Chen9707bb62010-06-25 21:14:08 +00001014#
Johnny Chenaf149a02010-09-16 17:11:30 +00001015parseOptionsAndInitTestdirs()
Johnny Chen9707bb62010-06-25 21:14:08 +00001016setupSysPath()
Johnny Chen91960d32010-09-08 20:56:16 +00001017
1018#
1019# If '-d' is specified, do a delay of 10 seconds for the debugger to attach.
1020#
1021if delay:
Johnny Chencd0279d2010-09-20 18:07:50 +00001022 doDelay(10)
Johnny Chen91960d32010-09-08 20:56:16 +00001023
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001024#
Johnny Chen41998192010-10-01 22:59:49 +00001025# If '-l' is specified, do not skip the long running tests.
Johnny Chen028d8eb2011-11-17 19:57:27 +00001026if not skip_long_running_test:
Johnny Chen41998192010-10-01 22:59:49 +00001027 os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
1028
1029#
Johnny Chen79723352010-10-12 15:53:22 +00001030# Walk through the testdirs while collecting tests.
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001031#
Johnny Chen9707bb62010-06-25 21:14:08 +00001032for testdir in testdirs:
1033 os.path.walk(testdir, visit, 'Test')
1034
Johnny Chenb40056b2010-09-21 00:09:27 +00001035#
Johnny Chen9707bb62010-06-25 21:14:08 +00001036# Now that we have loaded all the test cases, run the whole test suite.
Johnny Chenb40056b2010-09-21 00:09:27 +00001037#
Johnny Chencd0279d2010-09-20 18:07:50 +00001038
Johnny Chen1bfbd412010-06-29 19:44:16 +00001039# For the time being, let's bracket the test runner within the
1040# lldb.SBDebugger.Initialize()/Terminate() pair.
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001041import lldb, atexit
Johnny Chen6b6f5ba2010-10-14 16:36:49 +00001042# Update: the act of importing lldb now executes lldb.SBDebugger.Initialize(),
1043# there's no need to call it a second time.
1044#lldb.SBDebugger.Initialize()
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001045atexit.register(lambda: lldb.SBDebugger.Terminate())
Johnny Chen1bfbd412010-06-29 19:44:16 +00001046
Johnny Chen909e5a62010-07-01 22:52:57 +00001047# Create a singleton SBDebugger in the lldb namespace.
1048lldb.DBG = lldb.SBDebugger.Create()
1049
Johnny Chen4f93bf12010-12-10 00:51:23 +00001050# Put the blacklist in the lldb namespace, to be used by lldb.TestBase.
Johnny Chen82e6b1e2010-12-01 22:47:54 +00001051lldb.blacklist = blacklist
1052
Johnny Chenac97a6b2012-04-16 18:55:15 +00001053# The pre_flight and post_flight come from reading a config file.
1054lldb.pre_flight = pre_flight
1055lldb.post_flight = post_flight
1056def getsource_if_available(obj):
1057 """
1058 Return the text of the source code for an object if available. Otherwise,
1059 a print representation is returned.
1060 """
1061 import inspect
1062 try:
1063 return inspect.getsource(obj)
1064 except:
1065 return repr(obj)
1066
1067print "lldb.pre_flight:", getsource_if_available(lldb.pre_flight)
1068print "lldb.post_flight:", getsource_if_available(lldb.post_flight)
1069
Johnny Chena3ed7d82012-04-06 00:56:05 +00001070# Put all these test decorators in the lldb namespace.
Johnny Chen4f93bf12010-12-10 00:51:23 +00001071lldb.dont_do_python_api_test = dont_do_python_api_test
1072lldb.just_do_python_api_test = just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +00001073lldb.just_do_benchmarks_test = just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +00001074lldb.dont_do_dsym_test = dont_do_dsym_test
1075lldb.dont_do_dwarf_test = dont_do_dwarf_test
Johnny Chen4f93bf12010-12-10 00:51:23 +00001076
Johnny Chen028d8eb2011-11-17 19:57:27 +00001077# Do we need to skip build and cleanup?
1078lldb.skip_build_and_cleanup = skip_build_and_cleanup
1079
Johnny Chen5f2ed172011-10-20 18:43:28 +00001080# Put bmExecutable, bmBreakpointSpec, and bmIterationCount into the lldb namespace, too.
Johnny Chene00c9302011-10-10 22:03:44 +00001081lldb.bmExecutable = bmExecutable
1082lldb.bmBreakpointSpec = bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +00001083lldb.bmIterationCount = bmIterationCount
Johnny Chene00c9302011-10-10 22:03:44 +00001084
Johnny Chen38f823c2011-10-11 01:30:27 +00001085# And don't forget the runHooks!
1086lldb.runHooks = runHooks
1087
Johnny Chencd0279d2010-09-20 18:07:50 +00001088# Turn on lldb loggings if necessary.
1089lldbLoggings()
Johnny Chen909e5a62010-07-01 22:52:57 +00001090
Johnny Chen7987ac92010-08-09 20:40:52 +00001091# Install the control-c handler.
1092unittest2.signals.installHandler()
1093
Johnny Chen125fc2b2010-10-21 16:55:35 +00001094# If sdir_name is not specified through the '-s sdir_name' option, get a
1095# timestamp string and export it as LLDB_SESSION_DIR environment var. This will
1096# be used when/if we want to dump the session info of individual test cases
1097# later on.
Johnny Chence681462010-10-19 00:25:01 +00001098#
1099# See also TestBase.dumpSessionInfo() in lldbtest.py.
Johnny Chen125fc2b2010-10-21 16:55:35 +00001100if not sdir_name:
1101 import datetime
Johnny Chen41fae812010-10-29 22:26:38 +00001102 # The windows platforms don't like ':' in the pathname.
Johnny Chen76bd0102010-10-28 16:32:13 +00001103 timestamp = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
Johnny Chen125fc2b2010-10-21 16:55:35 +00001104 sdir_name = timestamp
Peter Collingbourne132476f2011-06-20 23:55:53 +00001105os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), sdir_name)
Johnny Chen067022b2011-01-19 19:31:46 +00001106
Johnny Chenfe5f1ed2011-10-21 18:33:27 +00001107if not noHeaders:
1108 sys.stderr.write("\nSession logs for test failures/errors/unexpected successes"
1109 " will go into directory '%s'\n" % sdir_name)
1110 sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
Johnny Chence681462010-10-19 00:25:01 +00001111
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001112if not os.path.isdir(sdir_name):
1113 os.mkdir(sdir_name)
1114fname = os.path.join(sdir_name, "svn-info")
1115with open(fname, "w") as f:
1116 print >> f, svn_info
1117 print >> f, "Command invoked: %s\n" % getMyCommandLine()
1118
Johnny Chenb40056b2010-09-21 00:09:27 +00001119#
Johnny Chen0f907b82012-01-31 00:38:03 +00001120# If we have environment variables to unset, do it here before we invoke the test runner.
1121#
1122for env_var in unsets :
1123 if env_var in os.environ:
1124 # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
Johnny Chen6346a292012-01-31 00:48:02 +00001125 # is automatically translated into a corresponding call to unsetenv().
Johnny Chen0f907b82012-01-31 00:38:03 +00001126 del os.environ[env_var]
1127 #os.unsetenv(env_var)
1128
1129#
Johnny Chenb40056b2010-09-21 00:09:27 +00001130# Invoke the default TextTestRunner to run the test suite, possibly iterating
1131# over different configurations.
1132#
1133
Johnny Chenb40056b2010-09-21 00:09:27 +00001134iterArchs = False
Johnny Chenf032d902010-09-21 00:16:09 +00001135iterCompilers = False
Johnny Chenb40056b2010-09-21 00:09:27 +00001136
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001137if not archs and "archs" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001138 archs = config["archs"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001139
1140if isinstance(archs, list) and len(archs) >= 1:
1141 iterArchs = True
1142
1143if not compilers and "compilers" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001144 compilers = config["compilers"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001145
Johnny Chen92693b52012-03-09 02:11:37 +00001146#
1147# Add some intervention here to sanity check that the compilers requested are sane.
1148# If found not to be an executable program, the invalid one is dropped from the list.
1149for i in range(len(compilers)):
1150 c = compilers[i]
1151 if which(c):
1152 continue
1153 else:
1154 if sys.platform.startswith("darwin"):
1155 pipe = subprocess.Popen(['xcrun', '-find', c], stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1156 cmd_output = pipe.stdout.read()
1157 if cmd_output:
1158 if "not found" in cmd_output:
1159 print "dropping %s from the compilers used" % c
1160 compilers.remove(i)
1161 else:
1162 compilers[i] = cmd_output.split('\n')[0]
1163 print "'xcrun -find %s' returning %s" % (c, compilers[i])
1164
1165print "compilers=%s" % str(compilers)
1166
1167if not compilers or len(compilers) == 0:
1168 print "No eligible compiler found, exiting."
1169 sys.exit(1)
1170
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001171if isinstance(compilers, list) and len(compilers) >= 1:
1172 iterCompilers = True
Johnny Chenb40056b2010-09-21 00:09:27 +00001173
Johnny Chen953864a2010-10-12 21:35:54 +00001174# Make a shallow copy of sys.path, we need to manipulate the search paths later.
1175# This is only necessary if we are relocated and with different configurations.
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001176if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001177 old_sys_path = sys.path[:]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001178# If we iterate on archs or compilers, there is a chance we want to split stderr/stdout.
1179if iterArchs or iterCompilers:
Johnny Chen953864a2010-10-12 21:35:54 +00001180 old_stderr = sys.stderr
1181 old_stdout = sys.stdout
1182 new_stderr = None
1183 new_stdout = None
1184
Johnny Chend96b5682010-11-05 17:30:53 +00001185# Iterating over all possible architecture and compiler combinations.
Johnny Chenb40056b2010-09-21 00:09:27 +00001186for ia in range(len(archs) if iterArchs else 1):
1187 archConfig = ""
1188 if iterArchs:
Johnny Chen18a921f2010-09-30 17:11:58 +00001189 os.environ["ARCH"] = archs[ia]
Johnny Chenb40056b2010-09-21 00:09:27 +00001190 archConfig = "arch=%s" % archs[ia]
1191 for ic in range(len(compilers) if iterCompilers else 1):
1192 if iterCompilers:
Johnny Chen18a921f2010-09-30 17:11:58 +00001193 os.environ["CC"] = compilers[ic]
Johnny Chenb40056b2010-09-21 00:09:27 +00001194 configString = "%s compiler=%s" % (archConfig, compilers[ic])
1195 else:
1196 configString = archConfig
1197
Johnny Chenb40056b2010-09-21 00:09:27 +00001198 if iterArchs or iterCompilers:
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001199 # Translate ' ' to '-' for pathname component.
1200 from string import maketrans
1201 tbl = maketrans(' ', '-')
1202 configPostfix = configString.translate(tbl)
1203
1204 # Check whether we need to split stderr/stdout into configuration
1205 # specific files.
1206 if old_stderr.name != '<stderr>' and config.get('split_stderr'):
1207 if new_stderr:
1208 new_stderr.close()
1209 new_stderr = open("%s.%s" % (old_stderr.name, configPostfix), "w")
1210 sys.stderr = new_stderr
1211 if old_stdout.name != '<stdout>' and config.get('split_stdout'):
1212 if new_stdout:
1213 new_stdout.close()
1214 new_stdout = open("%s.%s" % (old_stdout.name, configPostfix), "w")
1215 sys.stdout = new_stdout
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001216
Johnny Chen953864a2010-10-12 21:35:54 +00001217 # If we specified a relocated directory to run the test suite, do
1218 # the extra housekeeping to copy the testdirs to a configStringified
1219 # directory and to update sys.path before invoking the test runner.
1220 # The purpose is to separate the configuration-specific directories
1221 # from each other.
1222 if rdir:
Johnny Chen3bc7e5e2012-04-24 21:44:10 +00001223 from shutil import copytree, rmtree, ignore_patterns
Johnny Chen953864a2010-10-12 21:35:54 +00001224
Johnny Chen953864a2010-10-12 21:35:54 +00001225 newrdir = "%s.%s" % (rdir, configPostfix)
1226
1227 # Copy the tree to a new directory with postfix name configPostfix.
Johnny Chen3bc7e5e2012-04-24 21:44:10 +00001228 if os.path.exists(newrdir):
1229 rmtree(newrdir)
Johnny Chen953864a2010-10-12 21:35:54 +00001230 copytree(rdir, newrdir, ignore=ignore_patterns('*.pyc', '*.o', '*.d'))
1231
Filipe Cabecinhas0e1d06d2012-08-08 15:23:24 +00001232 # Update the LLDB_TEST environment variable to reflect new top
Johnny Chen953864a2010-10-12 21:35:54 +00001233 # level test directory.
1234 #
1235 # See also lldbtest.TestBase.setUpClass(cls).
1236 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
1237 os.environ["LLDB_TEST"] = os.path.join(newrdir, 'test')
1238 else:
1239 os.environ["LLDB_TEST"] = newrdir
1240
1241 # And update the Python search paths for modules.
1242 sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
1243
1244 # Output the configuration.
Johnny Chenb40056b2010-09-21 00:09:27 +00001245 sys.stderr.write("\nConfiguration: " + configString + "\n")
Johnny Chen953864a2010-10-12 21:35:54 +00001246
1247 #print "sys.stderr name is", sys.stderr.name
1248 #print "sys.stdout name is", sys.stdout.name
1249
1250 # First, write out the number of collected test cases.
Johnny Chen08967192011-11-18 00:19:29 +00001251 sys.stderr.write(separator + "\n")
1252 sys.stderr.write("Collected %d test%s\n\n"
1253 % (suite.countTestCases(),
1254 suite.countTestCases() != 1 and "s" or ""))
Johnny Chen953864a2010-10-12 21:35:54 +00001255
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001256 class LLDBTestResult(unittest2.TextTestResult):
1257 """
Johnny Chen26be4532010-11-09 23:56:14 +00001258 Enforce a singleton pattern to allow introspection of test progress.
1259
1260 Overwrite addError(), addFailure(), and addExpectedFailure() methods
1261 to enable each test instance to track its failure/error status. It
1262 is used in the LLDB test framework to emit detailed trace messages
1263 to a log file for easier human inspection of test failres/errors.
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001264 """
1265 __singleton__ = None
Johnny Chen360dd372010-11-29 17:50:10 +00001266 __ignore_singleton__ = False
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001267
1268 def __init__(self, *args):
Johnny Chen360dd372010-11-29 17:50:10 +00001269 if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
Johnny Chend2acdb32010-11-16 22:42:58 +00001270 raise Exception("LLDBTestResult instantiated more than once")
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001271 super(LLDBTestResult, self).__init__(*args)
1272 LLDBTestResult.__singleton__ = self
1273 # Now put this singleton into the lldb module namespace.
1274 lldb.test_result = self
Johnny Chen810042e2011-01-05 20:24:11 +00001275 # Computes the format string for displaying the counter.
1276 global suite
1277 counterWidth = len(str(suite.countTestCases()))
1278 self.fmt = "%" + str(counterWidth) + "d: "
Johnny Chenc87fd492011-01-05 22:50:11 +00001279 self.indentation = ' ' * (counterWidth + 2)
Johnny Chen810042e2011-01-05 20:24:11 +00001280 # This counts from 1 .. suite.countTestCases().
1281 self.counter = 0
1282
Johnny Chenbe452272012-04-19 21:33:55 +00001283 def _exc_info_to_string(self, err, test):
1284 """Overrides superclass TestResult's method in order to append
1285 our test config info string to the exception info string."""
1286 modified_exc_string = '%sConfig=%s-%s' % (super(LLDBTestResult, self)._exc_info_to_string(err, test),
1287 test.getArchitecture(),
1288 test.getCompiler())
1289 return modified_exc_string
1290
Johnny Chenc87fd492011-01-05 22:50:11 +00001291 def getDescription(self, test):
1292 doc_first_line = test.shortDescription()
1293 if self.descriptions and doc_first_line:
1294 return '\n'.join((str(test), self.indentation + doc_first_line))
1295 else:
1296 return str(test)
1297
Johnny Chen810042e2011-01-05 20:24:11 +00001298 def startTest(self, test):
1299 self.counter += 1
1300 if self.showAll:
1301 self.stream.write(self.fmt % self.counter)
1302 super(LLDBTestResult, self).startTest(test)
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001303
Johnny Chence681462010-10-19 00:25:01 +00001304 def addError(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001305 global sdir_has_content
1306 sdir_has_content = True
Johnny Chence681462010-10-19 00:25:01 +00001307 super(LLDBTestResult, self).addError(test, err)
1308 method = getattr(test, "markError", None)
1309 if method:
1310 method()
1311
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001312 def addFailure(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001313 global sdir_has_content
1314 sdir_has_content = True
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001315 super(LLDBTestResult, self).addFailure(test, err)
1316 method = getattr(test, "markFailure", None)
1317 if method:
1318 method()
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001319
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001320 def addExpectedFailure(self, test, err):
1321 global sdir_has_content
1322 sdir_has_content = True
1323 super(LLDBTestResult, self).addExpectedFailure(test, err)
1324 method = getattr(test, "markExpectedFailure", None)
1325 if method:
1326 method()
1327
Johnny Chenf5b89092011-08-15 23:09:08 +00001328 def addSkip(self, test, reason):
1329 global sdir_has_content
1330 sdir_has_content = True
1331 super(LLDBTestResult, self).addSkip(test, reason)
1332 method = getattr(test, "markSkippedTest", None)
1333 if method:
1334 method()
1335
Johnny Chenab2f0662011-05-06 20:30:22 +00001336 def addUnexpectedSuccess(self, test):
1337 global sdir_has_content
1338 sdir_has_content = True
1339 super(LLDBTestResult, self).addUnexpectedSuccess(test)
1340 method = getattr(test, "markUnexpectedSuccess", None)
1341 if method:
1342 method()
1343
Johnny Chen26be4532010-11-09 23:56:14 +00001344 # Invoke the test runner.
Johnny Chend2acdb32010-11-16 22:42:58 +00001345 if count == 1:
Johnny Chen7d6d8442010-12-03 19:59:35 +00001346 result = unittest2.TextTestRunner(stream=sys.stderr,
Johnny Chene6d88a82012-04-19 20:09:44 +00001347 verbosity=(1 if progress_bar else verbose),
Johnny Chen7d6d8442010-12-03 19:59:35 +00001348 failfast=failfast,
Johnny Chend2acdb32010-11-16 22:42:58 +00001349 resultclass=LLDBTestResult).run(suite)
1350 else:
Johnny Chend6e7ca22010-11-29 17:52:43 +00001351 # We are invoking the same test suite more than once. In this case,
1352 # mark __ignore_singleton__ flag as True so the signleton pattern is
1353 # not enforced.
Johnny Chen360dd372010-11-29 17:50:10 +00001354 LLDBTestResult.__ignore_singleton__ = True
Johnny Chend2acdb32010-11-16 22:42:58 +00001355 for i in range(count):
Johnny Chen7d6d8442010-12-03 19:59:35 +00001356 result = unittest2.TextTestRunner(stream=sys.stderr,
Johnny Chene6d88a82012-04-19 20:09:44 +00001357 verbosity=(1 if progress_bar else verbose),
Johnny Chen7d6d8442010-12-03 19:59:35 +00001358 failfast=failfast,
Johnny Chen360dd372010-11-29 17:50:10 +00001359 resultclass=LLDBTestResult).run(suite)
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001360
Johnny Chen1bfbd412010-06-29 19:44:16 +00001361
Johnny Chen63c2cba2010-10-29 22:20:36 +00001362if sdir_has_content:
Johnny Chenab2f0662011-05-06 20:30:22 +00001363 sys.stderr.write("Session logs for test failures/errors/unexpected successes"
1364 " can be found in directory '%s'\n" % sdir_name)
Johnny Chen63c2cba2010-10-29 22:20:36 +00001365
Johnny Chencd0279d2010-09-20 18:07:50 +00001366# Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1367# This should not be necessary now.
Johnny Chen83f6e512010-08-13 22:58:44 +00001368if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
Johnny Chen83f6e512010-08-13 22:58:44 +00001369 print "Terminating Test suite..."
1370 subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1371
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001372# Exiting.
1373sys.exit(not result.wasSuccessful)