blob: f33aa6f00b93bd5b2e78156b9dd2fa5e4937e3b6 [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 Chen548aefd2010-10-11 22:25:46 +0000131# By default, we skip long running test case. Use '-l' option to override.
Johnny Chen41998192010-10-01 22:59:49 +0000132skipLongRunningTest = True
133
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000134# By default, we print the build dir, lldb version, and svn info. Use '-n' option to
135# turn it off.
136noHeaders = False
137
Johnny Chen7c52ff12010-09-27 23:29:54 +0000138# The regular expression pattern to match against eligible filenames as our test cases.
139regexp = None
140
Johnny Chen548aefd2010-10-11 22:25:46 +0000141# By default, tests are executed in place and cleanups are performed afterwards.
142# Use '-r dir' option to relocate the tests and their intermediate files to a
143# different directory and to forgo any cleanups. The directory specified must
144# not exist yet.
145rdir = None
146
Johnny Chen125fc2b2010-10-21 16:55:35 +0000147# By default, recorded session info for errored/failed test are dumped into its
148# own file under a session directory named after the timestamp of the test suite
149# run. Use '-s session-dir-name' to specify a specific dir name.
150sdir_name = None
151
Johnny Chen63c2cba2010-10-29 22:20:36 +0000152# Set this flag if there is any session info dumped during the test run.
153sdir_has_content = False
154
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000155# svn_info stores the output from 'svn info lldb.base.dir'.
156svn_info = ''
157
Johnny Chen9707bb62010-06-25 21:14:08 +0000158# Default verbosity is 0.
159verbose = 0
160
Peter Collingbourne61aca482011-06-20 19:06:29 +0000161# By default, search from the script directory.
162testdirs = [ sys.path[0] ]
Johnny Chen9707bb62010-06-25 21:14:08 +0000163
Johnny Chen877c7e42010-08-07 00:16:07 +0000164# Separator string.
165separator = '-' * 70
166
Johnny Chen9707bb62010-06-25 21:14:08 +0000167
168def usage():
169 print """
170Usage: dotest.py [option] [args]
171where options:
Jim Ingham4f347cb2011-04-13 21:11:41 +0000172-h : print this help message and exit. Add '-v' for more detailed help.
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000173-A : specify the architecture(s) to launch for the inferior process
174 -A i386 => launch inferior with i386 architecture
175 -A x86_64^i386 => launch inferior with x86_64 and i386 architectures
176-C : specify the compiler(s) used to build the inferior executable
177 -C clang => build debuggee using clang compiler
178 -C clang^gcc => build debuggee using clang and gcc compilers
Johnny Chen50bc6382011-01-29 01:16:52 +0000179-D : dump the Python sys.path variable
Johnny Chen4f93bf12010-12-10 00:51:23 +0000180-a : don't do lldb Python API tests
181 use @python_api_test to decorate a test case as lldb Python API test
Johnny Chen3ebdacc2010-12-10 18:52:10 +0000182+a : just do lldb Python API tests
Johnny Chencc659ad2010-12-10 19:02:23 +0000183 do not specify both '-a' and '+a' at the same time
Johnny Chen82ccf402011-07-30 01:39:58 +0000184+b : just do benchmark tests
185 use @benchmark_test to decorate a test case as such
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000186-b : read a blacklist file specified after this option
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000187-c : read a config file specified after this option
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000188 the architectures and compilers (note the plurals) specified via '-A' and '-C'
189 will override those specified via a config file
Johnny Chenb40056b2010-09-21 00:09:27 +0000190 (see also lldb-trunk/example/test/usage-config)
Johnny Chen91960d32010-09-08 20:56:16 +0000191-d : delay startup for 10 seconds (in order for the debugger to attach)
Johnny Chene00c9302011-10-10 22:03:44 +0000192-e : specify the full path of an executable used for benchmark purpose;
193 see also '-x', which provides the breakpoint sepcification
Johnny Chen7d6d8442010-12-03 19:59:35 +0000194-F : failfast, stop the test suite on the first error/failure
Johnny Chen46be75d2010-10-11 16:19:48 +0000195-f : specify a filter, which consists of the test class name, a dot, followed by
Johnny Chen1a6e92a2010-11-08 20:17:04 +0000196 the test method, to only admit such test into the test suite
Johnny Chenb62436b2010-10-06 20:40:56 +0000197 e.g., -f 'ClassTypesTestCase.test_with_dwarf_and_python_api'
Johnny Chena224cd12010-11-08 01:21:03 +0000198-g : if specified, the filterspec by -f is not exclusive, i.e., if a test module
199 does not match the filterspec (testclass.testmethod), the whole module is
200 still admitted to the test suite
Johnny Chenaf149a02010-09-16 17:11:30 +0000201-i : ignore (don't bailout) if 'lldb.py' module cannot be located in the build
202 tree relative to this script; use PYTHONPATH to locate the module
Johnny Chen38f823c2011-10-11 01:30:27 +0000203-k : specify a runhook, which is an lldb command to be executed by the debugger;
204 '-k' option can occur multiple times, the commands are executed one after the
205 other to bring the debugger to a desired state, so that, for example, further
206 benchmarking can be done
Johnny Chen41998192010-10-01 22:59:49 +0000207-l : don't skip long running test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000208-n : don't print the headers like build dir, lldb version, and svn info at all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000209-p : specify a regexp filename pattern for inclusion in the test suite
Johnny Chen548aefd2010-10-11 22:25:46 +0000210-r : specify a dir to relocate the tests and their intermediate files to;
211 the directory must not exist before running this test driver;
212 no cleanup of intermediate test files is performed in this case
Johnny Chen125fc2b2010-10-21 16:55:35 +0000213-s : specify the name of the dir created to store the session files of tests
214 with errored or failed status; if not specified, the test driver uses the
215 timestamp as the session dir name
Johnny Chena2486f22011-04-21 20:48:32 +0000216-t : turn on tracing of lldb command and other detailed test executions
217-v : do verbose mode of unittest framework (print out each test case invocation)
Johnny Chene00c9302011-10-10 22:03:44 +0000218-x : specify the breakpoint specification for the benchmark executable;
219 see also '-e', which provides the full path of the executable
Johnny Chen5f2ed172011-10-20 18:43:28 +0000220-y : specify the iteration count used to collect our benchmarks; an example is
221 the number of times to do 'thread step-over' to measure stepping speed
222 see also '-e' and '-x' options
Johnny Chene47649c2010-10-07 02:04:14 +0000223-w : insert some wait time (currently 0.5 sec) between consecutive test cases
Johnny Chend2acdb32010-11-16 22:42:58 +0000224-# : Repeat the test suite for a specified number of times
Johnny Chen9707bb62010-06-25 21:14:08 +0000225
226and:
Johnny Chen9656ab22010-10-22 19:00:18 +0000227args : specify a list of directory names to search for test modules named after
228 Test*.py (test discovery)
Peter Collingbourne5f2b5d62011-06-14 03:55:45 +0000229 if empty, search from the current working directory, instead
Jim Ingham4f347cb2011-04-13 21:11:41 +0000230"""
Johnny Chen58f93922010-06-29 23:10:39 +0000231
Jim Ingham4f347cb2011-04-13 21:11:41 +0000232 if verbose > 0:
233 print """
Johnny Chen9656ab22010-10-22 19:00:18 +0000234Examples:
235
Johnny Chena224cd12010-11-08 01:21:03 +0000236This is an example of using the -f option to pinpoint to a specfic test class
237and test method to be run:
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000238
Johnny Chena224cd12010-11-08 01:21:03 +0000239$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000240----------------------------------------------------------------------
241Collected 1 test
242
243test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
244Test 'frame variable this' when stopped on a class constructor. ... ok
245
246----------------------------------------------------------------------
247Ran 1 test in 1.396s
248
249OK
Johnny Chen9656ab22010-10-22 19:00:18 +0000250
251And this is an example of using the -p option to run a single file (the filename
252matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
253
254$ ./dotest.py -v -p ObjC
255----------------------------------------------------------------------
256Collected 4 tests
257
258test_break_with_dsym (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000259Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000260test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000261Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000262test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
263Lookup objective-c data types and evaluate expressions. ... ok
264test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
265Lookup objective-c data types and evaluate expressions. ... ok
266
267----------------------------------------------------------------------
268Ran 4 tests in 16.661s
269
270OK
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000271
Johnny Chen58f93922010-06-29 23:10:39 +0000272Running of this script also sets up the LLDB_TEST environment variable so that
Johnny Chenaf149a02010-09-16 17:11:30 +0000273individual test cases can locate their supporting files correctly. The script
274tries to set up Python's search paths for modules by looking at the build tree
Johnny Chena85859f2010-11-11 22:14:56 +0000275relative to this script. See also the '-i' option in the following example.
276
277Finally, this is an example of using the lldb.py module distributed/installed by
278Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
279option to add some delay between two tests. It uses ARCH=x86_64 to specify that
280as the architecture and CC=clang to specify the compiler used for the test run:
281
282$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
283
284Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
285----------------------------------------------------------------------
286Collected 2 tests
287
288test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
289Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
290test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
291Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
292
293----------------------------------------------------------------------
294Ran 2 tests in 5.659s
295
296OK
297
298The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
299notify the directory containing the session logs for test failures or errors.
300In case there is any test failure/error, a similar message is appended at the
301end of the stderr output for your convenience.
Johnny Chenfde69bc2010-09-14 22:01:40 +0000302
303Environment variables related to loggings:
304
305o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
306 with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
307
308o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
309 'process.gdb-remote' subsystem with a default option of 'packets' if
310 GDB_REMOTE_LOG_OPTION is not defined.
Johnny Chen9707bb62010-06-25 21:14:08 +0000311"""
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000312 sys.exit(0)
Johnny Chen9707bb62010-06-25 21:14:08 +0000313
314
Johnny Chenaf149a02010-09-16 17:11:30 +0000315def parseOptionsAndInitTestdirs():
316 """Initialize the list of directories containing our unittest scripts.
317
318 '-h/--help as the first option prints out usage info and exit the program.
319 """
320
Johnny Chen4f93bf12010-12-10 00:51:23 +0000321 global dont_do_python_api_test
322 global just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000323 global just_do_benchmarks_test
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000324 global blacklist
325 global blacklistConfig
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000326 global configFile
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000327 global archs
328 global compilers
Johnny Chend2acdb32010-11-16 22:42:58 +0000329 global count
Johnny Chenaf149a02010-09-16 17:11:30 +0000330 global delay
Johnny Chen50bc6382011-01-29 01:16:52 +0000331 global dumpSysPath
Johnny Chene00c9302011-10-10 22:03:44 +0000332 global bmExecutable
333 global bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000334 global bmIterationCount
Johnny Chen7d6d8442010-12-03 19:59:35 +0000335 global failfast
Johnny Chenc5fa0052011-07-29 22:54:56 +0000336 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000337 global fs4all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000338 global ignore
Johnny Chen38f823c2011-10-11 01:30:27 +0000339 global runHooks
Johnny Chen41998192010-10-01 22:59:49 +0000340 global skipLongRunningTest
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000341 global noHeaders
Johnny Chen7c52ff12010-09-27 23:29:54 +0000342 global regexp
Johnny Chen548aefd2010-10-11 22:25:46 +0000343 global rdir
Johnny Chen125fc2b2010-10-21 16:55:35 +0000344 global sdir_name
Johnny Chenaf149a02010-09-16 17:11:30 +0000345 global verbose
346 global testdirs
347
Jim Ingham4f347cb2011-04-13 21:11:41 +0000348 do_help = False
349
Johnny Chenaf149a02010-09-16 17:11:30 +0000350 if len(sys.argv) == 1:
351 return
352
353 # Process possible trace and/or verbose flag, among other things.
354 index = 1
Johnny Chence2212c2010-10-07 15:41:55 +0000355 while index < len(sys.argv):
Johnny Chen4f93bf12010-12-10 00:51:23 +0000356 if sys.argv[index].startswith('-') or sys.argv[index].startswith('+'):
357 # We should continue processing...
358 pass
359 else:
Johnny Chenaf149a02010-09-16 17:11:30 +0000360 # End of option processing.
361 break
362
363 if sys.argv[index].find('-h') != -1:
Jim Ingham4f347cb2011-04-13 21:11:41 +0000364 index += 1
365 do_help = True
Johnny Chen012cba12011-01-26 19:07:42 +0000366 elif sys.argv[index].startswith('-A'):
367 # Increment by 1 to fetch the ARCH spec.
368 index += 1
369 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
370 usage()
Johnny Cheneee9b862011-04-26 20:45:00 +0000371 archs = sys.argv[index].split('^')
Johnny Chen012cba12011-01-26 19:07:42 +0000372 index += 1
373 elif sys.argv[index].startswith('-C'):
374 # Increment by 1 to fetch the CC spec.
375 index += 1
376 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
377 usage()
Johnny Cheneee9b862011-04-26 20:45:00 +0000378 compilers = sys.argv[index].split('^')
Johnny Chen012cba12011-01-26 19:07:42 +0000379 index += 1
Johnny Chen50bc6382011-01-29 01:16:52 +0000380 elif sys.argv[index].startswith('-D'):
381 dumpSysPath = True
382 index += 1
Johnny Chen4f93bf12010-12-10 00:51:23 +0000383 elif sys.argv[index].startswith('-a'):
384 dont_do_python_api_test = True
385 index += 1
386 elif sys.argv[index].startswith('+a'):
387 just_do_python_api_test = True
388 index += 1
Johnny Chen82ccf402011-07-30 01:39:58 +0000389 elif sys.argv[index].startswith('+b'):
390 just_do_benchmarks_test = True
391 index += 1
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000392 elif sys.argv[index].startswith('-b'):
393 # Increment by 1 to fetch the blacklist file name option argument.
394 index += 1
395 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
396 usage()
397 blacklistFile = sys.argv[index]
398 if not os.path.isfile(blacklistFile):
399 print "Blacklist file:", blacklistFile, "does not exist!"
400 usage()
401 index += 1
402 # Now read the blacklist contents and assign it to blacklist.
403 execfile(blacklistFile, globals(), blacklistConfig)
404 blacklist = blacklistConfig.get('blacklist')
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000405 elif sys.argv[index].startswith('-c'):
406 # Increment by 1 to fetch the config file name option argument.
407 index += 1
408 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
409 usage()
410 configFile = sys.argv[index]
411 if not os.path.isfile(configFile):
412 print "Config file:", configFile, "does not exist!"
413 usage()
414 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000415 elif sys.argv[index].startswith('-d'):
416 delay = True
417 index += 1
Johnny Chene00c9302011-10-10 22:03:44 +0000418 elif sys.argv[index].startswith('-e'):
419 # Increment by 1 to fetch the full path of the benchmark executable.
420 index += 1
421 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
422 usage()
423 bmExecutable = sys.argv[index]
424 if not is_exe(bmExecutable):
425 usage()
426 index += 1
Johnny Chen7d6d8442010-12-03 19:59:35 +0000427 elif sys.argv[index].startswith('-F'):
428 failfast = True
429 index += 1
Johnny Chenb62436b2010-10-06 20:40:56 +0000430 elif sys.argv[index].startswith('-f'):
431 # Increment by 1 to fetch the filter spec.
432 index += 1
433 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
434 usage()
Johnny Chenc5fa0052011-07-29 22:54:56 +0000435 filters.append(sys.argv[index])
Johnny Chenb62436b2010-10-06 20:40:56 +0000436 index += 1
437 elif sys.argv[index].startswith('-g'):
Johnny Chena224cd12010-11-08 01:21:03 +0000438 fs4all = False
Johnny Chenb62436b2010-10-06 20:40:56 +0000439 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000440 elif sys.argv[index].startswith('-i'):
441 ignore = True
442 index += 1
Johnny Chen38f823c2011-10-11 01:30:27 +0000443 elif sys.argv[index].startswith('-k'):
444 # Increment by 1 to fetch the runhook lldb command.
445 index += 1
446 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
447 usage()
448 runHooks.append(sys.argv[index])
449 index += 1
Johnny Chen41998192010-10-01 22:59:49 +0000450 elif sys.argv[index].startswith('-l'):
451 skipLongRunningTest = False
452 index += 1
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000453 elif sys.argv[index].startswith('-n'):
454 noHeaders = True
455 index += 1
Johnny Chen7c52ff12010-09-27 23:29:54 +0000456 elif sys.argv[index].startswith('-p'):
457 # Increment by 1 to fetch the reg exp pattern argument.
458 index += 1
459 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
460 usage()
461 regexp = sys.argv[index]
462 index += 1
Johnny Chen548aefd2010-10-11 22:25:46 +0000463 elif sys.argv[index].startswith('-r'):
464 # Increment by 1 to fetch the relocated directory argument.
465 index += 1
466 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
467 usage()
468 rdir = os.path.abspath(sys.argv[index])
469 if os.path.exists(rdir):
470 print "Relocated directory:", rdir, "must not exist!"
471 usage()
472 index += 1
Johnny Chen125fc2b2010-10-21 16:55:35 +0000473 elif sys.argv[index].startswith('-s'):
474 # Increment by 1 to fetch the session dir name.
475 index += 1
476 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
477 usage()
478 sdir_name = sys.argv[index]
479 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000480 elif sys.argv[index].startswith('-t'):
481 os.environ["LLDB_COMMAND_TRACE"] = "YES"
482 index += 1
483 elif sys.argv[index].startswith('-v'):
484 verbose = 2
485 index += 1
Johnny Chene47649c2010-10-07 02:04:14 +0000486 elif sys.argv[index].startswith('-w'):
487 os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] = 'YES'
488 index += 1
Johnny Chene00c9302011-10-10 22:03:44 +0000489 elif sys.argv[index].startswith('-x'):
490 # Increment by 1 to fetch the breakpoint specification of the benchmark executable.
491 index += 1
Johnny Chen8a1b1222011-10-20 22:16:24 +0000492 if index >= len(sys.argv):
Johnny Chene00c9302011-10-10 22:03:44 +0000493 usage()
494 bmBreakpointSpec = sys.argv[index]
495 index += 1
Johnny Chen5f2ed172011-10-20 18:43:28 +0000496 elif sys.argv[index].startswith('-y'):
497 # Increment by 1 to fetch the the benchmark iteration count.
498 index += 1
499 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
500 usage()
501 bmIterationCount = int(sys.argv[index])
502 index += 1
Johnny Chend2acdb32010-11-16 22:42:58 +0000503 elif sys.argv[index].startswith('-#'):
504 # Increment by 1 to fetch the repeat count argument.
505 index += 1
506 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
507 usage()
508 count = int(sys.argv[index])
509 index += 1
Johnny Chenaf149a02010-09-16 17:11:30 +0000510 else:
511 print "Unknown option: ", sys.argv[index]
512 usage()
Johnny Chenaf149a02010-09-16 17:11:30 +0000513
Jim Ingham4f347cb2011-04-13 21:11:41 +0000514 if do_help == True:
515 usage()
516
Johnny Chencc659ad2010-12-10 19:02:23 +0000517 # Do not specify both '-a' and '+a' at the same time.
518 if dont_do_python_api_test and just_do_python_api_test:
519 usage()
520
Johnny Chenaf149a02010-09-16 17:11:30 +0000521 # Gather all the dirs passed on the command line.
522 if len(sys.argv) > index:
523 testdirs = map(os.path.abspath, sys.argv[index:])
524
Johnny Chen548aefd2010-10-11 22:25:46 +0000525 # If '-r dir' is specified, the tests should be run under the relocated
526 # directory. Let's copy the testdirs over.
527 if rdir:
528 from shutil import copytree, ignore_patterns
529
530 tmpdirs = []
531 for srcdir in testdirs:
532 dstdir = os.path.join(rdir, os.path.basename(srcdir))
533 # Don't copy the *.pyc and .svn stuffs.
534 copytree(srcdir, dstdir, ignore=ignore_patterns('*.pyc', '.svn'))
535 tmpdirs.append(dstdir)
536
537 # This will be our modified testdirs.
538 testdirs = tmpdirs
539
540 # With '-r dir' specified, there's no cleanup of intermediate test files.
541 os.environ["LLDB_DO_CLEANUP"] = 'NO'
542
543 # If testdirs is ['test'], the make directory has already been copied
544 # recursively and is contained within the rdir/test dir. For anything
545 # else, we would need to copy over the make directory and its contents,
546 # so that, os.listdir(rdir) looks like, for example:
547 #
548 # array_types conditional_break make
549 #
550 # where the make directory contains the Makefile.rules file.
551 if len(testdirs) != 1 or os.path.basename(testdirs[0]) != 'test':
552 # Don't copy the .svn stuffs.
553 copytree('make', os.path.join(rdir, 'make'),
554 ignore=ignore_patterns('.svn'))
555
556 #print "testdirs:", testdirs
557
Johnny Chenb40056b2010-09-21 00:09:27 +0000558 # Source the configFile if specified.
559 # The side effect, if any, will be felt from this point on. An example
560 # config file may be these simple two lines:
561 #
562 # sys.stderr = open("/tmp/lldbtest-stderr", "w")
563 # sys.stdout = open("/tmp/lldbtest-stdout", "w")
564 #
565 # which will reassign the two file objects to sys.stderr and sys.stdout,
566 # respectively.
567 #
568 # See also lldb-trunk/example/test/usage-config.
569 global config
570 if configFile:
571 # Pass config (a dictionary) as the locals namespace for side-effect.
572 execfile(configFile, globals(), config)
573 #print "config:", config
574 #print "sys.stderr:", sys.stderr
575 #print "sys.stdout:", sys.stdout
576
Johnny Chenaf149a02010-09-16 17:11:30 +0000577
Johnny Chen9707bb62010-06-25 21:14:08 +0000578def setupSysPath():
Johnny Chen8a3c0432011-03-11 20:13:06 +0000579 """
580 Add LLDB.framework/Resources/Python to the search paths for modules.
581 As a side effect, we also discover the 'lldb' executable and export it here.
582 """
Johnny Chen9707bb62010-06-25 21:14:08 +0000583
Johnny Chen548aefd2010-10-11 22:25:46 +0000584 global rdir
585 global testdirs
Johnny Chen50bc6382011-01-29 01:16:52 +0000586 global dumpSysPath
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000587 global noHeaders
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000588 global svn_info
Johnny Chen548aefd2010-10-11 22:25:46 +0000589
Johnny Chen9707bb62010-06-25 21:14:08 +0000590 # Get the directory containing the current script.
Johnny Chen4d162e52011-08-12 18:54:11 +0000591 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 +0000592 scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
593 else:
594 scriptPath = sys.path[0]
Johnny Chena1affab2010-07-03 03:41:59 +0000595 if not scriptPath.endswith('test'):
Johnny Chen9707bb62010-06-25 21:14:08 +0000596 print "This script expects to reside in lldb's test directory."
597 sys.exit(-1)
598
Johnny Chen548aefd2010-10-11 22:25:46 +0000599 if rdir:
600 # Set up the LLDB_TEST environment variable appropriately, so that the
601 # individual tests can be located relatively.
602 #
603 # See also lldbtest.TestBase.setUpClass(cls).
604 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
605 os.environ["LLDB_TEST"] = os.path.join(rdir, 'test')
606 else:
607 os.environ["LLDB_TEST"] = rdir
608 else:
609 os.environ["LLDB_TEST"] = scriptPath
Peter Collingbournef6c3de82011-06-20 19:06:45 +0000610
611 # Set up the LLDB_SRC environment variable, so that the tests can locate
612 # the LLDB source code.
613 os.environ["LLDB_SRC"] = os.path.join(sys.path[0], os.pardir)
614
Johnny Chen9de4ede2010-08-31 17:42:54 +0000615 pluginPath = os.path.join(scriptPath, 'plugins')
Johnny Chen8a3c0432011-03-11 20:13:06 +0000616 pexpectPath = os.path.join(scriptPath, 'pexpect-2.4')
Johnny Chen58f93922010-06-29 23:10:39 +0000617
Johnny Chen8a3c0432011-03-11 20:13:06 +0000618 # Append script dir, plugin dir, and pexpect dir to the sys.path.
Johnny Chenaf149a02010-09-16 17:11:30 +0000619 sys.path.append(scriptPath)
620 sys.path.append(pluginPath)
Johnny Chen8a3c0432011-03-11 20:13:06 +0000621 sys.path.append(pexpectPath)
Johnny Chenaf149a02010-09-16 17:11:30 +0000622
Johnny Chen26901c82011-03-11 19:47:23 +0000623 # This is our base name component.
Johnny Chena1affab2010-07-03 03:41:59 +0000624 base = os.path.abspath(os.path.join(scriptPath, os.pardir))
Johnny Chen6a564a42011-02-15 18:50:19 +0000625
Johnny Chen26901c82011-03-11 19:47:23 +0000626 # These are for xcode build directories.
Johnny Chen6a564a42011-02-15 18:50:19 +0000627 xcode3_build_dir = ['build']
628 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
629 dbg = ['Debug']
630 rel = ['Release']
631 bai = ['BuildAndIntegration']
632 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
Johnny Chen26901c82011-03-11 19:47:23 +0000633
634 # Some of the tests can invoke the 'lldb' command directly.
635 # We'll try to locate the appropriate executable right here.
636
Johnny Chen6033bed2011-08-26 00:00:01 +0000637 # First, you can define an environment variable LLDB_EXEC specifying the
638 # full pathname of the lldb executable.
639 if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
640 lldbExec = os.environ["LLDB_EXEC"]
641 else:
642 lldbExec = None
643
Johnny Chen26901c82011-03-11 19:47:23 +0000644 executable = ['lldb']
645 dbgExec = os.path.join(base, *(xcode3_build_dir + dbg + executable))
646 dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
647 relExec = os.path.join(base, *(xcode3_build_dir + rel + executable))
648 relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
649 baiExec = os.path.join(base, *(xcode3_build_dir + bai + executable))
650 baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
651
Johnny Chen6033bed2011-08-26 00:00:01 +0000652 # The 'lldb' executable built here in the source tree.
653 lldbHere = None
Johnny Chen26901c82011-03-11 19:47:23 +0000654 if is_exe(dbgExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000655 lldbHere = dbgExec
Johnny Chen26901c82011-03-11 19:47:23 +0000656 elif is_exe(dbgExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000657 lldbHere = dbgExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000658 elif is_exe(relExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000659 lldbHere = relExec
Johnny Chen26901c82011-03-11 19:47:23 +0000660 elif is_exe(relExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000661 lldbHere = relExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000662 elif is_exe(baiExec):
Johnny Chen6033bed2011-08-26 00:00:01 +0000663 lldbHere = baiExec
Johnny Chen26901c82011-03-11 19:47:23 +0000664 elif is_exe(baiExec2):
Johnny Chen6033bed2011-08-26 00:00:01 +0000665 lldbHere = baiExec2
Johnny Chen26901c82011-03-11 19:47:23 +0000666
Johnny Chen6033bed2011-08-26 00:00:01 +0000667 if lldbHere:
668 os.environ["LLDB_HERE"] = lldbHere
669 if not lldbExec:
670 lldbExec = lldbHere
Johnny Chen62d527e2011-08-04 18:17:16 +0000671 os.environ["LLDB_BUILD_DIR"] = os.path.split(lldbExec)[0]
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000672 if not noHeaders:
673 print "LLDB build dir:", os.environ["LLDB_BUILD_DIR"]
Johnny Chen62d527e2011-08-04 18:17:16 +0000674
Johnny Chen6033bed2011-08-26 00:00:01 +0000675 # One last chance to locate the 'lldb' executable.
Johnny Chen26901c82011-03-11 19:47:23 +0000676 if not lldbExec:
Johnny Chen6033bed2011-08-26 00:00:01 +0000677 if lldbHere:
678 lldbExec = lldbHere
679 else:
680 lldbExec = which('lldb')
Johnny Chen26901c82011-03-11 19:47:23 +0000681
682 if not lldbExec:
683 print "The 'lldb' executable cannot be located. Some of the tests may not be run as a result."
684 else:
685 os.environ["LLDB_EXEC"] = lldbExec
Johnny Chend7931462011-03-17 00:38:22 +0000686 #print "The 'lldb' executable path is", lldbExec
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000687 if not noHeaders:
688 os.system('%s -v' % lldbExec)
Johnny Chend7931462011-03-17 00:38:22 +0000689
Johnny Chenb264c9b2011-06-24 22:52:05 +0000690 if os.path.isdir(os.path.join(base, '.svn')):
691 pipe = subprocess.Popen(["svn", "info", base], stdout = subprocess.PIPE)
692 svn_info = pipe.stdout.read()
693 elif os.path.isdir(os.path.join(base, '.git')):
694 pipe = subprocess.Popen(["git", "svn", "info", base], stdout = subprocess.PIPE)
695 svn_info = pipe.stdout.read()
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000696 if not noHeaders:
697 print svn_info
Johnny Chen26901c82011-03-11 19:47:23 +0000698
699 global ignore
700
701 # The '-i' option is used to skip looking for lldb.py in the build tree.
702 if ignore:
703 return
704
Johnny Chen6a564a42011-02-15 18:50:19 +0000705 dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
706 dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
707 relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
708 relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
709 baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
710 baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
Johnny Chen9707bb62010-06-25 21:14:08 +0000711
712 lldbPath = None
713 if os.path.isfile(os.path.join(dbgPath, 'lldb.py')):
714 lldbPath = dbgPath
Greg Claytond9846b02011-02-14 21:17:06 +0000715 elif os.path.isfile(os.path.join(dbgPath2, 'lldb.py')):
716 lldbPath = dbgPath2
Johnny Chen9707bb62010-06-25 21:14:08 +0000717 elif os.path.isfile(os.path.join(relPath, 'lldb.py')):
718 lldbPath = relPath
Greg Claytond9846b02011-02-14 21:17:06 +0000719 elif os.path.isfile(os.path.join(relPath2, 'lldb.py')):
720 lldbPath = relPath2
Johnny Chenc202c462010-09-15 18:11:19 +0000721 elif os.path.isfile(os.path.join(baiPath, 'lldb.py')):
722 lldbPath = baiPath
Greg Claytond9846b02011-02-14 21:17:06 +0000723 elif os.path.isfile(os.path.join(baiPath2, 'lldb.py')):
724 lldbPath = baiPath2
Johnny Chen9707bb62010-06-25 21:14:08 +0000725
726 if not lldbPath:
Johnny Chenc202c462010-09-15 18:11:19 +0000727 print 'This script requires lldb.py to be in either ' + dbgPath + ',',
728 print relPath + ', or ' + baiPath
Johnny Chen9707bb62010-06-25 21:14:08 +0000729 sys.exit(-1)
730
Johnny Chenaf149a02010-09-16 17:11:30 +0000731 # This is to locate the lldb.py module. Insert it right after sys.path[0].
732 sys.path[1:1] = [lldbPath]
Johnny Chen50bc6382011-01-29 01:16:52 +0000733 if dumpSysPath:
734 print "sys.path:", sys.path
Johnny Chen9707bb62010-06-25 21:14:08 +0000735
Johnny Chen9707bb62010-06-25 21:14:08 +0000736
Johnny Chencd0279d2010-09-20 18:07:50 +0000737def doDelay(delta):
738 """Delaying startup for delta-seconds to facilitate debugger attachment."""
739 def alarm_handler(*args):
740 raise Exception("timeout")
741
742 signal.signal(signal.SIGALRM, alarm_handler)
743 signal.alarm(delta)
744 sys.stdout.write("pid=%d\n" % os.getpid())
745 sys.stdout.write("Enter RET to proceed (or timeout after %d seconds):" %
746 delta)
747 sys.stdout.flush()
748 try:
749 text = sys.stdin.readline()
750 except:
751 text = ""
752 signal.alarm(0)
753 sys.stdout.write("proceeding...\n")
754 pass
755
756
Johnny Chen9707bb62010-06-25 21:14:08 +0000757def visit(prefix, dir, names):
758 """Visitor function for os.path.walk(path, visit, arg)."""
759
760 global suite
Johnny Chen7c52ff12010-09-27 23:29:54 +0000761 global regexp
Johnny Chenc5fa0052011-07-29 22:54:56 +0000762 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000763 global fs4all
Johnny Chen9707bb62010-06-25 21:14:08 +0000764
765 for name in names:
766 if os.path.isdir(os.path.join(dir, name)):
767 continue
768
769 if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
Johnny Chen7c52ff12010-09-27 23:29:54 +0000770 # Try to match the regexp pattern, if specified.
771 if regexp:
772 import re
773 if re.search(regexp, name):
774 #print "Filename: '%s' matches pattern: '%s'" % (name, regexp)
775 pass
776 else:
777 #print "Filename: '%s' does not match pattern: '%s'" % (name, regexp)
778 continue
779
Johnny Chen953864a2010-10-12 21:35:54 +0000780 # We found a match for our test. Add it to the suite.
Johnny Chen79723352010-10-12 15:53:22 +0000781
782 # Update the sys.path first.
Johnny Chena85d7ee2010-06-26 00:19:32 +0000783 if not sys.path.count(dir):
Johnny Chen548aefd2010-10-11 22:25:46 +0000784 sys.path.insert(0, dir)
Johnny Chen9707bb62010-06-25 21:14:08 +0000785 base = os.path.splitext(name)[0]
Johnny Chenb62436b2010-10-06 20:40:56 +0000786
787 # Thoroughly check the filterspec against the base module and admit
788 # the (base, filterspec) combination only when it makes sense.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000789 filterspec = None
790 for filterspec in filters:
Johnny Chenb62436b2010-10-06 20:40:56 +0000791 # Optimistically set the flag to True.
792 filtered = True
793 module = __import__(base)
794 parts = filterspec.split('.')
795 obj = module
796 for part in parts:
797 try:
798 parent, obj = obj, getattr(obj, part)
799 except AttributeError:
800 # The filterspec has failed.
801 filtered = False
802 break
Johnny Chenc5fa0052011-07-29 22:54:56 +0000803
Johnny Chendb4be602011-08-12 23:55:07 +0000804 # If filtered, we have a good filterspec. Add it.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000805 if filtered:
Johnny Chendb4be602011-08-12 23:55:07 +0000806 #print "adding filter spec %s to module %s" % (filterspec, module)
807 suite.addTests(
808 unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
809 continue
Johnny Chenc5fa0052011-07-29 22:54:56 +0000810
811 # Forgo this module if the (base, filterspec) combo is invalid
812 # and no '-g' option is specified
813 if filters and fs4all and not filtered:
814 continue
Johnny Chenb62436b2010-10-06 20:40:56 +0000815
Johnny Chendb4be602011-08-12 23:55:07 +0000816 # Add either the filtered test case(s) (which is done before) or the entire test class.
817 if not filterspec or not filtered:
Johnny Chenb62436b2010-10-06 20:40:56 +0000818 # A simple case of just the module name. Also the failover case
819 # from the filterspec branch when the (base, filterspec) combo
820 # doesn't make sense.
821 suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
Johnny Chen9707bb62010-06-25 21:14:08 +0000822
823
Johnny Chencd0279d2010-09-20 18:07:50 +0000824def lldbLoggings():
825 """Check and do lldb loggings if necessary."""
826
827 # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
828 # defined. Use ${LLDB_LOG} to specify the log file.
829 ci = lldb.DBG.GetCommandInterpreter()
830 res = lldb.SBCommandReturnObject()
831 if ("LLDB_LOG" in os.environ):
832 if ("LLDB_LOG_OPTION" in os.environ):
833 lldb_log_option = os.environ["LLDB_LOG_OPTION"]
834 else:
Johnny Chen8fd886c2010-12-08 01:25:21 +0000835 lldb_log_option = "event process expr state api"
Johnny Chencd0279d2010-09-20 18:07:50 +0000836 ci.HandleCommand(
Greg Clayton940b1032011-02-23 00:35:02 +0000837 "log enable -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option,
Johnny Chencd0279d2010-09-20 18:07:50 +0000838 res)
839 if not res.Succeeded():
840 raise Exception('log enable failed (check LLDB_LOG env variable.')
841 # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
842 # Use ${GDB_REMOTE_LOG} to specify the log file.
843 if ("GDB_REMOTE_LOG" in os.environ):
844 if ("GDB_REMOTE_LOG_OPTION" in os.environ):
845 gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
846 else:
Johnny Chen7ab8c852010-12-02 18:35:13 +0000847 gdb_remote_log_option = "packets process"
Johnny Chencd0279d2010-09-20 18:07:50 +0000848 ci.HandleCommand(
Johnny Chenc935a892011-06-21 19:25:45 +0000849 "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
Johnny Chencd0279d2010-09-20 18:07:50 +0000850 + gdb_remote_log_option,
851 res)
852 if not res.Succeeded():
853 raise Exception('log enable failed (check GDB_REMOTE_LOG env variable.')
854
Johnny Chen067022b2011-01-19 19:31:46 +0000855def getMyCommandLine():
Johnny Chen067022b2011-01-19 19:31:46 +0000856 ps = subprocess.Popen(['ps', '-o', "command=CMD", str(os.getpid())], stdout=subprocess.PIPE).communicate()[0]
857 lines = ps.split('\n')
858 cmd_line = lines[1]
859 return cmd_line
Johnny Chencd0279d2010-09-20 18:07:50 +0000860
Johnny Chend96b5682010-11-05 17:30:53 +0000861# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +0000862# #
863# Execution of the test driver starts here #
864# #
Johnny Chend96b5682010-11-05 17:30:53 +0000865# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +0000866
Johnny Chen2891bb02011-09-16 01:04:26 +0000867def checkDsymForUUIDIsNotOn():
Johnny Chen6a4e0872011-09-16 17:50:44 +0000868 cmd = ["defaults", "read", "com.apple.DebugSymbols"]
869 pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
870 cmd_output = pipe.stdout.read()
Johnny Chen178c8d92011-09-16 18:03:19 +0000871 if cmd_output and "DBGFileMappedPaths = " in cmd_output:
Johnny Chen6a451482011-09-16 18:09:45 +0000872 print "%s =>" % ' '.join(cmd)
Johnny Chen6a4e0872011-09-16 17:50:44 +0000873 print cmd_output
Johnny Chen2891bb02011-09-16 01:04:26 +0000874 print "Disable automatic lookup and caching of dSYMs before running the test suite!"
875 print "Exiting..."
876 sys.exit(0)
877
878# On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
879# does not exist before proceeding to running the test suite.
880if sys.platform.startswith("darwin"):
881 checkDsymForUUIDIsNotOn()
882
Johnny Chen9707bb62010-06-25 21:14:08 +0000883#
Johnny Chenaf149a02010-09-16 17:11:30 +0000884# Start the actions by first parsing the options while setting up the test
885# directories, followed by setting up the search paths for lldb utilities;
886# then, we walk the directory trees and collect the tests into our test suite.
Johnny Chen9707bb62010-06-25 21:14:08 +0000887#
Johnny Chenaf149a02010-09-16 17:11:30 +0000888parseOptionsAndInitTestdirs()
Johnny Chen9707bb62010-06-25 21:14:08 +0000889setupSysPath()
Johnny Chen91960d32010-09-08 20:56:16 +0000890
891#
892# If '-d' is specified, do a delay of 10 seconds for the debugger to attach.
893#
894if delay:
Johnny Chencd0279d2010-09-20 18:07:50 +0000895 doDelay(10)
Johnny Chen91960d32010-09-08 20:56:16 +0000896
Johnny Chen49f2f7a2010-09-20 17:25:45 +0000897#
Johnny Chen41998192010-10-01 22:59:49 +0000898# If '-l' is specified, do not skip the long running tests.
899if not skipLongRunningTest:
900 os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
901
902#
Johnny Chen79723352010-10-12 15:53:22 +0000903# Walk through the testdirs while collecting tests.
Johnny Chen49f2f7a2010-09-20 17:25:45 +0000904#
Johnny Chen9707bb62010-06-25 21:14:08 +0000905for testdir in testdirs:
906 os.path.walk(testdir, visit, 'Test')
907
Johnny Chenb40056b2010-09-21 00:09:27 +0000908#
Johnny Chen9707bb62010-06-25 21:14:08 +0000909# Now that we have loaded all the test cases, run the whole test suite.
Johnny Chenb40056b2010-09-21 00:09:27 +0000910#
Johnny Chencd0279d2010-09-20 18:07:50 +0000911
Johnny Chen1bfbd412010-06-29 19:44:16 +0000912# For the time being, let's bracket the test runner within the
913# lldb.SBDebugger.Initialize()/Terminate() pair.
Johnny Chen01f2a6a2010-08-10 20:23:55 +0000914import lldb, atexit
Johnny Chen6b6f5ba2010-10-14 16:36:49 +0000915# Update: the act of importing lldb now executes lldb.SBDebugger.Initialize(),
916# there's no need to call it a second time.
917#lldb.SBDebugger.Initialize()
Johnny Chen01f2a6a2010-08-10 20:23:55 +0000918atexit.register(lambda: lldb.SBDebugger.Terminate())
Johnny Chen1bfbd412010-06-29 19:44:16 +0000919
Johnny Chen909e5a62010-07-01 22:52:57 +0000920# Create a singleton SBDebugger in the lldb namespace.
921lldb.DBG = lldb.SBDebugger.Create()
922
Johnny Chen4f93bf12010-12-10 00:51:23 +0000923# Put the blacklist in the lldb namespace, to be used by lldb.TestBase.
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000924lldb.blacklist = blacklist
925
Johnny Chene00c9302011-10-10 22:03:44 +0000926# Put dont/just_do_python_api_test in the lldb namespace.
Johnny Chen4f93bf12010-12-10 00:51:23 +0000927lldb.dont_do_python_api_test = dont_do_python_api_test
928lldb.just_do_python_api_test = just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000929lldb.just_do_benchmarks_test = just_do_benchmarks_test
Johnny Chen4f93bf12010-12-10 00:51:23 +0000930
Johnny Chen5f2ed172011-10-20 18:43:28 +0000931# Put bmExecutable, bmBreakpointSpec, and bmIterationCount into the lldb namespace, too.
Johnny Chene00c9302011-10-10 22:03:44 +0000932lldb.bmExecutable = bmExecutable
933lldb.bmBreakpointSpec = bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000934lldb.bmIterationCount = bmIterationCount
Johnny Chene00c9302011-10-10 22:03:44 +0000935
Johnny Chen38f823c2011-10-11 01:30:27 +0000936# And don't forget the runHooks!
937lldb.runHooks = runHooks
938
Johnny Chencd0279d2010-09-20 18:07:50 +0000939# Turn on lldb loggings if necessary.
940lldbLoggings()
Johnny Chen909e5a62010-07-01 22:52:57 +0000941
Johnny Chen7987ac92010-08-09 20:40:52 +0000942# Install the control-c handler.
943unittest2.signals.installHandler()
944
Johnny Chen125fc2b2010-10-21 16:55:35 +0000945# If sdir_name is not specified through the '-s sdir_name' option, get a
946# timestamp string and export it as LLDB_SESSION_DIR environment var. This will
947# be used when/if we want to dump the session info of individual test cases
948# later on.
Johnny Chence681462010-10-19 00:25:01 +0000949#
950# See also TestBase.dumpSessionInfo() in lldbtest.py.
Johnny Chen125fc2b2010-10-21 16:55:35 +0000951if not sdir_name:
952 import datetime
Johnny Chen41fae812010-10-29 22:26:38 +0000953 # The windows platforms don't like ':' in the pathname.
Johnny Chen76bd0102010-10-28 16:32:13 +0000954 timestamp = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
Johnny Chen125fc2b2010-10-21 16:55:35 +0000955 sdir_name = timestamp
Peter Collingbourne132476f2011-06-20 23:55:53 +0000956os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), sdir_name)
Johnny Chen067022b2011-01-19 19:31:46 +0000957
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000958if not noHeaders:
959 sys.stderr.write("\nSession logs for test failures/errors/unexpected successes"
960 " will go into directory '%s'\n" % sdir_name)
961 sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
Johnny Chence681462010-10-19 00:25:01 +0000962
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000963if not os.path.isdir(sdir_name):
964 os.mkdir(sdir_name)
965fname = os.path.join(sdir_name, "svn-info")
966with open(fname, "w") as f:
967 print >> f, svn_info
968 print >> f, "Command invoked: %s\n" % getMyCommandLine()
969
Johnny Chenb40056b2010-09-21 00:09:27 +0000970#
971# Invoke the default TextTestRunner to run the test suite, possibly iterating
972# over different configurations.
973#
974
Johnny Chenb40056b2010-09-21 00:09:27 +0000975iterArchs = False
Johnny Chenf032d902010-09-21 00:16:09 +0000976iterCompilers = False
Johnny Chenb40056b2010-09-21 00:09:27 +0000977
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000978if not archs and "archs" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +0000979 archs = config["archs"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000980
981if isinstance(archs, list) and len(archs) >= 1:
982 iterArchs = True
983
984if not compilers and "compilers" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +0000985 compilers = config["compilers"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000986
987if isinstance(compilers, list) and len(compilers) >= 1:
988 iterCompilers = True
Johnny Chenb40056b2010-09-21 00:09:27 +0000989
Johnny Chen953864a2010-10-12 21:35:54 +0000990# Make a shallow copy of sys.path, we need to manipulate the search paths later.
991# This is only necessary if we are relocated and with different configurations.
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000992if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +0000993 old_sys_path = sys.path[:]
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000994# If we iterate on archs or compilers, there is a chance we want to split stderr/stdout.
995if iterArchs or iterCompilers:
Johnny Chen953864a2010-10-12 21:35:54 +0000996 old_stderr = sys.stderr
997 old_stdout = sys.stdout
998 new_stderr = None
999 new_stdout = None
1000
Johnny Chend96b5682010-11-05 17:30:53 +00001001# Iterating over all possible architecture and compiler combinations.
Johnny Chenb40056b2010-09-21 00:09:27 +00001002for ia in range(len(archs) if iterArchs else 1):
1003 archConfig = ""
1004 if iterArchs:
Johnny Chen18a921f2010-09-30 17:11:58 +00001005 os.environ["ARCH"] = archs[ia]
Johnny Chenb40056b2010-09-21 00:09:27 +00001006 archConfig = "arch=%s" % archs[ia]
1007 for ic in range(len(compilers) if iterCompilers else 1):
1008 if iterCompilers:
Johnny Chen18a921f2010-09-30 17:11:58 +00001009 os.environ["CC"] = compilers[ic]
Johnny Chenb40056b2010-09-21 00:09:27 +00001010 configString = "%s compiler=%s" % (archConfig, compilers[ic])
1011 else:
1012 configString = archConfig
1013
Johnny Chenb40056b2010-09-21 00:09:27 +00001014 if iterArchs or iterCompilers:
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001015 # Translate ' ' to '-' for pathname component.
1016 from string import maketrans
1017 tbl = maketrans(' ', '-')
1018 configPostfix = configString.translate(tbl)
1019
1020 # Check whether we need to split stderr/stdout into configuration
1021 # specific files.
1022 if old_stderr.name != '<stderr>' and config.get('split_stderr'):
1023 if new_stderr:
1024 new_stderr.close()
1025 new_stderr = open("%s.%s" % (old_stderr.name, configPostfix), "w")
1026 sys.stderr = new_stderr
1027 if old_stdout.name != '<stdout>' and config.get('split_stdout'):
1028 if new_stdout:
1029 new_stdout.close()
1030 new_stdout = open("%s.%s" % (old_stdout.name, configPostfix), "w")
1031 sys.stdout = new_stdout
1032
Johnny Chen953864a2010-10-12 21:35:54 +00001033 # If we specified a relocated directory to run the test suite, do
1034 # the extra housekeeping to copy the testdirs to a configStringified
1035 # directory and to update sys.path before invoking the test runner.
1036 # The purpose is to separate the configuration-specific directories
1037 # from each other.
1038 if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001039 from shutil import copytree, ignore_patterns
1040
Johnny Chen953864a2010-10-12 21:35:54 +00001041 newrdir = "%s.%s" % (rdir, configPostfix)
1042
1043 # Copy the tree to a new directory with postfix name configPostfix.
1044 copytree(rdir, newrdir, ignore=ignore_patterns('*.pyc', '*.o', '*.d'))
1045
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001046 # Update the LLDB_TEST environment variable to reflect new top
Johnny Chen953864a2010-10-12 21:35:54 +00001047 # level test directory.
1048 #
1049 # See also lldbtest.TestBase.setUpClass(cls).
1050 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
1051 os.environ["LLDB_TEST"] = os.path.join(newrdir, 'test')
1052 else:
1053 os.environ["LLDB_TEST"] = newrdir
1054
1055 # And update the Python search paths for modules.
1056 sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
1057
1058 # Output the configuration.
Johnny Chenb40056b2010-09-21 00:09:27 +00001059 sys.stderr.write("\nConfiguration: " + configString + "\n")
Johnny Chen953864a2010-10-12 21:35:54 +00001060
1061 #print "sys.stderr name is", sys.stderr.name
1062 #print "sys.stdout name is", sys.stdout.name
1063
1064 # First, write out the number of collected test cases.
Johnny Cheneef90572011-10-22 00:57:05 +00001065 if not noHeaders:
1066 sys.stderr.write(separator + "\n")
1067 sys.stderr.write("Collected %d test%s\n\n"
1068 % (suite.countTestCases(),
1069 suite.countTestCases() != 1 and "s" or ""))
Johnny Chen953864a2010-10-12 21:35:54 +00001070
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001071 class LLDBTestResult(unittest2.TextTestResult):
1072 """
Johnny Chen26be4532010-11-09 23:56:14 +00001073 Enforce a singleton pattern to allow introspection of test progress.
1074
1075 Overwrite addError(), addFailure(), and addExpectedFailure() methods
1076 to enable each test instance to track its failure/error status. It
1077 is used in the LLDB test framework to emit detailed trace messages
1078 to a log file for easier human inspection of test failres/errors.
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001079 """
1080 __singleton__ = None
Johnny Chen360dd372010-11-29 17:50:10 +00001081 __ignore_singleton__ = False
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001082
1083 def __init__(self, *args):
Johnny Chen360dd372010-11-29 17:50:10 +00001084 if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
Johnny Chend2acdb32010-11-16 22:42:58 +00001085 raise Exception("LLDBTestResult instantiated more than once")
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001086 super(LLDBTestResult, self).__init__(*args)
1087 LLDBTestResult.__singleton__ = self
1088 # Now put this singleton into the lldb module namespace.
1089 lldb.test_result = self
Johnny Chen810042e2011-01-05 20:24:11 +00001090 # Computes the format string for displaying the counter.
1091 global suite
1092 counterWidth = len(str(suite.countTestCases()))
1093 self.fmt = "%" + str(counterWidth) + "d: "
Johnny Chenc87fd492011-01-05 22:50:11 +00001094 self.indentation = ' ' * (counterWidth + 2)
Johnny Chen810042e2011-01-05 20:24:11 +00001095 # This counts from 1 .. suite.countTestCases().
1096 self.counter = 0
1097
Johnny Chenc87fd492011-01-05 22:50:11 +00001098 def getDescription(self, test):
1099 doc_first_line = test.shortDescription()
1100 if self.descriptions and doc_first_line:
1101 return '\n'.join((str(test), self.indentation + doc_first_line))
1102 else:
1103 return str(test)
1104
Johnny Chen810042e2011-01-05 20:24:11 +00001105 def startTest(self, test):
1106 self.counter += 1
1107 if self.showAll:
1108 self.stream.write(self.fmt % self.counter)
1109 super(LLDBTestResult, self).startTest(test)
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001110
Johnny Chence681462010-10-19 00:25:01 +00001111 def addError(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001112 global sdir_has_content
1113 sdir_has_content = True
Johnny Chence681462010-10-19 00:25:01 +00001114 super(LLDBTestResult, self).addError(test, err)
1115 method = getattr(test, "markError", None)
1116 if method:
1117 method()
1118
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001119 def addFailure(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001120 global sdir_has_content
1121 sdir_has_content = True
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001122 super(LLDBTestResult, self).addFailure(test, err)
1123 method = getattr(test, "markFailure", None)
1124 if method:
1125 method()
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001126
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001127 def addExpectedFailure(self, test, err):
1128 global sdir_has_content
1129 sdir_has_content = True
1130 super(LLDBTestResult, self).addExpectedFailure(test, err)
1131 method = getattr(test, "markExpectedFailure", None)
1132 if method:
1133 method()
1134
Johnny Chenf5b89092011-08-15 23:09:08 +00001135 def addSkip(self, test, reason):
1136 global sdir_has_content
1137 sdir_has_content = True
1138 super(LLDBTestResult, self).addSkip(test, reason)
1139 method = getattr(test, "markSkippedTest", None)
1140 if method:
1141 method()
1142
Johnny Chenab2f0662011-05-06 20:30:22 +00001143 def addUnexpectedSuccess(self, test):
1144 global sdir_has_content
1145 sdir_has_content = True
1146 super(LLDBTestResult, self).addUnexpectedSuccess(test)
1147 method = getattr(test, "markUnexpectedSuccess", None)
1148 if method:
1149 method()
1150
Johnny Chen26be4532010-11-09 23:56:14 +00001151 # Invoke the test runner.
Johnny Chend2acdb32010-11-16 22:42:58 +00001152 if count == 1:
Johnny Chen7d6d8442010-12-03 19:59:35 +00001153 result = unittest2.TextTestRunner(stream=sys.stderr,
1154 verbosity=verbose,
1155 failfast=failfast,
Johnny Chend2acdb32010-11-16 22:42:58 +00001156 resultclass=LLDBTestResult).run(suite)
1157 else:
Johnny Chend6e7ca22010-11-29 17:52:43 +00001158 # We are invoking the same test suite more than once. In this case,
1159 # mark __ignore_singleton__ flag as True so the signleton pattern is
1160 # not enforced.
Johnny Chen360dd372010-11-29 17:50:10 +00001161 LLDBTestResult.__ignore_singleton__ = True
Johnny Chend2acdb32010-11-16 22:42:58 +00001162 for i in range(count):
Johnny Chen7d6d8442010-12-03 19:59:35 +00001163 result = unittest2.TextTestRunner(stream=sys.stderr,
1164 verbosity=verbose,
1165 failfast=failfast,
Johnny Chen360dd372010-11-29 17:50:10 +00001166 resultclass=LLDBTestResult).run(suite)
Johnny Chenb40056b2010-09-21 00:09:27 +00001167
Johnny Chen1bfbd412010-06-29 19:44:16 +00001168
Johnny Chen63c2cba2010-10-29 22:20:36 +00001169if sdir_has_content:
Johnny Chenab2f0662011-05-06 20:30:22 +00001170 sys.stderr.write("Session logs for test failures/errors/unexpected successes"
1171 " can be found in directory '%s'\n" % sdir_name)
Johnny Chen63c2cba2010-10-29 22:20:36 +00001172
Johnny Chencd0279d2010-09-20 18:07:50 +00001173# Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1174# This should not be necessary now.
Johnny Chen83f6e512010-08-13 22:58:44 +00001175if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
Johnny Chen83f6e512010-08-13 22:58:44 +00001176 print "Terminating Test suite..."
1177 subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1178
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001179# Exiting.
1180sys.exit(not result.wasSuccessful)