blob: 7cd334f2d094148f1fd2f74f083d3e95197eb704 [file] [log] [blame]
Johnny Chen9707bb62010-06-25 21:14:08 +00001#!/usr/bin/env python
2
3"""
4A simple testing framework for lldb using python's unit testing framework.
5
6Tests for lldb are written as python scripts which take advantage of the script
7bridging provided by LLDB.framework to interact with lldb core.
8
9A specific naming pattern is followed by the .py script to be recognized as
10a module which implements a test scenario, namely, Test*.py.
11
12To specify the directories where "Test*.py" python test scripts are located,
13you need to pass in a list of directory names. By default, the current
14working directory is searched if nothing is specified on the command line.
Johnny Chen872aee12010-09-16 15:44:23 +000015
16Type:
17
18./dotest.py -h
19
20for available options.
Johnny Chen9707bb62010-06-25 21:14:08 +000021"""
22
Johnny Chen91960d32010-09-08 20:56:16 +000023import os, signal, sys, time
Johnny Chen2891bb02011-09-16 01:04:26 +000024import subprocess
Johnny Chen75e28f92010-08-05 23:42:46 +000025import unittest2
Johnny Chen9707bb62010-06-25 21:14:08 +000026
Johnny Chen26901c82011-03-11 19:47:23 +000027def is_exe(fpath):
Johnny Chenf2c7b282011-04-26 23:10:51 +000028 """Returns true if fpath is an executable."""
Johnny Chen26901c82011-03-11 19:47:23 +000029 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
30
Johnny Chen26901c82011-03-11 19:47:23 +000031def which(program):
Johnny Chenf2c7b282011-04-26 23:10:51 +000032 """Returns the full path to a program; None otherwise."""
Johnny Chen26901c82011-03-11 19:47:23 +000033 fpath, fname = os.path.split(program)
34 if fpath:
35 if is_exe(program):
36 return program
37 else:
38 for path in os.environ["PATH"].split(os.pathsep):
39 exe_file = os.path.join(path, program)
40 if is_exe(exe_file):
41 return exe_file
42 return None
43
Johnny Chen877c7e42010-08-07 00:16:07 +000044class _WritelnDecorator(object):
45 """Used to decorate file-like objects with a handy 'writeln' method"""
46 def __init__(self,stream):
47 self.stream = stream
48
49 def __getattr__(self, attr):
50 if attr in ('stream', '__getstate__'):
51 raise AttributeError(attr)
52 return getattr(self.stream,attr)
53
54 def writeln(self, arg=None):
55 if arg:
56 self.write(arg)
57 self.write('\n') # text-mode streams translate to \r\n if needed
58
Johnny Chen9707bb62010-06-25 21:14:08 +000059#
60# Global variables:
61#
62
63# The test suite.
Johnny Chen75e28f92010-08-05 23:42:46 +000064suite = unittest2.TestSuite()
Johnny Chen9707bb62010-06-25 21:14:08 +000065
Johnny Chen4f93bf12010-12-10 00:51:23 +000066# By default, both command line and Python API tests are performed.
Johnny Chen3ebdacc2010-12-10 18:52:10 +000067# Use @python_api_test decorator, defined in lldbtest.py, to mark a test as
68# a Python API test.
Johnny Chen4f93bf12010-12-10 00:51:23 +000069dont_do_python_api_test = False
70
71# By default, both command line and Python API tests are performed.
Johnny Chen4f93bf12010-12-10 00:51:23 +000072just_do_python_api_test = False
73
Johnny Chen82ccf402011-07-30 01:39:58 +000074# By default, benchmarks tests are not run.
75just_do_benchmarks_test = False
76
Johnny Chen82e6b1e2010-12-01 22:47:54 +000077# The blacklist is optional (-b blacklistFile) and allows a central place to skip
78# testclass's and/or testclass.testmethod's.
79blacklist = None
80
81# The dictionary as a result of sourcing blacklistFile.
82blacklistConfig = {}
83
Johnny Chen9fdb0a92010-09-18 00:16:47 +000084# The config file is optional.
85configFile = None
86
Johnny Chend2acdb32010-11-16 22:42:58 +000087# Test suite repeat count. Can be overwritten with '-# count'.
88count = 1
89
Johnny Chenb40056b2010-09-21 00:09:27 +000090# The dictionary as a result of sourcing configFile.
91config = {}
92
Johnny Chen1a4d5e72011-03-04 01:35:22 +000093# The 'archs' and 'compilers' can be specified via either command line or configFile,
94# with the command line overriding the configFile. When specified, they should be
95# of the list type. For example, "-A x86_64^i386" => archs=['x86_64', 'i386'] and
96# "-C gcc^clang" => compilers=['gcc', 'clang'].
97archs = None
98compilers = None
99
Johnny Chen91960d32010-09-08 20:56:16 +0000100# Delay startup in order for the debugger to attach.
101delay = False
102
Johnny Chend5362332011-01-29 01:21:04 +0000103# Dump the Python sys.path variable. Use '-D' to dump sys.path.
Johnny Chen50bc6382011-01-29 01:16:52 +0000104dumpSysPath = False
105
Johnny Chene00c9302011-10-10 22:03:44 +0000106# Full path of the benchmark executable, as specified by the '-e' option.
107bmExecutable = None
108# The breakpoint specification of bmExecutable, as specified by the '-x' option.
109bmBreakpointSpec = None
Johnny Chen5f2ed172011-10-20 18:43:28 +0000110# The benchamrk iteration count, as specified by the '-y' option.
111bmIterationCount = -1
Johnny Chene00c9302011-10-10 22:03:44 +0000112
Johnny Chen7d6d8442010-12-03 19:59:35 +0000113# By default, failfast is False. Use '-F' to overwrite it.
114failfast = False
115
Johnny Chenc5fa0052011-07-29 22:54:56 +0000116# The filters (testclass.testmethod) used to admit tests into our test suite.
117filters = []
Johnny Chenb62436b2010-10-06 20:40:56 +0000118
Johnny Chen38f823c2011-10-11 01:30:27 +0000119# The runhooks is a list of lldb commands specifically for the debugger.
120# Use '-k' to specify a runhook.
121runHooks = []
122
Johnny Chena224cd12010-11-08 01:21:03 +0000123# If '-g' is specified, the filterspec is not exclusive. If a test module does
124# not contain testclass.testmethod which matches the filterspec, the whole test
125# module is still admitted into our test suite. fs4all flag defaults to True.
126fs4all = True
Johnny Chenb62436b2010-10-06 20:40:56 +0000127
Johnny Chenaf149a02010-09-16 17:11:30 +0000128# Ignore the build search path relative to this script to locate the lldb.py module.
129ignore = False
130
Johnny Chen028d8eb2011-11-17 19:57:27 +0000131# By default, we do not skip build and cleanup. Use '-S' option to override.
132skip_build_and_cleanup = False
133
Johnny Chen548aefd2010-10-11 22:25:46 +0000134# By default, we skip long running test case. Use '-l' option to override.
Johnny Chen028d8eb2011-11-17 19:57:27 +0000135skip_long_running_test = True
Johnny Chen41998192010-10-01 22:59:49 +0000136
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000137# By default, we print the build dir, lldb version, and svn info. Use '-n' option to
138# turn it off.
139noHeaders = False
140
Johnny Chen7c52ff12010-09-27 23:29:54 +0000141# The regular expression pattern to match against eligible filenames as our test cases.
142regexp = None
143
Johnny Chen548aefd2010-10-11 22:25:46 +0000144# By default, tests are executed in place and cleanups are performed afterwards.
145# Use '-r dir' option to relocate the tests and their intermediate files to a
146# different directory and to forgo any cleanups. The directory specified must
147# not exist yet.
148rdir = None
149
Johnny Chen125fc2b2010-10-21 16:55:35 +0000150# By default, recorded session info for errored/failed test are dumped into its
151# own file under a session directory named after the timestamp of the test suite
152# run. Use '-s session-dir-name' to specify a specific dir name.
153sdir_name = None
154
Johnny Chen63c2cba2010-10-29 22:20:36 +0000155# Set this flag if there is any session info dumped during the test run.
156sdir_has_content = False
157
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000158# svn_info stores the output from 'svn info lldb.base.dir'.
159svn_info = ''
160
Johnny Chen9707bb62010-06-25 21:14:08 +0000161# Default verbosity is 0.
162verbose = 0
163
Johnny Chen08967192011-11-18 00:19:29 +0000164# Set to True only if verbose is 0 and LLDB trace mode is off.
165progress_bar = False
166
Peter Collingbourne61aca482011-06-20 19:06:29 +0000167# By default, search from the script directory.
168testdirs = [ sys.path[0] ]
Johnny Chen9707bb62010-06-25 21:14:08 +0000169
Johnny Chen877c7e42010-08-07 00:16:07 +0000170# Separator string.
171separator = '-' * 70
172
Johnny Chen9707bb62010-06-25 21:14:08 +0000173
174def usage():
175 print """
176Usage: dotest.py [option] [args]
177where options:
Jim Ingham4f347cb2011-04-13 21:11:41 +0000178-h : print this help message and exit. Add '-v' for more detailed help.
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000179-A : specify the architecture(s) to launch for the inferior process
180 -A i386 => launch inferior with i386 architecture
181 -A x86_64^i386 => launch inferior with x86_64 and i386 architectures
182-C : specify the compiler(s) used to build the inferior executable
183 -C clang => build debuggee using clang compiler
184 -C clang^gcc => build debuggee using clang and gcc compilers
Johnny Chen50bc6382011-01-29 01:16:52 +0000185-D : dump the Python sys.path variable
Johnny Chen4f93bf12010-12-10 00:51:23 +0000186-a : don't do lldb Python API tests
187 use @python_api_test to decorate a test case as lldb Python API test
Johnny Chen3ebdacc2010-12-10 18:52:10 +0000188+a : just do lldb Python API tests
Johnny Chencc659ad2010-12-10 19:02:23 +0000189 do not specify both '-a' and '+a' at the same time
Johnny Chen82ccf402011-07-30 01:39:58 +0000190+b : just do benchmark tests
191 use @benchmark_test to decorate a test case as such
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000192-b : read a blacklist file specified after this option
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000193-c : read a config file specified after this option
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000194 the architectures and compilers (note the plurals) specified via '-A' and '-C'
195 will override those specified via a config file
Johnny Chenb40056b2010-09-21 00:09:27 +0000196 (see also lldb-trunk/example/test/usage-config)
Johnny Chen91960d32010-09-08 20:56:16 +0000197-d : delay startup for 10 seconds (in order for the debugger to attach)
Johnny Chene00c9302011-10-10 22:03:44 +0000198-e : specify the full path of an executable used for benchmark purpose;
199 see also '-x', which provides the breakpoint sepcification
Johnny Chen7d6d8442010-12-03 19:59:35 +0000200-F : failfast, stop the test suite on the first error/failure
Johnny Chen46be75d2010-10-11 16:19:48 +0000201-f : specify a filter, which consists of the test class name, a dot, followed by
Johnny Chen1a6e92a2010-11-08 20:17:04 +0000202 the test method, to only admit such test into the test suite
Johnny Chenb62436b2010-10-06 20:40:56 +0000203 e.g., -f 'ClassTypesTestCase.test_with_dwarf_and_python_api'
Johnny Chena224cd12010-11-08 01:21:03 +0000204-g : if specified, the filterspec by -f is not exclusive, i.e., if a test module
205 does not match the filterspec (testclass.testmethod), the whole module is
206 still admitted to the test suite
Johnny Chenaf149a02010-09-16 17:11:30 +0000207-i : ignore (don't bailout) if 'lldb.py' module cannot be located in the build
208 tree relative to this script; use PYTHONPATH to locate the module
Johnny Chen38f823c2011-10-11 01:30:27 +0000209-k : specify a runhook, which is an lldb command to be executed by the debugger;
210 '-k' option can occur multiple times, the commands are executed one after the
211 other to bring the debugger to a desired state, so that, for example, further
212 benchmarking can be done
Johnny Chen41998192010-10-01 22:59:49 +0000213-l : don't skip long running test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000214-n : don't print the headers like build dir, lldb version, and svn info at all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000215-p : specify a regexp filename pattern for inclusion in the test suite
Johnny Chen548aefd2010-10-11 22:25:46 +0000216-r : specify a dir to relocate the tests and their intermediate files to;
217 the directory must not exist before running this test driver;
218 no cleanup of intermediate test files is performed in this case
Johnny Chen028d8eb2011-11-17 19:57:27 +0000219-S : skip the build and cleanup while running the test
220 use this option with care as you would need to build the inferior(s) by hand
221 and build the executable(s) with the correct name(s)
222 this can be used with '-# n' to stress test certain test cases for n number of
223 times
Johnny Chen125fc2b2010-10-21 16:55:35 +0000224-s : specify the name of the dir created to store the session files of tests
225 with errored or failed status; if not specified, the test driver uses the
226 timestamp as the session dir name
Johnny Chena2486f22011-04-21 20:48:32 +0000227-t : turn on tracing of lldb command and other detailed test executions
228-v : do verbose mode of unittest framework (print out each test case invocation)
Johnny Chene00c9302011-10-10 22:03:44 +0000229-x : specify the breakpoint specification for the benchmark executable;
230 see also '-e', which provides the full path of the executable
Johnny Chen5f2ed172011-10-20 18:43:28 +0000231-y : specify the iteration count used to collect our benchmarks; an example is
232 the number of times to do 'thread step-over' to measure stepping speed
233 see also '-e' and '-x' options
Johnny Chene47649c2010-10-07 02:04:14 +0000234-w : insert some wait time (currently 0.5 sec) between consecutive test cases
Johnny Chend2acdb32010-11-16 22:42:58 +0000235-# : Repeat the test suite for a specified number of times
Johnny Chen9707bb62010-06-25 21:14:08 +0000236
237and:
Johnny Chen9656ab22010-10-22 19:00:18 +0000238args : specify a list of directory names to search for test modules named after
239 Test*.py (test discovery)
Peter Collingbourne5f2b5d62011-06-14 03:55:45 +0000240 if empty, search from the current working directory, instead
Jim Ingham4f347cb2011-04-13 21:11:41 +0000241"""
Johnny Chen58f93922010-06-29 23:10:39 +0000242
Jim Ingham4f347cb2011-04-13 21:11:41 +0000243 if verbose > 0:
244 print """
Johnny Chen9656ab22010-10-22 19:00:18 +0000245Examples:
246
Johnny Chena224cd12010-11-08 01:21:03 +0000247This is an example of using the -f option to pinpoint to a specfic test class
248and test method to be run:
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000249
Johnny Chena224cd12010-11-08 01:21:03 +0000250$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000251----------------------------------------------------------------------
252Collected 1 test
253
254test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
255Test 'frame variable this' when stopped on a class constructor. ... ok
256
257----------------------------------------------------------------------
258Ran 1 test in 1.396s
259
260OK
Johnny Chen9656ab22010-10-22 19:00:18 +0000261
262And this is an example of using the -p option to run a single file (the filename
263matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
264
265$ ./dotest.py -v -p ObjC
266----------------------------------------------------------------------
267Collected 4 tests
268
269test_break_with_dsym (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000270Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000271test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000272Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000273test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
274Lookup objective-c data types and evaluate expressions. ... ok
275test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
276Lookup objective-c data types and evaluate expressions. ... ok
277
278----------------------------------------------------------------------
279Ran 4 tests in 16.661s
280
281OK
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000282
Johnny Chen58f93922010-06-29 23:10:39 +0000283Running of this script also sets up the LLDB_TEST environment variable so that
Johnny Chenaf149a02010-09-16 17:11:30 +0000284individual test cases can locate their supporting files correctly. The script
285tries to set up Python's search paths for modules by looking at the build tree
Johnny Chena85859f2010-11-11 22:14:56 +0000286relative to this script. See also the '-i' option in the following example.
287
288Finally, this is an example of using the lldb.py module distributed/installed by
289Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
290option to add some delay between two tests. It uses ARCH=x86_64 to specify that
291as the architecture and CC=clang to specify the compiler used for the test run:
292
293$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
294
295Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
296----------------------------------------------------------------------
297Collected 2 tests
298
299test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
300Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
301test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
302Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
303
304----------------------------------------------------------------------
305Ran 2 tests in 5.659s
306
307OK
308
309The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
310notify the directory containing the session logs for test failures or errors.
311In case there is any test failure/error, a similar message is appended at the
312end of the stderr output for your convenience.
Johnny Chenfde69bc2010-09-14 22:01:40 +0000313
314Environment variables related to loggings:
315
316o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
317 with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
318
319o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
320 'process.gdb-remote' subsystem with a default option of 'packets' if
321 GDB_REMOTE_LOG_OPTION is not defined.
Johnny Chen9707bb62010-06-25 21:14:08 +0000322"""
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000323 sys.exit(0)
Johnny Chen9707bb62010-06-25 21:14:08 +0000324
325
Johnny Chenaf149a02010-09-16 17:11:30 +0000326def parseOptionsAndInitTestdirs():
327 """Initialize the list of directories containing our unittest scripts.
328
329 '-h/--help as the first option prints out usage info and exit the program.
330 """
331
Johnny Chen4f93bf12010-12-10 00:51:23 +0000332 global dont_do_python_api_test
333 global just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000334 global just_do_benchmarks_test
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000335 global blacklist
336 global blacklistConfig
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000337 global configFile
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000338 global archs
339 global compilers
Johnny Chend2acdb32010-11-16 22:42:58 +0000340 global count
Johnny Chenaf149a02010-09-16 17:11:30 +0000341 global delay
Johnny Chen50bc6382011-01-29 01:16:52 +0000342 global dumpSysPath
Johnny Chene00c9302011-10-10 22:03:44 +0000343 global bmExecutable
344 global bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000345 global bmIterationCount
Johnny Chen7d6d8442010-12-03 19:59:35 +0000346 global failfast
Johnny Chenc5fa0052011-07-29 22:54:56 +0000347 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000348 global fs4all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000349 global ignore
Johnny Chen08967192011-11-18 00:19:29 +0000350 global progress_bar
Johnny Chen38f823c2011-10-11 01:30:27 +0000351 global runHooks
Johnny Chen028d8eb2011-11-17 19:57:27 +0000352 global skip_build_and_cleanup
353 global skip_long_running_test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000354 global noHeaders
Johnny Chen7c52ff12010-09-27 23:29:54 +0000355 global regexp
Johnny Chen548aefd2010-10-11 22:25:46 +0000356 global rdir
Johnny Chen125fc2b2010-10-21 16:55:35 +0000357 global sdir_name
Johnny Chenaf149a02010-09-16 17:11:30 +0000358 global verbose
359 global testdirs
360
Jim Ingham4f347cb2011-04-13 21:11:41 +0000361 do_help = False
362
Johnny Chenaf149a02010-09-16 17:11:30 +0000363 if len(sys.argv) == 1:
364 return
365
366 # Process possible trace and/or verbose flag, among other things.
367 index = 1
Johnny Chence2212c2010-10-07 15:41:55 +0000368 while index < len(sys.argv):
Johnny Chen4f93bf12010-12-10 00:51:23 +0000369 if sys.argv[index].startswith('-') or sys.argv[index].startswith('+'):
370 # We should continue processing...
371 pass
372 else:
Johnny Chenaf149a02010-09-16 17:11:30 +0000373 # End of option processing.
374 break
375
376 if sys.argv[index].find('-h') != -1:
Jim Ingham4f347cb2011-04-13 21:11:41 +0000377 index += 1
378 do_help = True
Johnny Chen012cba12011-01-26 19:07:42 +0000379 elif sys.argv[index].startswith('-A'):
380 # Increment by 1 to fetch the ARCH spec.
381 index += 1
382 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
383 usage()
Johnny Cheneee9b862011-04-26 20:45:00 +0000384 archs = sys.argv[index].split('^')
Johnny Chen012cba12011-01-26 19:07:42 +0000385 index += 1
386 elif sys.argv[index].startswith('-C'):
387 # Increment by 1 to fetch the CC spec.
388 index += 1
389 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
390 usage()
Johnny Cheneee9b862011-04-26 20:45:00 +0000391 compilers = sys.argv[index].split('^')
Johnny Chen012cba12011-01-26 19:07:42 +0000392 index += 1
Johnny Chen50bc6382011-01-29 01:16:52 +0000393 elif sys.argv[index].startswith('-D'):
394 dumpSysPath = True
395 index += 1
Johnny Chen4f93bf12010-12-10 00:51:23 +0000396 elif sys.argv[index].startswith('-a'):
397 dont_do_python_api_test = True
398 index += 1
399 elif sys.argv[index].startswith('+a'):
400 just_do_python_api_test = True
401 index += 1
Johnny Chen82ccf402011-07-30 01:39:58 +0000402 elif sys.argv[index].startswith('+b'):
403 just_do_benchmarks_test = True
404 index += 1
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000405 elif sys.argv[index].startswith('-b'):
406 # Increment by 1 to fetch the blacklist file name option argument.
407 index += 1
408 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
409 usage()
410 blacklistFile = sys.argv[index]
411 if not os.path.isfile(blacklistFile):
412 print "Blacklist file:", blacklistFile, "does not exist!"
413 usage()
414 index += 1
415 # Now read the blacklist contents and assign it to blacklist.
416 execfile(blacklistFile, globals(), blacklistConfig)
417 blacklist = blacklistConfig.get('blacklist')
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000418 elif sys.argv[index].startswith('-c'):
419 # Increment by 1 to fetch the config file name option argument.
420 index += 1
421 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
422 usage()
423 configFile = sys.argv[index]
424 if not os.path.isfile(configFile):
425 print "Config file:", configFile, "does not exist!"
426 usage()
427 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000428 elif sys.argv[index].startswith('-d'):
429 delay = True
430 index += 1
Johnny Chene00c9302011-10-10 22:03:44 +0000431 elif sys.argv[index].startswith('-e'):
432 # Increment by 1 to fetch the full path of the benchmark executable.
433 index += 1
434 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
435 usage()
436 bmExecutable = sys.argv[index]
437 if not is_exe(bmExecutable):
438 usage()
439 index += 1
Johnny Chen7d6d8442010-12-03 19:59:35 +0000440 elif sys.argv[index].startswith('-F'):
441 failfast = True
442 index += 1
Johnny Chenb62436b2010-10-06 20:40:56 +0000443 elif sys.argv[index].startswith('-f'):
444 # Increment by 1 to fetch the filter spec.
445 index += 1
446 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
447 usage()
Johnny Chenc5fa0052011-07-29 22:54:56 +0000448 filters.append(sys.argv[index])
Johnny Chenb62436b2010-10-06 20:40:56 +0000449 index += 1
450 elif sys.argv[index].startswith('-g'):
Johnny Chena224cd12010-11-08 01:21:03 +0000451 fs4all = False
Johnny Chenb62436b2010-10-06 20:40:56 +0000452 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000453 elif sys.argv[index].startswith('-i'):
454 ignore = True
455 index += 1
Johnny Chen38f823c2011-10-11 01:30:27 +0000456 elif sys.argv[index].startswith('-k'):
457 # Increment by 1 to fetch the runhook lldb command.
458 index += 1
459 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
460 usage()
461 runHooks.append(sys.argv[index])
462 index += 1
Johnny Chen41998192010-10-01 22:59:49 +0000463 elif sys.argv[index].startswith('-l'):
Johnny Chen028d8eb2011-11-17 19:57:27 +0000464 skip_long_running_test = False
Johnny Chen41998192010-10-01 22:59:49 +0000465 index += 1
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000466 elif sys.argv[index].startswith('-n'):
467 noHeaders = True
468 index += 1
Johnny Chen7c52ff12010-09-27 23:29:54 +0000469 elif sys.argv[index].startswith('-p'):
470 # Increment by 1 to fetch the reg exp pattern argument.
471 index += 1
472 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
473 usage()
474 regexp = sys.argv[index]
475 index += 1
Johnny Chen548aefd2010-10-11 22:25:46 +0000476 elif sys.argv[index].startswith('-r'):
477 # Increment by 1 to fetch the relocated directory argument.
478 index += 1
479 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
480 usage()
481 rdir = os.path.abspath(sys.argv[index])
482 if os.path.exists(rdir):
483 print "Relocated directory:", rdir, "must not exist!"
484 usage()
485 index += 1
Johnny Chen028d8eb2011-11-17 19:57:27 +0000486 elif sys.argv[index].startswith('-S'):
487 skip_build_and_cleanup = True
488 index += 1
Johnny Chen125fc2b2010-10-21 16:55:35 +0000489 elif sys.argv[index].startswith('-s'):
490 # Increment by 1 to fetch the session dir name.
491 index += 1
492 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
493 usage()
494 sdir_name = sys.argv[index]
495 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000496 elif sys.argv[index].startswith('-t'):
497 os.environ["LLDB_COMMAND_TRACE"] = "YES"
498 index += 1
499 elif sys.argv[index].startswith('-v'):
500 verbose = 2
501 index += 1
Johnny Chene47649c2010-10-07 02:04:14 +0000502 elif sys.argv[index].startswith('-w'):
503 os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] = 'YES'
504 index += 1
Johnny Chene00c9302011-10-10 22:03:44 +0000505 elif sys.argv[index].startswith('-x'):
506 # Increment by 1 to fetch the breakpoint specification of the benchmark executable.
507 index += 1
Johnny Chen8a1b1222011-10-20 22:16:24 +0000508 if index >= len(sys.argv):
Johnny Chene00c9302011-10-10 22:03:44 +0000509 usage()
510 bmBreakpointSpec = sys.argv[index]
511 index += 1
Johnny Chen5f2ed172011-10-20 18:43:28 +0000512 elif sys.argv[index].startswith('-y'):
513 # Increment by 1 to fetch the the benchmark iteration count.
514 index += 1
515 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
516 usage()
517 bmIterationCount = int(sys.argv[index])
518 index += 1
Johnny Chend2acdb32010-11-16 22:42:58 +0000519 elif sys.argv[index].startswith('-#'):
520 # Increment by 1 to fetch the repeat count argument.
521 index += 1
522 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
523 usage()
524 count = int(sys.argv[index])
525 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000526 else:
527 print "Unknown option: ", sys.argv[index]
528 usage()
Johnny Chenaf149a02010-09-16 17:11:30 +0000529
Jim Ingham4f347cb2011-04-13 21:11:41 +0000530 if do_help == True:
531 usage()
532
Johnny Chencc659ad2010-12-10 19:02:23 +0000533 # Do not specify both '-a' and '+a' at the same time.
534 if dont_do_python_api_test and just_do_python_api_test:
535 usage()
536
Johnny Chen08967192011-11-18 00:19:29 +0000537 # The simple progress bar is turned on only if verbose == 0 and LLDB_COMMAND_TRACE is not 'YES'
538 if ("LLDB_COMMAND_TRACE" not in os.environ or os.environ["LLDB_COMMAND_TRACE"]!="YES") and verbose==0:
539 progress_bar = True
540
Johnny Chenaf149a02010-09-16 17:11:30 +0000541 # Gather all the dirs passed on the command line.
542 if len(sys.argv) > index:
543 testdirs = map(os.path.abspath, sys.argv[index:])
544
Johnny Chen548aefd2010-10-11 22:25:46 +0000545 # If '-r dir' is specified, the tests should be run under the relocated
546 # directory. Let's copy the testdirs over.
547 if rdir:
548 from shutil import copytree, ignore_patterns
549
550 tmpdirs = []
551 for srcdir in testdirs:
552 dstdir = os.path.join(rdir, os.path.basename(srcdir))
553 # Don't copy the *.pyc and .svn stuffs.
554 copytree(srcdir, dstdir, ignore=ignore_patterns('*.pyc', '.svn'))
555 tmpdirs.append(dstdir)
556
557 # This will be our modified testdirs.
558 testdirs = tmpdirs
559
560 # With '-r dir' specified, there's no cleanup of intermediate test files.
561 os.environ["LLDB_DO_CLEANUP"] = 'NO'
562
563 # If testdirs is ['test'], the make directory has already been copied
564 # recursively and is contained within the rdir/test dir. For anything
565 # else, we would need to copy over the make directory and its contents,
566 # so that, os.listdir(rdir) looks like, for example:
567 #
568 # array_types conditional_break make
569 #
570 # where the make directory contains the Makefile.rules file.
571 if len(testdirs) != 1 or os.path.basename(testdirs[0]) != 'test':
572 # Don't copy the .svn stuffs.
573 copytree('make', os.path.join(rdir, 'make'),
574 ignore=ignore_patterns('.svn'))
575
576 #print "testdirs:", testdirs
577
Johnny Chenb40056b2010-09-21 00:09:27 +0000578 # Source the configFile if specified.
579 # The side effect, if any, will be felt from this point on. An example
580 # config file may be these simple two lines:
581 #
582 # sys.stderr = open("/tmp/lldbtest-stderr", "w")
583 # sys.stdout = open("/tmp/lldbtest-stdout", "w")
584 #
585 # which will reassign the two file objects to sys.stderr and sys.stdout,
586 # respectively.
587 #
588 # See also lldb-trunk/example/test/usage-config.
589 global config
590 if configFile:
591 # Pass config (a dictionary) as the locals namespace for side-effect.
592 execfile(configFile, globals(), config)
593 #print "config:", config
594 #print "sys.stderr:", sys.stderr
595 #print "sys.stdout:", sys.stdout
596
Johnny Chenaf149a02010-09-16 17:11:30 +0000597
Johnny Chen9707bb62010-06-25 21:14:08 +0000598def setupSysPath():
Johnny Chen8a3c0432011-03-11 20:13:06 +0000599 """
600 Add LLDB.framework/Resources/Python to the search paths for modules.
601 As a side effect, we also discover the 'lldb' executable and export it here.
602 """
Johnny Chen9707bb62010-06-25 21:14:08 +0000603
Johnny Chen548aefd2010-10-11 22:25:46 +0000604 global rdir
605 global testdirs
Johnny Chen50bc6382011-01-29 01:16:52 +0000606 global dumpSysPath
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000607 global noHeaders
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000608 global svn_info
Johnny Chen548aefd2010-10-11 22:25:46 +0000609
Johnny Chen9707bb62010-06-25 21:14:08 +0000610 # Get the directory containing the current script.
Johnny Chen4d162e52011-08-12 18:54:11 +0000611 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 +0000612 scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
613 else:
614 scriptPath = sys.path[0]
Johnny Chena1affab2010-07-03 03:41:59 +0000615 if not scriptPath.endswith('test'):
Johnny Chen9707bb62010-06-25 21:14:08 +0000616 print "This script expects to reside in lldb's test directory."
617 sys.exit(-1)
618
Johnny Chen548aefd2010-10-11 22:25:46 +0000619 if rdir:
620 # Set up the LLDB_TEST environment variable appropriately, so that the
621 # individual tests can be located relatively.
622 #
623 # See also lldbtest.TestBase.setUpClass(cls).
624 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
625 os.environ["LLDB_TEST"] = os.path.join(rdir, 'test')
626 else:
627 os.environ["LLDB_TEST"] = rdir
628 else:
629 os.environ["LLDB_TEST"] = scriptPath
Peter Collingbournef6c3de82011-06-20 19:06:45 +0000630
631 # Set up the LLDB_SRC environment variable, so that the tests can locate
632 # the LLDB source code.
633 os.environ["LLDB_SRC"] = os.path.join(sys.path[0], os.pardir)
634
Johnny Chen9de4ede2010-08-31 17:42:54 +0000635 pluginPath = os.path.join(scriptPath, 'plugins')
Johnny Chen8a3c0432011-03-11 20:13:06 +0000636 pexpectPath = os.path.join(scriptPath, 'pexpect-2.4')
Johnny Chen58f93922010-06-29 23:10:39 +0000637
Johnny Chen8a3c0432011-03-11 20:13:06 +0000638 # Append script dir, plugin dir, and pexpect dir to the sys.path.
Johnny Chenaf149a02010-09-16 17:11:30 +0000639 sys.path.append(scriptPath)
640 sys.path.append(pluginPath)
Johnny Chen8a3c0432011-03-11 20:13:06 +0000641 sys.path.append(pexpectPath)
Johnny Chenaf149a02010-09-16 17:11:30 +0000642
Johnny Chen26901c82011-03-11 19:47:23 +0000643 # This is our base name component.
Johnny Chena1affab2010-07-03 03:41:59 +0000644 base = os.path.abspath(os.path.join(scriptPath, os.pardir))
Johnny Chen6a564a42011-02-15 18:50:19 +0000645
Johnny Chen26901c82011-03-11 19:47:23 +0000646 # These are for xcode build directories.
Johnny Chen6a564a42011-02-15 18:50:19 +0000647 xcode3_build_dir = ['build']
648 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
649 dbg = ['Debug']
650 rel = ['Release']
651 bai = ['BuildAndIntegration']
652 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
Johnny Chen26901c82011-03-11 19:47:23 +0000653
654 # Some of the tests can invoke the 'lldb' command directly.
655 # We'll try to locate the appropriate executable right here.
656
Johnny Chen6033bed2011-08-26 00:00:01 +0000657 # First, you can define an environment variable LLDB_EXEC specifying the
658 # full pathname of the lldb executable.
659 if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
660 lldbExec = os.environ["LLDB_EXEC"]
661 else:
662 lldbExec = None
663
Johnny Chen26901c82011-03-11 19:47:23 +0000664 executable = ['lldb']
665 dbgExec = os.path.join(base, *(xcode3_build_dir + dbg + executable))
666 dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
667 relExec = os.path.join(base, *(xcode3_build_dir + rel + executable))
668 relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
669 baiExec = os.path.join(base, *(xcode3_build_dir + bai + executable))
670 baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
671
Johnny Chen6033bed2011-08-26 00:00:01 +0000672 # The 'lldb' executable built here in the source tree.
673 lldbHere = None
Johnny Chen26901c82011-03-11 19:47:23 +0000674 if is_exe(dbgExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000675 lldbHere = dbgExec
Johnny Chen26901c82011-03-11 19:47:23 +0000676 elif is_exe(dbgExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000677 lldbHere = dbgExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000678 elif is_exe(relExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000679 lldbHere = relExec
Johnny Chen26901c82011-03-11 19:47:23 +0000680 elif is_exe(relExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000681 lldbHere = relExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000682 elif is_exe(baiExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000683 lldbHere = baiExec
Johnny Chen26901c82011-03-11 19:47:23 +0000684 elif is_exe(baiExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000685 lldbHere = baiExec2
Daniel Dunbar2bd310c2011-10-31 23:27:06 +0000686 elif lldbExec:
687 lldbHere = lldbExec
Johnny Chen26901c82011-03-11 19:47:23 +0000688
Johnny Chen6033bed2011-08-26 00:00:01 +0000689 if lldbHere:
690 os.environ["LLDB_HERE"] = lldbHere
Johnny Chen0409d992011-10-25 20:08:03 +0000691 os.environ["LLDB_BUILD_DIR"] = os.path.split(lldbHere)[0]
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000692 if not noHeaders:
693 print "LLDB build dir:", os.environ["LLDB_BUILD_DIR"]
Johnny Chen91da0052011-10-28 17:56:02 +0000694 os.system('%s -v' % lldbHere)
Johnny Chen62d527e2011-08-04 18:17:16 +0000695
Johnny Chen6033bed2011-08-26 00:00:01 +0000696 # One last chance to locate the 'lldb' executable.
Johnny Chen26901c82011-03-11 19:47:23 +0000697 if not lldbExec:
Johnny Chen0409d992011-10-25 20:08:03 +0000698 lldbExec = which('lldb')
699 if lldbHere and not lldbExec:
Johnny Chen6033bed2011-08-26 00:00:01 +0000700 lldbExec = lldbHere
Johnny Chen0409d992011-10-25 20:08:03 +0000701
Johnny Chen26901c82011-03-11 19:47:23 +0000702
703 if not lldbExec:
704 print "The 'lldb' executable cannot be located. Some of the tests may not be run as a result."
705 else:
706 os.environ["LLDB_EXEC"] = lldbExec
Johnny Chen8904eb02011-10-28 00:59:00 +0000707 #print "The 'lldb' from PATH env variable", lldbExec
Johnny Chend7931462011-03-17 00:38:22 +0000708
Johnny Chenb264c9b2011-06-24 22:52:05 +0000709 if os.path.isdir(os.path.join(base, '.svn')):
710 pipe = subprocess.Popen(["svn", "info", base], stdout = subprocess.PIPE)
711 svn_info = pipe.stdout.read()
712 elif os.path.isdir(os.path.join(base, '.git')):
713 pipe = subprocess.Popen(["git", "svn", "info", base], stdout = subprocess.PIPE)
714 svn_info = pipe.stdout.read()
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000715 if not noHeaders:
716 print svn_info
Johnny Chen26901c82011-03-11 19:47:23 +0000717
718 global ignore
719
720 # The '-i' option is used to skip looking for lldb.py in the build tree.
721 if ignore:
722 return
723
Johnny Chen6a564a42011-02-15 18:50:19 +0000724 dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
725 dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
726 relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
727 relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
728 baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
729 baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
Johnny Chen9707bb62010-06-25 21:14:08 +0000730
731 lldbPath = None
732 if os.path.isfile(os.path.join(dbgPath, 'lldb.py')):
733 lldbPath = dbgPath
Greg Claytond9846b02011-02-14 21:17:06 +0000734 elif os.path.isfile(os.path.join(dbgPath2, 'lldb.py')):
735 lldbPath = dbgPath2
Johnny Chen9707bb62010-06-25 21:14:08 +0000736 elif os.path.isfile(os.path.join(relPath, 'lldb.py')):
737 lldbPath = relPath
Greg Claytond9846b02011-02-14 21:17:06 +0000738 elif os.path.isfile(os.path.join(relPath2, 'lldb.py')):
739 lldbPath = relPath2
Johnny Chenc202c462010-09-15 18:11:19 +0000740 elif os.path.isfile(os.path.join(baiPath, 'lldb.py')):
741 lldbPath = baiPath
Greg Claytond9846b02011-02-14 21:17:06 +0000742 elif os.path.isfile(os.path.join(baiPath2, 'lldb.py')):
743 lldbPath = baiPath2
Johnny Chen9707bb62010-06-25 21:14:08 +0000744
745 if not lldbPath:
Johnny Chenc202c462010-09-15 18:11:19 +0000746 print 'This script requires lldb.py to be in either ' + dbgPath + ',',
747 print relPath + ', or ' + baiPath
Johnny Chen9707bb62010-06-25 21:14:08 +0000748 sys.exit(-1)
749
Johnny Chenaf149a02010-09-16 17:11:30 +0000750 # This is to locate the lldb.py module. Insert it right after sys.path[0].
751 sys.path[1:1] = [lldbPath]
Johnny Chen50bc6382011-01-29 01:16:52 +0000752 if dumpSysPath:
753 print "sys.path:", sys.path
Johnny Chen9707bb62010-06-25 21:14:08 +0000754
Johnny Chen9707bb62010-06-25 21:14:08 +0000755
Johnny Chencd0279d2010-09-20 18:07:50 +0000756def doDelay(delta):
757 """Delaying startup for delta-seconds to facilitate debugger attachment."""
758 def alarm_handler(*args):
759 raise Exception("timeout")
760
761 signal.signal(signal.SIGALRM, alarm_handler)
762 signal.alarm(delta)
763 sys.stdout.write("pid=%d\n" % os.getpid())
764 sys.stdout.write("Enter RET to proceed (or timeout after %d seconds):" %
765 delta)
766 sys.stdout.flush()
767 try:
768 text = sys.stdin.readline()
769 except:
770 text = ""
771 signal.alarm(0)
772 sys.stdout.write("proceeding...\n")
773 pass
774
775
Johnny Chen9707bb62010-06-25 21:14:08 +0000776def visit(prefix, dir, names):
777 """Visitor function for os.path.walk(path, visit, arg)."""
778
779 global suite
Johnny Chen7c52ff12010-09-27 23:29:54 +0000780 global regexp
Johnny Chenc5fa0052011-07-29 22:54:56 +0000781 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000782 global fs4all
Johnny Chen9707bb62010-06-25 21:14:08 +0000783
784 for name in names:
785 if os.path.isdir(os.path.join(dir, name)):
786 continue
787
788 if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
Johnny Chen7c52ff12010-09-27 23:29:54 +0000789 # Try to match the regexp pattern, if specified.
790 if regexp:
791 import re
792 if re.search(regexp, name):
793 #print "Filename: '%s' matches pattern: '%s'" % (name, regexp)
794 pass
795 else:
796 #print "Filename: '%s' does not match pattern: '%s'" % (name, regexp)
797 continue
798
Johnny Chen953864a2010-10-12 21:35:54 +0000799 # We found a match for our test. Add it to the suite.
Johnny Chen79723352010-10-12 15:53:22 +0000800
801 # Update the sys.path first.
Johnny Chena85d7ee2010-06-26 00:19:32 +0000802 if not sys.path.count(dir):
Johnny Chen548aefd2010-10-11 22:25:46 +0000803 sys.path.insert(0, dir)
Johnny Chen9707bb62010-06-25 21:14:08 +0000804 base = os.path.splitext(name)[0]
Johnny Chenb62436b2010-10-06 20:40:56 +0000805
806 # Thoroughly check the filterspec against the base module and admit
807 # the (base, filterspec) combination only when it makes sense.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000808 filterspec = None
809 for filterspec in filters:
Johnny Chenb62436b2010-10-06 20:40:56 +0000810 # Optimistically set the flag to True.
811 filtered = True
812 module = __import__(base)
813 parts = filterspec.split('.')
814 obj = module
815 for part in parts:
816 try:
817 parent, obj = obj, getattr(obj, part)
818 except AttributeError:
819 # The filterspec has failed.
820 filtered = False
821 break
Johnny Chenc5fa0052011-07-29 22:54:56 +0000822
Johnny Chendb4be602011-08-12 23:55:07 +0000823 # If filtered, we have a good filterspec. Add it.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000824 if filtered:
Johnny Chendb4be602011-08-12 23:55:07 +0000825 #print "adding filter spec %s to module %s" % (filterspec, module)
826 suite.addTests(
827 unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
828 continue
Johnny Chenc5fa0052011-07-29 22:54:56 +0000829
830 # Forgo this module if the (base, filterspec) combo is invalid
831 # and no '-g' option is specified
832 if filters and fs4all and not filtered:
833 continue
Johnny Chenb62436b2010-10-06 20:40:56 +0000834
Johnny Chendb4be602011-08-12 23:55:07 +0000835 # Add either the filtered test case(s) (which is done before) or the entire test class.
836 if not filterspec or not filtered:
Johnny Chenb62436b2010-10-06 20:40:56 +0000837 # A simple case of just the module name. Also the failover case
838 # from the filterspec branch when the (base, filterspec) combo
839 # doesn't make sense.
840 suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
Johnny Chen9707bb62010-06-25 21:14:08 +0000841
842
Johnny Chencd0279d2010-09-20 18:07:50 +0000843def lldbLoggings():
844 """Check and do lldb loggings if necessary."""
845
846 # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
847 # defined. Use ${LLDB_LOG} to specify the log file.
848 ci = lldb.DBG.GetCommandInterpreter()
849 res = lldb.SBCommandReturnObject()
850 if ("LLDB_LOG" in os.environ):
851 if ("LLDB_LOG_OPTION" in os.environ):
852 lldb_log_option = os.environ["LLDB_LOG_OPTION"]
853 else:
Johnny Chen8fd886c2010-12-08 01:25:21 +0000854 lldb_log_option = "event process expr state api"
Johnny Chencd0279d2010-09-20 18:07:50 +0000855 ci.HandleCommand(
Greg Clayton940b1032011-02-23 00:35:02 +0000856 "log enable -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option,
Johnny Chencd0279d2010-09-20 18:07:50 +0000857 res)
858 if not res.Succeeded():
859 raise Exception('log enable failed (check LLDB_LOG env variable.')
860 # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
861 # Use ${GDB_REMOTE_LOG} to specify the log file.
862 if ("GDB_REMOTE_LOG" in os.environ):
863 if ("GDB_REMOTE_LOG_OPTION" in os.environ):
864 gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
865 else:
Johnny Chen7ab8c852010-12-02 18:35:13 +0000866 gdb_remote_log_option = "packets process"
Johnny Chencd0279d2010-09-20 18:07:50 +0000867 ci.HandleCommand(
Johnny Chenc935a892011-06-21 19:25:45 +0000868 "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
Johnny Chencd0279d2010-09-20 18:07:50 +0000869 + gdb_remote_log_option,
870 res)
871 if not res.Succeeded():
872 raise Exception('log enable failed (check GDB_REMOTE_LOG env variable.')
873
Johnny Chen067022b2011-01-19 19:31:46 +0000874def getMyCommandLine():
Johnny Chen067022b2011-01-19 19:31:46 +0000875 ps = subprocess.Popen(['ps', '-o', "command=CMD", str(os.getpid())], stdout=subprocess.PIPE).communicate()[0]
876 lines = ps.split('\n')
877 cmd_line = lines[1]
878 return cmd_line
Johnny Chencd0279d2010-09-20 18:07:50 +0000879
Johnny Chend96b5682010-11-05 17:30:53 +0000880# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +0000881# #
882# Execution of the test driver starts here #
883# #
Johnny Chend96b5682010-11-05 17:30:53 +0000884# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +0000885
Johnny Chen2891bb02011-09-16 01:04:26 +0000886def checkDsymForUUIDIsNotOn():
Johnny Chen6a4e0872011-09-16 17:50:44 +0000887 cmd = ["defaults", "read", "com.apple.DebugSymbols"]
888 pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
889 cmd_output = pipe.stdout.read()
Johnny Chen178c8d92011-09-16 18:03:19 +0000890 if cmd_output and "DBGFileMappedPaths = " in cmd_output:
Johnny Chen6a451482011-09-16 18:09:45 +0000891 print "%s =>" % ' '.join(cmd)
Johnny Chen6a4e0872011-09-16 17:50:44 +0000892 print cmd_output
Johnny Chen2891bb02011-09-16 01:04:26 +0000893 print "Disable automatic lookup and caching of dSYMs before running the test suite!"
894 print "Exiting..."
895 sys.exit(0)
896
897# On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
898# does not exist before proceeding to running the test suite.
899if sys.platform.startswith("darwin"):
900 checkDsymForUUIDIsNotOn()
901
Johnny Chen9707bb62010-06-25 21:14:08 +0000902#
Johnny Chenaf149a02010-09-16 17:11:30 +0000903# Start the actions by first parsing the options while setting up the test
904# directories, followed by setting up the search paths for lldb utilities;
905# then, we walk the directory trees and collect the tests into our test suite.
Johnny Chen9707bb62010-06-25 21:14:08 +0000906#
Johnny Chenaf149a02010-09-16 17:11:30 +0000907parseOptionsAndInitTestdirs()
Johnny Chen9707bb62010-06-25 21:14:08 +0000908setupSysPath()
Johnny Chen91960d32010-09-08 20:56:16 +0000909
910#
911# If '-d' is specified, do a delay of 10 seconds for the debugger to attach.
912#
913if delay:
Johnny Chencd0279d2010-09-20 18:07:50 +0000914 doDelay(10)
Johnny Chen91960d32010-09-08 20:56:16 +0000915
Johnny Chen49f2f7a2010-09-20 17:25:45 +0000916#
Johnny Chen41998192010-10-01 22:59:49 +0000917# If '-l' is specified, do not skip the long running tests.
Johnny Chen028d8eb2011-11-17 19:57:27 +0000918if not skip_long_running_test:
Johnny Chen41998192010-10-01 22:59:49 +0000919 os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
920
921#
Johnny Chen79723352010-10-12 15:53:22 +0000922# Walk through the testdirs while collecting tests.
Johnny Chen49f2f7a2010-09-20 17:25:45 +0000923#
Johnny Chen9707bb62010-06-25 21:14:08 +0000924for testdir in testdirs:
925 os.path.walk(testdir, visit, 'Test')
926
Johnny Chenb40056b2010-09-21 00:09:27 +0000927#
Johnny Chen9707bb62010-06-25 21:14:08 +0000928# Now that we have loaded all the test cases, run the whole test suite.
Johnny Chenb40056b2010-09-21 00:09:27 +0000929#
Johnny Chencd0279d2010-09-20 18:07:50 +0000930
Johnny Chen1bfbd412010-06-29 19:44:16 +0000931# For the time being, let's bracket the test runner within the
932# lldb.SBDebugger.Initialize()/Terminate() pair.
Johnny Chen01f2a6a2010-08-10 20:23:55 +0000933import lldb, atexit
Johnny Chen6b6f5ba2010-10-14 16:36:49 +0000934# Update: the act of importing lldb now executes lldb.SBDebugger.Initialize(),
935# there's no need to call it a second time.
936#lldb.SBDebugger.Initialize()
Johnny Chen01f2a6a2010-08-10 20:23:55 +0000937atexit.register(lambda: lldb.SBDebugger.Terminate())
Johnny Chen1bfbd412010-06-29 19:44:16 +0000938
Johnny Chen909e5a62010-07-01 22:52:57 +0000939# Create a singleton SBDebugger in the lldb namespace.
940lldb.DBG = lldb.SBDebugger.Create()
941
Johnny Chen4f93bf12010-12-10 00:51:23 +0000942# Put the blacklist in the lldb namespace, to be used by lldb.TestBase.
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000943lldb.blacklist = blacklist
944
Johnny Chene00c9302011-10-10 22:03:44 +0000945# Put dont/just_do_python_api_test in the lldb namespace.
Johnny Chen4f93bf12010-12-10 00:51:23 +0000946lldb.dont_do_python_api_test = dont_do_python_api_test
947lldb.just_do_python_api_test = just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000948lldb.just_do_benchmarks_test = just_do_benchmarks_test
Johnny Chen4f93bf12010-12-10 00:51:23 +0000949
Johnny Chen028d8eb2011-11-17 19:57:27 +0000950# Do we need to skip build and cleanup?
951lldb.skip_build_and_cleanup = skip_build_and_cleanup
952
Johnny Chen5f2ed172011-10-20 18:43:28 +0000953# Put bmExecutable, bmBreakpointSpec, and bmIterationCount into the lldb namespace, too.
Johnny Chene00c9302011-10-10 22:03:44 +0000954lldb.bmExecutable = bmExecutable
955lldb.bmBreakpointSpec = bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000956lldb.bmIterationCount = bmIterationCount
Johnny Chene00c9302011-10-10 22:03:44 +0000957
Johnny Chen38f823c2011-10-11 01:30:27 +0000958# And don't forget the runHooks!
959lldb.runHooks = runHooks
960
Johnny Chencd0279d2010-09-20 18:07:50 +0000961# Turn on lldb loggings if necessary.
962lldbLoggings()
Johnny Chen909e5a62010-07-01 22:52:57 +0000963
Johnny Chen7987ac92010-08-09 20:40:52 +0000964# Install the control-c handler.
965unittest2.signals.installHandler()
966
Johnny Chen125fc2b2010-10-21 16:55:35 +0000967# If sdir_name is not specified through the '-s sdir_name' option, get a
968# timestamp string and export it as LLDB_SESSION_DIR environment var. This will
969# be used when/if we want to dump the session info of individual test cases
970# later on.
Johnny Chence681462010-10-19 00:25:01 +0000971#
972# See also TestBase.dumpSessionInfo() in lldbtest.py.
Johnny Chen125fc2b2010-10-21 16:55:35 +0000973if not sdir_name:
974 import datetime
Johnny Chen41fae812010-10-29 22:26:38 +0000975 # The windows platforms don't like ':' in the pathname.
Johnny Chen76bd0102010-10-28 16:32:13 +0000976 timestamp = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
Johnny Chen125fc2b2010-10-21 16:55:35 +0000977 sdir_name = timestamp
Peter Collingbourne132476f2011-06-20 23:55:53 +0000978os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), sdir_name)
Johnny Chen067022b2011-01-19 19:31:46 +0000979
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000980if not noHeaders:
981 sys.stderr.write("\nSession logs for test failures/errors/unexpected successes"
982 " will go into directory '%s'\n" % sdir_name)
983 sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
Johnny Chence681462010-10-19 00:25:01 +0000984
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000985if not os.path.isdir(sdir_name):
986 os.mkdir(sdir_name)
987fname = os.path.join(sdir_name, "svn-info")
988with open(fname, "w") as f:
989 print >> f, svn_info
990 print >> f, "Command invoked: %s\n" % getMyCommandLine()
991
Johnny Chenb40056b2010-09-21 00:09:27 +0000992#
993# Invoke the default TextTestRunner to run the test suite, possibly iterating
994# over different configurations.
995#
996
Johnny Chenb40056b2010-09-21 00:09:27 +0000997iterArchs = False
Johnny Chenf032d902010-09-21 00:16:09 +0000998iterCompilers = False
Johnny Chenb40056b2010-09-21 00:09:27 +0000999
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001000if not archs and "archs" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001001 archs = config["archs"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001002
1003if isinstance(archs, list) and len(archs) >= 1:
1004 iterArchs = True
1005
1006if not compilers and "compilers" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001007 compilers = config["compilers"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001008
1009if isinstance(compilers, list) and len(compilers) >= 1:
1010 iterCompilers = True
Johnny Chenb40056b2010-09-21 00:09:27 +00001011
Johnny Chen953864a2010-10-12 21:35:54 +00001012# Make a shallow copy of sys.path, we need to manipulate the search paths later.
1013# This is only necessary if we are relocated and with different configurations.
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001014if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001015 old_sys_path = sys.path[:]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001016# If we iterate on archs or compilers, there is a chance we want to split stderr/stdout.
1017if iterArchs or iterCompilers:
Johnny Chen953864a2010-10-12 21:35:54 +00001018 old_stderr = sys.stderr
1019 old_stdout = sys.stdout
1020 new_stderr = None
1021 new_stdout = None
1022
Johnny Chend96b5682010-11-05 17:30:53 +00001023# Iterating over all possible architecture and compiler combinations.
Johnny Chenb40056b2010-09-21 00:09:27 +00001024for ia in range(len(archs) if iterArchs else 1):
1025 archConfig = ""
1026 if iterArchs:
Johnny Chen18a921f2010-09-30 17:11:58 +00001027 os.environ["ARCH"] = archs[ia]
Johnny Chenb40056b2010-09-21 00:09:27 +00001028 archConfig = "arch=%s" % archs[ia]
1029 for ic in range(len(compilers) if iterCompilers else 1):
1030 if iterCompilers:
Johnny Chen18a921f2010-09-30 17:11:58 +00001031 os.environ["CC"] = compilers[ic]
Johnny Chenb40056b2010-09-21 00:09:27 +00001032 configString = "%s compiler=%s" % (archConfig, compilers[ic])
1033 else:
1034 configString = archConfig
1035
Johnny Chenb40056b2010-09-21 00:09:27 +00001036 if iterArchs or iterCompilers:
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001037 # Translate ' ' to '-' for pathname component.
1038 from string import maketrans
1039 tbl = maketrans(' ', '-')
1040 configPostfix = configString.translate(tbl)
1041
1042 # Check whether we need to split stderr/stdout into configuration
1043 # specific files.
1044 if old_stderr.name != '<stderr>' and config.get('split_stderr'):
1045 if new_stderr:
1046 new_stderr.close()
1047 new_stderr = open("%s.%s" % (old_stderr.name, configPostfix), "w")
1048 sys.stderr = new_stderr
1049 if old_stdout.name != '<stdout>' and config.get('split_stdout'):
1050 if new_stdout:
1051 new_stdout.close()
1052 new_stdout = open("%s.%s" % (old_stdout.name, configPostfix), "w")
1053 sys.stdout = new_stdout
1054
Johnny Chen953864a2010-10-12 21:35:54 +00001055 # If we specified a relocated directory to run the test suite, do
1056 # the extra housekeeping to copy the testdirs to a configStringified
1057 # directory and to update sys.path before invoking the test runner.
1058 # The purpose is to separate the configuration-specific directories
1059 # from each other.
1060 if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001061 from shutil import copytree, ignore_patterns
1062
Johnny Chen953864a2010-10-12 21:35:54 +00001063 newrdir = "%s.%s" % (rdir, configPostfix)
1064
1065 # Copy the tree to a new directory with postfix name configPostfix.
1066 copytree(rdir, newrdir, ignore=ignore_patterns('*.pyc', '*.o', '*.d'))
1067
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001068 # Update the LLDB_TEST environment variable to reflect new top
Johnny Chen953864a2010-10-12 21:35:54 +00001069 # level test directory.
1070 #
1071 # See also lldbtest.TestBase.setUpClass(cls).
1072 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
1073 os.environ["LLDB_TEST"] = os.path.join(newrdir, 'test')
1074 else:
1075 os.environ["LLDB_TEST"] = newrdir
1076
1077 # And update the Python search paths for modules.
1078 sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
1079
1080 # Output the configuration.
Johnny Chenb40056b2010-09-21 00:09:27 +00001081 sys.stderr.write("\nConfiguration: " + configString + "\n")
Johnny Chen953864a2010-10-12 21:35:54 +00001082
1083 #print "sys.stderr name is", sys.stderr.name
1084 #print "sys.stdout name is", sys.stdout.name
1085
1086 # First, write out the number of collected test cases.
Johnny Chen08967192011-11-18 00:19:29 +00001087 sys.stderr.write(separator + "\n")
1088 sys.stderr.write("Collected %d test%s\n\n"
1089 % (suite.countTestCases(),
1090 suite.countTestCases() != 1 and "s" or ""))
Johnny Chen953864a2010-10-12 21:35:54 +00001091
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001092 class LLDBTestResult(unittest2.TextTestResult):
1093 """
Johnny Chen26be4532010-11-09 23:56:14 +00001094 Enforce a singleton pattern to allow introspection of test progress.
1095
1096 Overwrite addError(), addFailure(), and addExpectedFailure() methods
1097 to enable each test instance to track its failure/error status. It
1098 is used in the LLDB test framework to emit detailed trace messages
1099 to a log file for easier human inspection of test failres/errors.
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001100 """
1101 __singleton__ = None
Johnny Chen360dd372010-11-29 17:50:10 +00001102 __ignore_singleton__ = False
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001103
1104 def __init__(self, *args):
Johnny Chen360dd372010-11-29 17:50:10 +00001105 if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
Johnny Chend2acdb32010-11-16 22:42:58 +00001106 raise Exception("LLDBTestResult instantiated more than once")
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001107 super(LLDBTestResult, self).__init__(*args)
1108 LLDBTestResult.__singleton__ = self
1109 # Now put this singleton into the lldb module namespace.
1110 lldb.test_result = self
Johnny Chen810042e2011-01-05 20:24:11 +00001111 # Computes the format string for displaying the counter.
1112 global suite
1113 counterWidth = len(str(suite.countTestCases()))
1114 self.fmt = "%" + str(counterWidth) + "d: "
Johnny Chenc87fd492011-01-05 22:50:11 +00001115 self.indentation = ' ' * (counterWidth + 2)
Johnny Chen810042e2011-01-05 20:24:11 +00001116 # This counts from 1 .. suite.countTestCases().
1117 self.counter = 0
1118
Johnny Chenc87fd492011-01-05 22:50:11 +00001119 def getDescription(self, test):
1120 doc_first_line = test.shortDescription()
1121 if self.descriptions and doc_first_line:
1122 return '\n'.join((str(test), self.indentation + doc_first_line))
1123 else:
1124 return str(test)
1125
Johnny Chen810042e2011-01-05 20:24:11 +00001126 def startTest(self, test):
1127 self.counter += 1
1128 if self.showAll:
1129 self.stream.write(self.fmt % self.counter)
1130 super(LLDBTestResult, self).startTest(test)
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001131
Johnny Chen08967192011-11-18 00:19:29 +00001132 def stopTest(self, test):
1133 """Called when the given test has been run"""
1134 if progress_bar:
1135 sys.__stdout__.write('.')
1136 sys.__stdout__.flush()
1137 if self.counter == suite.countTestCases():
1138 sys.__stdout__.write('\n')
1139
1140 super(LLDBTestResult, self).stopTest(test)
1141
Johnny Chence681462010-10-19 00:25:01 +00001142 def addError(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001143 global sdir_has_content
1144 sdir_has_content = True
Johnny Chence681462010-10-19 00:25:01 +00001145 super(LLDBTestResult, self).addError(test, err)
1146 method = getattr(test, "markError", None)
1147 if method:
1148 method()
1149
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001150 def addFailure(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001151 global sdir_has_content
1152 sdir_has_content = True
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001153 super(LLDBTestResult, self).addFailure(test, err)
1154 method = getattr(test, "markFailure", None)
1155 if method:
1156 method()
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001157
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001158 def addExpectedFailure(self, test, err):
1159 global sdir_has_content
1160 sdir_has_content = True
1161 super(LLDBTestResult, self).addExpectedFailure(test, err)
1162 method = getattr(test, "markExpectedFailure", None)
1163 if method:
1164 method()
1165
Johnny Chenf5b89092011-08-15 23:09:08 +00001166 def addSkip(self, test, reason):
1167 global sdir_has_content
1168 sdir_has_content = True
1169 super(LLDBTestResult, self).addSkip(test, reason)
1170 method = getattr(test, "markSkippedTest", None)
1171 if method:
1172 method()
1173
Johnny Chenab2f0662011-05-06 20:30:22 +00001174 def addUnexpectedSuccess(self, test):
1175 global sdir_has_content
1176 sdir_has_content = True
1177 super(LLDBTestResult, self).addUnexpectedSuccess(test)
1178 method = getattr(test, "markUnexpectedSuccess", None)
1179 if method:
1180 method()
1181
Johnny Chen26be4532010-11-09 23:56:14 +00001182 # Invoke the test runner.
Johnny Chend2acdb32010-11-16 22:42:58 +00001183 if count == 1:
Johnny Chen7d6d8442010-12-03 19:59:35 +00001184 result = unittest2.TextTestRunner(stream=sys.stderr,
1185 verbosity=verbose,
1186 failfast=failfast,
Johnny Chend2acdb32010-11-16 22:42:58 +00001187 resultclass=LLDBTestResult).run(suite)
1188 else:
Johnny Chend6e7ca22010-11-29 17:52:43 +00001189 # We are invoking the same test suite more than once. In this case,
1190 # mark __ignore_singleton__ flag as True so the signleton pattern is
1191 # not enforced.
Johnny Chen360dd372010-11-29 17:50:10 +00001192 LLDBTestResult.__ignore_singleton__ = True
Johnny Chend2acdb32010-11-16 22:42:58 +00001193 for i in range(count):
Johnny Chen7d6d8442010-12-03 19:59:35 +00001194 result = unittest2.TextTestRunner(stream=sys.stderr,
1195 verbosity=verbose,
1196 failfast=failfast,
Johnny Chen360dd372010-11-29 17:50:10 +00001197 resultclass=LLDBTestResult).run(suite)
Johnny Chenb40056b2010-09-21 00:09:27 +00001198
Johnny Chen1bfbd412010-06-29 19:44:16 +00001199
Johnny Chen63c2cba2010-10-29 22:20:36 +00001200if sdir_has_content:
Johnny Chenab2f0662011-05-06 20:30:22 +00001201 sys.stderr.write("Session logs for test failures/errors/unexpected successes"
1202 " can be found in directory '%s'\n" % sdir_name)
Johnny Chen63c2cba2010-10-29 22:20:36 +00001203
Johnny Chencd0279d2010-09-20 18:07:50 +00001204# Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1205# This should not be necessary now.
Johnny Chen83f6e512010-08-13 22:58:44 +00001206if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
Johnny Chen83f6e512010-08-13 22:58:44 +00001207 print "Terminating Test suite..."
1208 subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1209
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001210# Exiting.
1211sys.exit(not result.wasSuccessful)