blob: 8e8a2f26a0e0617e34f5c18c5d04416eb2608e40 [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
Greg Clayton4793e942012-09-04 15:42:49 +000023import os
24import platform
25import signal
Johnny Chen2891bb02011-09-16 01:04:26 +000026import subprocess
Greg Clayton4793e942012-09-04 15:42:49 +000027import sys
28import textwrap
29import time
Johnny Chen75e28f92010-08-05 23:42:46 +000030import unittest2
Enrico Granatabc0c5a62013-02-08 23:39:18 +000031import progress
Johnny Chen9707bb62010-06-25 21:14:08 +000032
Filipe Cabecinhasd3eb8372013-02-16 09:05:23 +000033if sys.version_info >= (2, 7):
34 argparse = __import__('argparse')
35else:
36 argparse = __import__('argparse_compat')
37
Johnny Chen26901c82011-03-11 19:47:23 +000038def is_exe(fpath):
Johnny Chenf2c7b282011-04-26 23:10:51 +000039 """Returns true if fpath is an executable."""
Johnny Chen26901c82011-03-11 19:47:23 +000040 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
41
Johnny Chen26901c82011-03-11 19:47:23 +000042def which(program):
Johnny Chenf2c7b282011-04-26 23:10:51 +000043 """Returns the full path to a program; None otherwise."""
Johnny Chen26901c82011-03-11 19:47:23 +000044 fpath, fname = os.path.split(program)
45 if fpath:
46 if is_exe(program):
47 return program
48 else:
49 for path in os.environ["PATH"].split(os.pathsep):
50 exe_file = os.path.join(path, program)
51 if is_exe(exe_file):
52 return exe_file
53 return None
54
Johnny Chen877c7e42010-08-07 00:16:07 +000055class _WritelnDecorator(object):
56 """Used to decorate file-like objects with a handy 'writeln' method"""
57 def __init__(self,stream):
58 self.stream = stream
59
60 def __getattr__(self, attr):
61 if attr in ('stream', '__getstate__'):
62 raise AttributeError(attr)
63 return getattr(self.stream,attr)
64
65 def writeln(self, arg=None):
66 if arg:
67 self.write(arg)
68 self.write('\n') # text-mode streams translate to \r\n if needed
69
Johnny Chen9707bb62010-06-25 21:14:08 +000070#
71# Global variables:
72#
73
Enrico Granataac3a8e22012-09-21 19:10:53 +000074# Dictionary of categories
75# When you define a new category for your testcases, be sure to add it here, or the test suite
76# will gladly complain as soon as you try to use it. This allows us to centralize which categories
77# exist, and to provide a description for each one
78validCategories = {
79'dataformatters':'Tests related to the type command and the data formatters subsystem',
80'expression':'Tests related to the expression parser',
81'objc':'Tests related to the Objective-C programming language support',
Jim Ingham60139f32013-02-25 23:51:06 +000082'pyapi':'Tests related to the Python API',
83'basic_process': 'Basic process execution sniff tests.'
Enrico Granataac3a8e22012-09-21 19:10:53 +000084}
85
Johnny Chen9707bb62010-06-25 21:14:08 +000086# The test suite.
Johnny Chen75e28f92010-08-05 23:42:46 +000087suite = unittest2.TestSuite()
Johnny Chen9707bb62010-06-25 21:14:08 +000088
Johnny Chen4f93bf12010-12-10 00:51:23 +000089# By default, both command line and Python API tests are performed.
Johnny Chen3ebdacc2010-12-10 18:52:10 +000090# Use @python_api_test decorator, defined in lldbtest.py, to mark a test as
91# a Python API test.
Johnny Chen4f93bf12010-12-10 00:51:23 +000092dont_do_python_api_test = False
93
94# By default, both command line and Python API tests are performed.
Johnny Chen4f93bf12010-12-10 00:51:23 +000095just_do_python_api_test = False
96
Johnny Chen82ccf402011-07-30 01:39:58 +000097# By default, benchmarks tests are not run.
98just_do_benchmarks_test = False
99
Johnny Chena3ed7d82012-04-06 00:56:05 +0000100# By default, both dsym and dwarf tests are performed.
101# Use @dsym_test or @dwarf_test decorators, defined in lldbtest.py, to mark a test
102# as a dsym or dwarf test. Use '-N dsym' or '-N dwarf' to exclude dsym or dwarf
103# tests from running.
Daniel Maleab8106282012-11-20 16:07:33 +0000104dont_do_dsym_test = "linux" in sys.platform
Johnny Chena3ed7d82012-04-06 00:56:05 +0000105dont_do_dwarf_test = False
106
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000107# The blacklist is optional (-b blacklistFile) and allows a central place to skip
108# testclass's and/or testclass.testmethod's.
109blacklist = None
110
111# The dictionary as a result of sourcing blacklistFile.
112blacklistConfig = {}
113
Enrico Granataac3a8e22012-09-21 19:10:53 +0000114# The list of categories we said we care about
115categoriesList = None
116# set to true if we are going to use categories for cherry-picking test cases
117useCategories = False
118# use this to track per-category failures
119failuresPerCategory = {}
120
Sean Callanan0acf4c62012-10-24 22:45:39 +0000121# The path to LLDB.framework is optional.
122lldbFrameworkPath = None
123
124# The path to lldb is optional
125lldbExecutablePath = None
126
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000127# The config file is optional.
128configFile = None
129
Johnny Chend2acdb32010-11-16 22:42:58 +0000130# Test suite repeat count. Can be overwritten with '-# count'.
131count = 1
132
Johnny Chenb40056b2010-09-21 00:09:27 +0000133# The dictionary as a result of sourcing configFile.
134config = {}
Johnny Chenac97a6b2012-04-16 18:55:15 +0000135# The pre_flight and post_flight functions come from reading a config file.
136pre_flight = None
137post_flight = None
Johnny Chenb40056b2010-09-21 00:09:27 +0000138
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000139# The 'archs' and 'compilers' can be specified via either command line or configFile,
Greg Clayton4793e942012-09-04 15:42:49 +0000140# with the command line overriding the configFile. The corresponding options can be
Filipe Cabecinhasd3eb8372013-02-16 09:05:23 +0000141# specified more than once. For example, "-A x86_64 -A i386" => archs=['x86_64', 'i386']
Greg Clayton4793e942012-09-04 15:42:49 +0000142# and "-C gcc -C clang" => compilers=['gcc', 'clang'].
143archs = None # Must be initialized after option parsing
144compilers = None # Must be initialized after option parsing
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000145
Johnny Chen1abe4c02012-03-20 00:33:51 +0000146# The arch might dictate some specific CFLAGS to be passed to the toolchain to build
147# the inferior programs. The global variable cflags_extras provides a hook to do
148# just that.
149cflags_extras = ''
150
Johnny Chen91960d32010-09-08 20:56:16 +0000151# Delay startup in order for the debugger to attach.
152delay = False
153
Johnny Chend5362332011-01-29 01:21:04 +0000154# Dump the Python sys.path variable. Use '-D' to dump sys.path.
Johnny Chen50bc6382011-01-29 01:16:52 +0000155dumpSysPath = False
156
Johnny Chene00c9302011-10-10 22:03:44 +0000157# Full path of the benchmark executable, as specified by the '-e' option.
158bmExecutable = None
159# The breakpoint specification of bmExecutable, as specified by the '-x' option.
160bmBreakpointSpec = None
Johnny Chen5f2ed172011-10-20 18:43:28 +0000161# The benchamrk iteration count, as specified by the '-y' option.
162bmIterationCount = -1
Johnny Chene00c9302011-10-10 22:03:44 +0000163
Johnny Chene9eae812012-01-18 05:15:00 +0000164# By default, don't exclude any directories. Use '-X' to add one excluded directory.
165excluded = set(['.svn', '.git'])
166
Johnny Chen7d6d8442010-12-03 19:59:35 +0000167# By default, failfast is False. Use '-F' to overwrite it.
168failfast = False
169
Johnny Chenc5fa0052011-07-29 22:54:56 +0000170# The filters (testclass.testmethod) used to admit tests into our test suite.
171filters = []
Johnny Chenb62436b2010-10-06 20:40:56 +0000172
Johnny Chen38f823c2011-10-11 01:30:27 +0000173# The runhooks is a list of lldb commands specifically for the debugger.
174# Use '-k' to specify a runhook.
175runHooks = []
176
Johnny Chena224cd12010-11-08 01:21:03 +0000177# If '-g' is specified, the filterspec is not exclusive. If a test module does
178# not contain testclass.testmethod which matches the filterspec, the whole test
179# module is still admitted into our test suite. fs4all flag defaults to True.
180fs4all = True
Johnny Chenb62436b2010-10-06 20:40:56 +0000181
Johnny Chenaf149a02010-09-16 17:11:30 +0000182# Ignore the build search path relative to this script to locate the lldb.py module.
183ignore = False
184
Johnny Chen028d8eb2011-11-17 19:57:27 +0000185# By default, we do not skip build and cleanup. Use '-S' option to override.
186skip_build_and_cleanup = False
187
Johnny Chen548aefd2010-10-11 22:25:46 +0000188# By default, we skip long running test case. Use '-l' option to override.
Johnny Chen028d8eb2011-11-17 19:57:27 +0000189skip_long_running_test = True
Johnny Chen41998192010-10-01 22:59:49 +0000190
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000191# By default, we print the build dir, lldb version, and svn info. Use '-n' option to
192# turn it off.
193noHeaders = False
194
Daniel Malea361eb432013-02-15 21:31:37 +0000195# Parsable mode silences headers, and any other output this script might generate, and instead
196# prints machine-readable output similar to what clang tests produce.
197parsable = False
198
Johnny Chen7c52ff12010-09-27 23:29:54 +0000199# The regular expression pattern to match against eligible filenames as our test cases.
200regexp = None
201
Johnny Chen548aefd2010-10-11 22:25:46 +0000202# By default, tests are executed in place and cleanups are performed afterwards.
203# Use '-r dir' option to relocate the tests and their intermediate files to a
204# different directory and to forgo any cleanups. The directory specified must
205# not exist yet.
206rdir = None
207
Johnny Chen125fc2b2010-10-21 16:55:35 +0000208# By default, recorded session info for errored/failed test are dumped into its
209# own file under a session directory named after the timestamp of the test suite
210# run. Use '-s session-dir-name' to specify a specific dir name.
211sdir_name = None
212
Johnny Chen63c2cba2010-10-29 22:20:36 +0000213# Set this flag if there is any session info dumped during the test run.
214sdir_has_content = False
215
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000216# svn_info stores the output from 'svn info lldb.base.dir'.
217svn_info = ''
218
Enrico Granata814c8132013-04-11 23:48:00 +0000219# svn_silent means do not try to obtain svn status
220svn_silent = True
221
Johnny Chen9707bb62010-06-25 21:14:08 +0000222# Default verbosity is 0.
Jim Ingham75f260a2013-02-19 20:39:27 +0000223verbose = 1
Johnny Chen9707bb62010-06-25 21:14:08 +0000224
Johnny Chen08967192011-11-18 00:19:29 +0000225# Set to True only if verbose is 0 and LLDB trace mode is off.
226progress_bar = False
227
Peter Collingbourne61aca482011-06-20 19:06:29 +0000228# By default, search from the script directory.
229testdirs = [ sys.path[0] ]
Johnny Chen9707bb62010-06-25 21:14:08 +0000230
Johnny Chen877c7e42010-08-07 00:16:07 +0000231# Separator string.
232separator = '-' * 70
233
Daniel Malea24765572013-02-20 20:12:11 +0000234failed = False
Johnny Chen9707bb62010-06-25 21:14:08 +0000235
Greg Clayton4793e942012-09-04 15:42:49 +0000236def usage(parser):
237 parser.print_help()
Jim Ingham4f347cb2011-04-13 21:11:41 +0000238 if verbose > 0:
239 print """
Johnny Chen9656ab22010-10-22 19:00:18 +0000240Examples:
241
Johnny Chena224cd12010-11-08 01:21:03 +0000242This is an example of using the -f option to pinpoint to a specfic test class
243and test method to be run:
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000244
Johnny Chena224cd12010-11-08 01:21:03 +0000245$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000246----------------------------------------------------------------------
247Collected 1 test
248
249test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
250Test 'frame variable this' when stopped on a class constructor. ... ok
251
252----------------------------------------------------------------------
253Ran 1 test in 1.396s
254
255OK
Johnny Chen9656ab22010-10-22 19:00:18 +0000256
257And this is an example of using the -p option to run a single file (the filename
258matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
259
260$ ./dotest.py -v -p ObjC
261----------------------------------------------------------------------
262Collected 4 tests
263
264test_break_with_dsym (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000265Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000266test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000267Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000268test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
269Lookup objective-c data types and evaluate expressions. ... ok
270test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
271Lookup objective-c data types and evaluate expressions. ... ok
272
273----------------------------------------------------------------------
274Ran 4 tests in 16.661s
275
276OK
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000277
Johnny Chen58f93922010-06-29 23:10:39 +0000278Running of this script also sets up the LLDB_TEST environment variable so that
Johnny Chenaf149a02010-09-16 17:11:30 +0000279individual test cases can locate their supporting files correctly. The script
280tries to set up Python's search paths for modules by looking at the build tree
Johnny Chena85859f2010-11-11 22:14:56 +0000281relative to this script. See also the '-i' option in the following example.
282
283Finally, this is an example of using the lldb.py module distributed/installed by
284Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
285option to add some delay between two tests. It uses ARCH=x86_64 to specify that
286as the architecture and CC=clang to specify the compiler used for the test run:
287
288$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
289
290Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
291----------------------------------------------------------------------
292Collected 2 tests
293
294test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
295Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
296test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
297Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
298
299----------------------------------------------------------------------
300Ran 2 tests in 5.659s
301
302OK
303
304The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
305notify the directory containing the session logs for test failures or errors.
306In case there is any test failure/error, a similar message is appended at the
307end of the stderr output for your convenience.
Johnny Chenfde69bc2010-09-14 22:01:40 +0000308
309Environment variables related to loggings:
310
311o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
312 with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
313
314o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
315 'process.gdb-remote' subsystem with a default option of 'packets' if
316 GDB_REMOTE_LOG_OPTION is not defined.
Johnny Chen9707bb62010-06-25 21:14:08 +0000317"""
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000318 sys.exit(0)
Johnny Chen9707bb62010-06-25 21:14:08 +0000319
320
Johnny Chenaf149a02010-09-16 17:11:30 +0000321def parseOptionsAndInitTestdirs():
322 """Initialize the list of directories containing our unittest scripts.
323
324 '-h/--help as the first option prints out usage info and exit the program.
325 """
326
Johnny Chen4f93bf12010-12-10 00:51:23 +0000327 global dont_do_python_api_test
328 global just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000329 global just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +0000330 global dont_do_dsym_test
331 global dont_do_dwarf_test
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000332 global blacklist
333 global blacklistConfig
Enrico Granataac3a8e22012-09-21 19:10:53 +0000334 global categoriesList
335 global validCategories
336 global useCategories
Sean Callanan0acf4c62012-10-24 22:45:39 +0000337 global lldbFrameworkPath
338 global lldbExecutablePath
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000339 global configFile
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000340 global archs
341 global compilers
Johnny Chend2acdb32010-11-16 22:42:58 +0000342 global count
Johnny Chenaf149a02010-09-16 17:11:30 +0000343 global delay
Johnny Chen50bc6382011-01-29 01:16:52 +0000344 global dumpSysPath
Johnny Chene00c9302011-10-10 22:03:44 +0000345 global bmExecutable
346 global bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000347 global bmIterationCount
Johnny Chen7d6d8442010-12-03 19:59:35 +0000348 global failfast
Johnny Chenc5fa0052011-07-29 22:54:56 +0000349 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000350 global fs4all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000351 global ignore
Johnny Chen08967192011-11-18 00:19:29 +0000352 global progress_bar
Johnny Chen38f823c2011-10-11 01:30:27 +0000353 global runHooks
Johnny Chen028d8eb2011-11-17 19:57:27 +0000354 global skip_build_and_cleanup
355 global skip_long_running_test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000356 global noHeaders
Daniel Malea361eb432013-02-15 21:31:37 +0000357 global parsable
Johnny Chen7c52ff12010-09-27 23:29:54 +0000358 global regexp
Johnny Chen548aefd2010-10-11 22:25:46 +0000359 global rdir
Johnny Chen125fc2b2010-10-21 16:55:35 +0000360 global sdir_name
Enrico Granata814c8132013-04-11 23:48:00 +0000361 global svn_silent
Johnny Chenaf149a02010-09-16 17:11:30 +0000362 global verbose
363 global testdirs
364
Jim Ingham4f347cb2011-04-13 21:11:41 +0000365 do_help = False
366
Greg Clayton4793e942012-09-04 15:42:49 +0000367 parser = argparse.ArgumentParser(description='description', prefix_chars='+-', add_help=False)
368 group = None
Johnny Chenaf149a02010-09-16 17:11:30 +0000369
Greg Clayton4793e942012-09-04 15:42:49 +0000370 # Helper function for boolean options (group will point to the current group when executing X)
371 X = lambda optstr, helpstr, **kwargs: group.add_argument(optstr, help=helpstr, action='store_true', **kwargs)
372
373 group = parser.add_argument_group('Help')
374 group.add_argument('-h', '--help', dest='h', action='store_true', help="Print this help message and exit. Add '-v' for more detailed help.")
375
376 # C and Python toolchain options
377 group = parser.add_argument_group('Toolchain options')
378 group.add_argument('-A', '--arch', metavar='arch', action='append', dest='archs', help=textwrap.dedent('''Specify the architecture(s) to test. This option can be specified more than once'''))
379 group.add_argument('-C', '--compiler', metavar='compiler', dest='compilers', action='append', help=textwrap.dedent('''Specify the compiler(s) used to build the inferior executables. The compiler path can be an executable basename or a full path to a compiler executable. This option can be specified multiple times.'''))
380 # FIXME? This won't work for different extra flags according to each arch.
381 group.add_argument('-E', metavar='extra-flags', help=textwrap.dedent('''Specify the extra flags to be passed to the toolchain when building the inferior programs to be debugged
382 suggestions: do not lump the "-A arch1 -A arch2" together such that the -E option applies to only one of the architectures'''))
383 X('-D', 'Dump the Python sys.path variable')
384
385 # Test filtering options
386 group = parser.add_argument_group('Test filtering options')
387 group.add_argument('-N', choices=['dwarf', 'dsym'], help="Don't do test cases marked with the @dsym decorator by passing 'dsym' as the option arg, or don't do test cases marked with the @dwarf decorator by passing 'dwarf' as the option arg")
388 X('-a', "Don't do lldb Python API tests")
389 X('+a', "Just do lldb Python API tests. Do not specify along with '+a'", dest='plus_a')
390 X('+b', 'Just do benchmark tests', dest='plus_b')
391 group.add_argument('-b', metavar='blacklist', help='Read a blacklist file specified after this option')
Enrico Granata58b03a42012-12-14 00:07:09 +0000392 group.add_argument('-f', metavar='filterspec', action='append', help='Specify a filter, which consists of the test class name, a dot, followed by the test method, to only admit such test into the test suite') # FIXME: Example?
Greg Clayton4793e942012-09-04 15:42:49 +0000393 X('-g', 'If specified, the filterspec by -f is not exclusive, i.e., if a test module does not match the filterspec (testclass.testmethod), the whole module is still admitted to the test suite')
394 X('-l', "Don't skip long running tests")
395 group.add_argument('-p', metavar='pattern', help='Specify a regexp filename pattern for inclusion in the test suite')
396 group.add_argument('-X', metavar='directory', help="Exclude a directory from consideration for test discovery. -X types => if 'types' appear in the pathname components of a potential testfile, it will be ignored")
Enrico Granataac3a8e22012-09-21 19:10:53 +0000397 group.add_argument('-G', '--category', metavar='category', action='append', dest='categoriesList', help=textwrap.dedent('''Specify categories of test cases of interest. Can be specified more than once.'''))
Greg Clayton4793e942012-09-04 15:42:49 +0000398
399 # Configuration options
400 group = parser.add_argument_group('Configuration options')
401 group.add_argument('-c', metavar='config-file', help='Read a config file specified after this option') # FIXME: additional doc.
Sean Callanan0acf4c62012-10-24 22:45:39 +0000402 group.add_argument('--framework', metavar='framework-path', help='The path to LLDB.framework')
403 group.add_argument('--executable', metavar='executable-path', help='The path to the lldb executable')
Greg Clayton4793e942012-09-04 15:42:49 +0000404 group.add_argument('-e', metavar='benchmark-exe', help='Specify the full path of an executable used for benchmark purposes (see also: -x)')
405 group.add_argument('-k', metavar='command', action='append', help="Specify a runhook, which is an lldb command to be executed by the debugger; The option can occur multiple times. The commands are executed one after the other to bring the debugger to a desired state, so that, for example, further benchmarking can be done")
406 group.add_argument('-R', metavar='dir', help='Specify a directory to relocate the tests and their intermediate files to. BE WARNED THAT the directory, if exists, will be deleted before running this test driver. No cleanup of intermediate test files is performed in this case')
407 group.add_argument('-r', metavar='dir', help="Similar to '-R', except that the directory must not exist before running this test driver")
408 group.add_argument('-s', metavar='name', help='Specify the name of the dir created to store the session files of tests with errored or failed status. If not specified, the test driver uses the timestamp as the session dir name')
409 group.add_argument('-x', metavar='breakpoint-spec', help='Specify the breakpoint specification for the benchmark executable')
410 group.add_argument('-y', type=int, metavar='count', help="Specify the iteration count used to collect our benchmarks. An example is the number of times to do 'thread step-over' to measure stepping speed.")
411 group.add_argument('-#', type=int, metavar='sharp', dest='sharp', help='Repeat the test suite for a specified number of times')
412
413 # Test-suite behaviour
414 group = parser.add_argument_group('Runtime behaviour options')
415 X('-d', 'Delay startup for 10 seconds (in order for the debugger to attach)')
416 X('-F', 'Fail fast. Stop the test suite on the first error/failure')
417 X('-i', "Ignore (don't bailout) if 'lldb.py' module cannot be located in the build tree relative to this script; use PYTHONPATH to locate the module")
418 X('-n', "Don't print the headers like build dir, lldb version, and svn info at all")
Jim Ingham75f260a2013-02-19 20:39:27 +0000419 X('-P', "Use the graphic progress bar.")
Daniel Malea361eb432013-02-15 21:31:37 +0000420 X('-q', "Don't print extra output from this script.")
Greg Clayton4793e942012-09-04 15:42:49 +0000421 X('-S', "Skip the build and cleanup while running the test. Use this option with care as you would need to build the inferior(s) by hand and build the executable(s) with the correct name(s). This can be used with '-# n' to stress test certain test cases for n number of times")
422 X('-t', 'Turn on tracing of lldb command and other detailed test executions')
Greg Claytonb85785c2013-02-08 21:52:32 +0000423 group.add_argument('-u', dest='unset_env_varnames', metavar='variable', action='append', help='Specify an environment variable to unset before running the test cases. e.g., -u DYLD_INSERT_LIBRARIES -u MallocScribble')
Greg Clayton4793e942012-09-04 15:42:49 +0000424 X('-v', 'Do verbose mode of unittest framework (print out each test case invocation)')
425 X('-w', 'Insert some wait time (currently 0.5 sec) between consecutive test cases')
Enrico Granata814c8132013-04-11 23:48:00 +0000426 X('-T', 'Obtain and dump svn information for this checkout of LLDB (off by default)')
Greg Clayton4793e942012-09-04 15:42:49 +0000427
428 # Remove the reference to our helper function
429 del X
430
431 group = parser.add_argument_group('Test directories')
432 group.add_argument('args', metavar='test-dir', nargs='*', help='Specify a list of directory names to search for test modules named after Test*.py (test discovery). If empty, search from the current working directory instead.')
433 args = parser.parse_args()
434
435 platform_system = platform.system()
436 platform_machine = platform.machine()
Enrico Granata2d329242012-10-23 22:52:49 +0000437
Greg Claytonb85785c2013-02-08 21:52:32 +0000438 if args.unset_env_varnames:
439 for env_var in args.unset_env_varnames:
440 if env_var in os.environ:
441 # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
442 # is automatically translated into a corresponding call to unsetenv().
443 del os.environ[env_var]
444 #os.unsetenv(env_var)
445
Daniel Malea361eb432013-02-15 21:31:37 +0000446 # only print the args if being verbose (and parsable is off)
447 if args.v and not args.q:
Enrico Granata2d329242012-10-23 22:52:49 +0000448 print args
Greg Clayton4793e942012-09-04 15:42:49 +0000449
450 if args.h:
451 do_help = True
452
453 if args.archs:
454 archs = args.archs
455 else:
456 if platform_system == 'Darwin' and platform_machine == 'x86_64':
457 archs = ['x86_64', 'i386']
Johnny Chenaf149a02010-09-16 17:11:30 +0000458 else:
Greg Clayton4793e942012-09-04 15:42:49 +0000459 archs = [platform_machine]
460
Enrico Granataac3a8e22012-09-21 19:10:53 +0000461 if args.categoriesList:
462 for category in args.categoriesList:
463 if not(category in validCategories):
Enrico Granata2d329242012-10-23 22:52:49 +0000464 print "fatal error: category '" + category + "' is not a valid category"
465 print "if you have added a new category, please edit dotest.py, adding your new category to validCategories"
466 print "else, please specify one or more of the following: " + str(validCategories.keys())
Enrico Granataac3a8e22012-09-21 19:10:53 +0000467 sys.exit(1)
468 categoriesList = set(args.categoriesList)
469 useCategories = True
470 else:
471 categoriesList = []
472
Greg Clayton4793e942012-09-04 15:42:49 +0000473 if args.compilers:
474 compilers = args.compilers
475 else:
476 compilers = ['clang']
477
478 if args.D:
479 dumpSysPath = True
480
481 if args.E:
482 cflags_extras = args.E
483 os.environ['CFLAGS_EXTRAS'] = cflags_extras
484
485 # argparse makes sure we have correct options
486 if args.N == 'dwarf':
487 dont_do_dwarf_test = True
488 elif args.N == 'dsym':
489 dont_do_dsym_test = True
490
491 if args.a:
492 dont_do_python_api_test = True
493
494 if args.plus_a:
495 if dont_do_python_api_test:
496 print "Warning: -a and +a can't both be specified! Using only -a"
497 else:
498 just_do_python_api_test = True
499
500 if args.plus_b:
501 just_do_benchmarks_test = True
502
503 if args.b:
504 if args.b.startswith('-'):
505 usage(parser)
506 blacklistFile = args.b
507 if not os.path.isfile(blacklistFile):
508 print 'Blacklist file:', blacklistFile, 'does not exist!'
509 usage(parser)
510 # Now read the blacklist contents and assign it to blacklist.
511 execfile(blacklistFile, globals(), blacklistConfig)
512 blacklist = blacklistConfig.get('blacklist')
513
514 if args.c:
515 if args.c.startswith('-'):
516 usage(parser)
517 configFile = args.c
518 if not os.path.isfile(configFile):
519 print 'Config file:', configFile, 'does not exist!'
520 usage(parser)
521
522 if args.d:
523 delay = True
524
525 if args.e:
526 if args.e.startswith('-'):
527 usage(parser)
528 bmExecutable = args.e
529 if not is_exe(bmExecutable):
530 usage(parser)
531
532 if args.F:
533 failfast = True
534
535 if args.f:
Enrico Granata58b03a42012-12-14 00:07:09 +0000536 if any([x.startswith('-') for x in args.f]):
Greg Clayton4793e942012-09-04 15:42:49 +0000537 usage(parser)
Enrico Granata58b03a42012-12-14 00:07:09 +0000538 filters.extend(args.f)
Greg Clayton4793e942012-09-04 15:42:49 +0000539
540 if args.g:
541 fs4all = False
542
543 if args.i:
544 ignore = True
545
546 if args.k:
547 runHooks.extend(args.k)
548
549 if args.l:
550 skip_long_running_test = False
551
Sean Callanan0acf4c62012-10-24 22:45:39 +0000552 if args.framework:
553 lldbFrameworkPath = args.framework
554
555 if args.executable:
556 lldbExecutablePath = args.executable
557
Greg Clayton4793e942012-09-04 15:42:49 +0000558 if args.n:
559 noHeaders = True
560
561 if args.p:
562 if args.p.startswith('-'):
563 usage(parser)
564 regexp = args.p
565
Daniel Malea361eb432013-02-15 21:31:37 +0000566 if args.q:
567 noHeaders = True
568 parsable = True
569
Jim Ingham75f260a2013-02-19 20:39:27 +0000570 if args.P:
571 progress_bar = True
572 verbose = 0
573
Greg Clayton4793e942012-09-04 15:42:49 +0000574 if args.R:
575 if args.R.startswith('-'):
576 usage(parser)
577 rdir = os.path.abspath(args.R)
578 if os.path.exists(rdir):
579 import shutil
580 print 'Removing tree:', rdir
581 shutil.rmtree(rdir)
582
583 if args.r:
584 if args.r.startswith('-'):
585 usage(parser)
586 rdir = os.path.abspath(args.r)
587 if os.path.exists(rdir):
588 print 'Relocated directory:', rdir, 'must not exist!'
589 usage(parser)
590
591 if args.S:
592 skip_build_and_cleanup = True
593
594 if args.s:
595 if args.s.startswith('-'):
596 usage(parser)
597 sdir_name = args.s
598
599 if args.t:
600 os.environ['LLDB_COMMAND_TRACE'] = 'YES'
601
Enrico Granata814c8132013-04-11 23:48:00 +0000602 if args.T:
603 svn_silent = False
604
Greg Clayton4793e942012-09-04 15:42:49 +0000605 if args.v:
606 verbose = 2
607
608 if args.w:
609 os.environ['LLDB_WAIT_BETWEEN_TEST_CASES'] = 'YES'
610
611 if args.X:
612 if args.X.startswith('-'):
613 usage(parser)
614 excluded.add(args.X)
615
616 if args.x:
617 if args.x.startswith('-'):
618 usage(parser)
619 bmBreakpointSpec = args.x
620
621 # argparse makes sure we have a number
622 if args.y:
623 bmIterationCount = args.y
624
625 # argparse makes sure we have a number
626 if args.sharp:
627 count = args.sharp
Johnny Chenaf149a02010-09-16 17:11:30 +0000628
Jim Ingham4f347cb2011-04-13 21:11:41 +0000629 if do_help == True:
Greg Clayton4793e942012-09-04 15:42:49 +0000630 usage(parser)
Jim Ingham4f347cb2011-04-13 21:11:41 +0000631
Johnny Chencc659ad2010-12-10 19:02:23 +0000632 # Do not specify both '-a' and '+a' at the same time.
633 if dont_do_python_api_test and just_do_python_api_test:
Greg Clayton4793e942012-09-04 15:42:49 +0000634 usage(parser)
Johnny Chencc659ad2010-12-10 19:02:23 +0000635
Johnny Chenaf149a02010-09-16 17:11:30 +0000636 # Gather all the dirs passed on the command line.
Greg Clayton4793e942012-09-04 15:42:49 +0000637 if len(args.args) > 0:
638 testdirs = map(os.path.abspath, args.args)
Johnny Chenaf149a02010-09-16 17:11:30 +0000639
Johnny Chen548aefd2010-10-11 22:25:46 +0000640 # If '-r dir' is specified, the tests should be run under the relocated
641 # directory. Let's copy the testdirs over.
642 if rdir:
643 from shutil import copytree, ignore_patterns
644
645 tmpdirs = []
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000646 orig_testdirs = testdirs[:]
Johnny Chen548aefd2010-10-11 22:25:46 +0000647 for srcdir in testdirs:
Johnny Chen1abe4c02012-03-20 00:33:51 +0000648 # For example, /Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/hello_watchpoint
649 # shall be split into ['/Volumes/data/lldb/svn/ToT/', 'functionalities/watchpoint/hello_watchpoint'].
650 # Utilize the relative path to the 'test' directory to make our destination dir path.
Greg Clayton4793e942012-09-04 15:42:49 +0000651 if ("test" + os.sep) in srcdir:
652 to_split_on = "test" + os.sep
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000653 else:
654 to_split_on = "test"
655 dstdir = os.path.join(rdir, srcdir.split(to_split_on)[1])
656 dstdir = dstdir.rstrip(os.sep)
Johnny Chen548aefd2010-10-11 22:25:46 +0000657 # Don't copy the *.pyc and .svn stuffs.
658 copytree(srcdir, dstdir, ignore=ignore_patterns('*.pyc', '.svn'))
659 tmpdirs.append(dstdir)
660
661 # This will be our modified testdirs.
662 testdirs = tmpdirs
663
664 # With '-r dir' specified, there's no cleanup of intermediate test files.
665 os.environ["LLDB_DO_CLEANUP"] = 'NO'
666
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000667 # If the original testdirs is ['test'], the make directory has already been copied
Johnny Chen548aefd2010-10-11 22:25:46 +0000668 # recursively and is contained within the rdir/test dir. For anything
669 # else, we would need to copy over the make directory and its contents,
670 # so that, os.listdir(rdir) looks like, for example:
671 #
672 # array_types conditional_break make
673 #
674 # where the make directory contains the Makefile.rules file.
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000675 if len(testdirs) != 1 or os.path.basename(orig_testdirs[0]) != 'test':
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000676 scriptdir = os.path.dirname(__file__)
Johnny Chen548aefd2010-10-11 22:25:46 +0000677 # Don't copy the .svn stuffs.
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000678 copytree(os.path.join(scriptdir, 'make'), os.path.join(rdir, 'make'),
Johnny Chen548aefd2010-10-11 22:25:46 +0000679 ignore=ignore_patterns('.svn'))
680
681 #print "testdirs:", testdirs
682
Johnny Chenb40056b2010-09-21 00:09:27 +0000683 # Source the configFile if specified.
684 # The side effect, if any, will be felt from this point on. An example
685 # config file may be these simple two lines:
686 #
687 # sys.stderr = open("/tmp/lldbtest-stderr", "w")
688 # sys.stdout = open("/tmp/lldbtest-stdout", "w")
689 #
690 # which will reassign the two file objects to sys.stderr and sys.stdout,
691 # respectively.
692 #
Johnny Chen8c130642012-08-22 17:53:02 +0000693 # See also lldb-trunk/examples/test/usage-config.
Johnny Chenac97a6b2012-04-16 18:55:15 +0000694 global config, pre_flight, post_flight
Johnny Chenb40056b2010-09-21 00:09:27 +0000695 if configFile:
696 # Pass config (a dictionary) as the locals namespace for side-effect.
697 execfile(configFile, globals(), config)
Johnny Chenac97a6b2012-04-16 18:55:15 +0000698 print "config:", config
699 if "pre_flight" in config:
700 pre_flight = config["pre_flight"]
701 if not callable(pre_flight):
702 print "fatal error: pre_flight is not callable, exiting."
703 sys.exit(1)
704 if "post_flight" in config:
705 post_flight = config["post_flight"]
706 if not callable(post_flight):
707 print "fatal error: post_flight is not callable, exiting."
708 sys.exit(1)
Johnny Chenb40056b2010-09-21 00:09:27 +0000709 #print "sys.stderr:", sys.stderr
710 #print "sys.stdout:", sys.stdout
711
Johnny Chenaf149a02010-09-16 17:11:30 +0000712
Johnny Chen9707bb62010-06-25 21:14:08 +0000713def setupSysPath():
Johnny Chen8a3c0432011-03-11 20:13:06 +0000714 """
715 Add LLDB.framework/Resources/Python to the search paths for modules.
716 As a side effect, we also discover the 'lldb' executable and export it here.
717 """
Johnny Chen9707bb62010-06-25 21:14:08 +0000718
Johnny Chen548aefd2010-10-11 22:25:46 +0000719 global rdir
720 global testdirs
Johnny Chen50bc6382011-01-29 01:16:52 +0000721 global dumpSysPath
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000722 global noHeaders
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000723 global svn_info
Enrico Granata814c8132013-04-11 23:48:00 +0000724 global svn_silent
Sean Callanan0acf4c62012-10-24 22:45:39 +0000725 global lldbFrameworkPath
726 global lldbExecutablePath
Johnny Chen548aefd2010-10-11 22:25:46 +0000727
Johnny Chen9707bb62010-06-25 21:14:08 +0000728 # Get the directory containing the current script.
Johnny Chen4d162e52011-08-12 18:54:11 +0000729 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 +0000730 scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
731 else:
732 scriptPath = sys.path[0]
Johnny Chena1affab2010-07-03 03:41:59 +0000733 if not scriptPath.endswith('test'):
Johnny Chen9707bb62010-06-25 21:14:08 +0000734 print "This script expects to reside in lldb's test directory."
735 sys.exit(-1)
736
Johnny Chen548aefd2010-10-11 22:25:46 +0000737 if rdir:
738 # Set up the LLDB_TEST environment variable appropriately, so that the
739 # individual tests can be located relatively.
740 #
741 # See also lldbtest.TestBase.setUpClass(cls).
742 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
743 os.environ["LLDB_TEST"] = os.path.join(rdir, 'test')
744 else:
745 os.environ["LLDB_TEST"] = rdir
746 else:
747 os.environ["LLDB_TEST"] = scriptPath
Peter Collingbournef6c3de82011-06-20 19:06:45 +0000748
749 # Set up the LLDB_SRC environment variable, so that the tests can locate
750 # the LLDB source code.
751 os.environ["LLDB_SRC"] = os.path.join(sys.path[0], os.pardir)
752
Johnny Chen9de4ede2010-08-31 17:42:54 +0000753 pluginPath = os.path.join(scriptPath, 'plugins')
Johnny Chen8a3c0432011-03-11 20:13:06 +0000754 pexpectPath = os.path.join(scriptPath, 'pexpect-2.4')
Johnny Chen58f93922010-06-29 23:10:39 +0000755
Johnny Chen8a3c0432011-03-11 20:13:06 +0000756 # Append script dir, plugin dir, and pexpect dir to the sys.path.
Johnny Chenaf149a02010-09-16 17:11:30 +0000757 sys.path.append(scriptPath)
758 sys.path.append(pluginPath)
Johnny Chen8a3c0432011-03-11 20:13:06 +0000759 sys.path.append(pexpectPath)
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000760
Johnny Chen26901c82011-03-11 19:47:23 +0000761 # This is our base name component.
Johnny Chena1affab2010-07-03 03:41:59 +0000762 base = os.path.abspath(os.path.join(scriptPath, os.pardir))
Johnny Chen6a564a42011-02-15 18:50:19 +0000763
Johnny Chen26901c82011-03-11 19:47:23 +0000764 # These are for xcode build directories.
Johnny Chen6a564a42011-02-15 18:50:19 +0000765 xcode3_build_dir = ['build']
766 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
767 dbg = ['Debug']
Sean Callanand9d94632012-09-26 21:16:15 +0000768 dbc = ['DebugClang']
Johnny Chen6a564a42011-02-15 18:50:19 +0000769 rel = ['Release']
770 bai = ['BuildAndIntegration']
771 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
Johnny Chen26901c82011-03-11 19:47:23 +0000772
773 # Some of the tests can invoke the 'lldb' command directly.
774 # We'll try to locate the appropriate executable right here.
775
Sean Callanan0acf4c62012-10-24 22:45:39 +0000776 lldbExec = None
777 if lldbExecutablePath:
778 if is_exe(lldbExecutablePath):
779 lldbExec = lldbExecutablePath
Sean Callanan502000d2012-11-01 21:23:21 +0000780 lldbHere = lldbExec
Sean Callanan0acf4c62012-10-24 22:45:39 +0000781 else:
782 print lldbExecutablePath + " is not an executable"
783 sys.exit(-1)
Johnny Chen6033bed2011-08-26 00:00:01 +0000784 else:
Sean Callanan0acf4c62012-10-24 22:45:39 +0000785 # First, you can define an environment variable LLDB_EXEC specifying the
786 # full pathname of the lldb executable.
787 if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
788 lldbExec = os.environ["LLDB_EXEC"]
789 else:
790 lldbExec = None
791
792 executable = ['lldb']
793 dbgExec = os.path.join(base, *(xcode3_build_dir + dbg + executable))
794 dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
795 dbcExec = os.path.join(base, *(xcode3_build_dir + dbc + executable))
796 dbcExec2 = os.path.join(base, *(xcode4_build_dir + dbc + executable))
797 relExec = os.path.join(base, *(xcode3_build_dir + rel + executable))
798 relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
799 baiExec = os.path.join(base, *(xcode3_build_dir + bai + executable))
800 baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
801
802 # The 'lldb' executable built here in the source tree.
803 lldbHere = None
804 if is_exe(dbgExec):
805 lldbHere = dbgExec
806 elif is_exe(dbgExec2):
807 lldbHere = dbgExec2
808 elif is_exe(dbcExec):
809 lldbHere = dbcExec
810 elif is_exe(dbcExec2):
811 lldbHere = dbcExec2
812 elif is_exe(relExec):
813 lldbHere = relExec
814 elif is_exe(relExec2):
815 lldbHere = relExec2
816 elif is_exe(baiExec):
817 lldbHere = baiExec
818 elif is_exe(baiExec2):
819 lldbHere = baiExec2
820 elif lldbExec:
821 lldbHere = lldbExec
Sean Callanan502000d2012-11-01 21:23:21 +0000822
Sean Callanan0acf4c62012-10-24 22:45:39 +0000823 # One last chance to locate the 'lldb' executable.
824 if not lldbExec:
825 lldbExec = which('lldb')
826 if lldbHere and not lldbExec:
827 lldbExec = lldbHere
Daniel Malea2777b012013-02-06 16:55:07 +0000828 if lldbExec and not lldbHere:
829 lldbHere = lldbExec
Sean Callanan502000d2012-11-01 21:23:21 +0000830
831 if lldbHere:
832 os.environ["LLDB_HERE"] = lldbHere
Matt Kopeca964b092013-02-20 20:54:10 +0000833 os.environ["LLDB_LIB_DIR"] = os.path.split(lldbHere)[0]
Sean Callanan502000d2012-11-01 21:23:21 +0000834 if not noHeaders:
Matt Kopeca964b092013-02-20 20:54:10 +0000835 print "LLDB library dir:", os.environ["LLDB_LIB_DIR"]
Sean Callanan502000d2012-11-01 21:23:21 +0000836 os.system('%s -v' % lldbHere)
Johnny Chen26901c82011-03-11 19:47:23 +0000837
838 if not lldbExec:
839 print "The 'lldb' executable cannot be located. Some of the tests may not be run as a result."
840 else:
841 os.environ["LLDB_EXEC"] = lldbExec
Johnny Chen8904eb02011-10-28 00:59:00 +0000842 #print "The 'lldb' from PATH env variable", lldbExec
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000843
Daniel Malea2b606ab2013-03-13 20:50:05 +0000844 # Skip printing svn/git information when running in parsable (lit-test compatibility) mode
Enrico Granata814c8132013-04-11 23:48:00 +0000845 if not svn_silent and not parsable:
Daniel Malea2b606ab2013-03-13 20:50:05 +0000846 if os.path.isdir(os.path.join(base, '.svn')) and which("svn") is not None:
847 pipe = subprocess.Popen([which("svn"), "info", base], stdout = subprocess.PIPE)
848 svn_info = pipe.stdout.read()
849 elif os.path.isdir(os.path.join(base, '.git')) and which("git") is not None:
850 pipe = subprocess.Popen([which("git"), "svn", "info", base], stdout = subprocess.PIPE)
851 svn_info = pipe.stdout.read()
852 if not noHeaders:
853 print svn_info
Johnny Chen26901c82011-03-11 19:47:23 +0000854
855 global ignore
856
Johnny Chen9707bb62010-06-25 21:14:08 +0000857 lldbPath = None
Sean Callanan0acf4c62012-10-24 22:45:39 +0000858 if lldbFrameworkPath:
859 candidatePath = os.path.join(lldbFrameworkPath, 'Resources', 'Python')
860 if os.path.isfile(os.path.join(candidatePath, 'lldb/__init__.py')):
861 lldbPath = candidatePath
862 if not lldbPath:
863 print 'Resources/Python/lldb/__init__.py was not found in ' + lldbFrameworkPath
864 sys.exit(-1)
865 else:
866 # The '-i' option is used to skip looking for lldb.py in the build tree.
867 if ignore:
868 return
Jim Inghamaa93c932012-12-21 22:22:26 +0000869
870 # If our lldb supports the -P option, use it to find the python path:
871 init_in_python_dir = 'lldb/__init__.py'
872 import pexpect
873 lldb_dash_p_result = None
874
875 if lldbHere:
876 lldb_dash_p_result = pexpect.run("%s -P"%(lldbHere))
877 elif lldbExec:
878 lldb_dash_p_result = pexpect.run("%s -P"%(lldbExec))
879
880 if lldb_dash_p_result and not lldb_dash_p_result.startswith(("<", "lldb: invalid option:")):
881 lines = lldb_dash_p_result.splitlines()
882 if len(lines) == 1 and os.path.isfile(os.path.join(lines[0], init_in_python_dir)):
883 lldbPath = lines[0]
Daniel Malea21e32a62013-01-04 23:35:13 +0000884 if "linux" in sys.platform:
Matt Kopeca964b092013-02-20 20:54:10 +0000885 os.environ['LLDB_LIB_DIR'] = os.path.join(lldbPath, '..', '..')
Jim Inghamaa93c932012-12-21 22:22:26 +0000886
887 if not lldbPath:
888 dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
889 dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
890 dbcPath = os.path.join(base, *(xcode3_build_dir + dbc + python_resource_dir))
891 dbcPath2 = os.path.join(base, *(xcode4_build_dir + dbc + python_resource_dir))
892 relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
893 relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
894 baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
895 baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
Sean Callanan0acf4c62012-10-24 22:45:39 +0000896
Jim Inghamaa93c932012-12-21 22:22:26 +0000897 if os.path.isfile(os.path.join(dbgPath, init_in_python_dir)):
898 lldbPath = dbgPath
899 elif os.path.isfile(os.path.join(dbgPath2, init_in_python_dir)):
900 lldbPath = dbgPath2
901 elif os.path.isfile(os.path.join(dbcPath, init_in_python_dir)):
902 lldbPath = dbcPath
903 elif os.path.isfile(os.path.join(dbcPath2, init_in_python_dir)):
904 lldbPath = dbcPath2
905 elif os.path.isfile(os.path.join(relPath, init_in_python_dir)):
906 lldbPath = relPath
907 elif os.path.isfile(os.path.join(relPath2, init_in_python_dir)):
908 lldbPath = relPath2
909 elif os.path.isfile(os.path.join(baiPath, init_in_python_dir)):
910 lldbPath = baiPath
911 elif os.path.isfile(os.path.join(baiPath2, init_in_python_dir)):
912 lldbPath = baiPath2
913
Sean Callanan0acf4c62012-10-24 22:45:39 +0000914 if not lldbPath:
915 print 'This script requires lldb.py to be in either ' + dbgPath + ',',
916 print relPath + ', or ' + baiPath
917 sys.exit(-1)
Johnny Chen9707bb62010-06-25 21:14:08 +0000918
Jim Inghamaa93c932012-12-21 22:22:26 +0000919 # Some of the code that uses this path assumes it hasn't resolved the Versions... link.
920 # If the path we've constructed looks like that, then we'll strip out the Versions/A part.
921 (before, frameWithVersion, after) = lldbPath.rpartition("LLDB.framework/Versions/A")
922 if frameWithVersion != "" :
923 lldbPath = before + "LLDB.framework" + after
924
Enrico Granata0ad92972013-04-11 23:40:59 +0000925 lldbPath = os.path.abspath(lldbPath)
926
Enrico Granata01458ca2012-10-23 00:09:02 +0000927 # If tests need to find LLDB_FRAMEWORK, now they can do it
928 os.environ["LLDB_FRAMEWORK"] = os.path.dirname(os.path.dirname(lldbPath))
929
Johnny Chenaf149a02010-09-16 17:11:30 +0000930 # This is to locate the lldb.py module. Insert it right after sys.path[0].
931 sys.path[1:1] = [lldbPath]
Johnny Chen50bc6382011-01-29 01:16:52 +0000932 if dumpSysPath:
933 print "sys.path:", sys.path
Johnny Chen9707bb62010-06-25 21:14:08 +0000934
Johnny Chen9707bb62010-06-25 21:14:08 +0000935
Johnny Chencd0279d2010-09-20 18:07:50 +0000936def doDelay(delta):
937 """Delaying startup for delta-seconds to facilitate debugger attachment."""
938 def alarm_handler(*args):
939 raise Exception("timeout")
940
941 signal.signal(signal.SIGALRM, alarm_handler)
942 signal.alarm(delta)
943 sys.stdout.write("pid=%d\n" % os.getpid())
944 sys.stdout.write("Enter RET to proceed (or timeout after %d seconds):" %
945 delta)
946 sys.stdout.flush()
947 try:
948 text = sys.stdin.readline()
949 except:
950 text = ""
951 signal.alarm(0)
952 sys.stdout.write("proceeding...\n")
953 pass
954
955
Johnny Chen9707bb62010-06-25 21:14:08 +0000956def visit(prefix, dir, names):
957 """Visitor function for os.path.walk(path, visit, arg)."""
958
959 global suite
Johnny Chen7c52ff12010-09-27 23:29:54 +0000960 global regexp
Johnny Chenc5fa0052011-07-29 22:54:56 +0000961 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000962 global fs4all
Johnny Chene9eae812012-01-18 05:15:00 +0000963 global excluded
964
965 if set(dir.split(os.sep)).intersection(excluded):
966 #print "Detected an excluded dir component: %s" % dir
967 return
Johnny Chen9707bb62010-06-25 21:14:08 +0000968
969 for name in names:
970 if os.path.isdir(os.path.join(dir, name)):
971 continue
972
973 if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
Johnny Chen7c52ff12010-09-27 23:29:54 +0000974 # Try to match the regexp pattern, if specified.
975 if regexp:
976 import re
977 if re.search(regexp, name):
978 #print "Filename: '%s' matches pattern: '%s'" % (name, regexp)
979 pass
980 else:
981 #print "Filename: '%s' does not match pattern: '%s'" % (name, regexp)
982 continue
983
Johnny Chen953864a2010-10-12 21:35:54 +0000984 # We found a match for our test. Add it to the suite.
Johnny Chen79723352010-10-12 15:53:22 +0000985
986 # Update the sys.path first.
Johnny Chena85d7ee2010-06-26 00:19:32 +0000987 if not sys.path.count(dir):
Johnny Chen548aefd2010-10-11 22:25:46 +0000988 sys.path.insert(0, dir)
Johnny Chen9707bb62010-06-25 21:14:08 +0000989 base = os.path.splitext(name)[0]
Johnny Chenb62436b2010-10-06 20:40:56 +0000990
991 # Thoroughly check the filterspec against the base module and admit
992 # the (base, filterspec) combination only when it makes sense.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000993 filterspec = None
994 for filterspec in filters:
Johnny Chenb62436b2010-10-06 20:40:56 +0000995 # Optimistically set the flag to True.
996 filtered = True
997 module = __import__(base)
998 parts = filterspec.split('.')
999 obj = module
1000 for part in parts:
1001 try:
1002 parent, obj = obj, getattr(obj, part)
1003 except AttributeError:
1004 # The filterspec has failed.
1005 filtered = False
1006 break
Johnny Chenc5fa0052011-07-29 22:54:56 +00001007
Johnny Chendb4be602011-08-12 23:55:07 +00001008 # If filtered, we have a good filterspec. Add it.
Johnny Chenc5fa0052011-07-29 22:54:56 +00001009 if filtered:
Johnny Chendb4be602011-08-12 23:55:07 +00001010 #print "adding filter spec %s to module %s" % (filterspec, module)
1011 suite.addTests(
1012 unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
1013 continue
Johnny Chenc5fa0052011-07-29 22:54:56 +00001014
1015 # Forgo this module if the (base, filterspec) combo is invalid
1016 # and no '-g' option is specified
1017 if filters and fs4all and not filtered:
1018 continue
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001019
Johnny Chendb4be602011-08-12 23:55:07 +00001020 # Add either the filtered test case(s) (which is done before) or the entire test class.
1021 if not filterspec or not filtered:
Johnny Chenb62436b2010-10-06 20:40:56 +00001022 # A simple case of just the module name. Also the failover case
1023 # from the filterspec branch when the (base, filterspec) combo
1024 # doesn't make sense.
1025 suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
Johnny Chen9707bb62010-06-25 21:14:08 +00001026
1027
Johnny Chencd0279d2010-09-20 18:07:50 +00001028def lldbLoggings():
1029 """Check and do lldb loggings if necessary."""
1030
1031 # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
1032 # defined. Use ${LLDB_LOG} to specify the log file.
1033 ci = lldb.DBG.GetCommandInterpreter()
1034 res = lldb.SBCommandReturnObject()
1035 if ("LLDB_LOG" in os.environ):
1036 if ("LLDB_LOG_OPTION" in os.environ):
1037 lldb_log_option = os.environ["LLDB_LOG_OPTION"]
1038 else:
Johnny Chen8fd886c2010-12-08 01:25:21 +00001039 lldb_log_option = "event process expr state api"
Johnny Chencd0279d2010-09-20 18:07:50 +00001040 ci.HandleCommand(
Greg Clayton940b1032011-02-23 00:35:02 +00001041 "log enable -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option,
Johnny Chencd0279d2010-09-20 18:07:50 +00001042 res)
1043 if not res.Succeeded():
1044 raise Exception('log enable failed (check LLDB_LOG env variable.')
1045 # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
1046 # Use ${GDB_REMOTE_LOG} to specify the log file.
1047 if ("GDB_REMOTE_LOG" in os.environ):
1048 if ("GDB_REMOTE_LOG_OPTION" in os.environ):
1049 gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
1050 else:
Johnny Chen7ab8c852010-12-02 18:35:13 +00001051 gdb_remote_log_option = "packets process"
Johnny Chencd0279d2010-09-20 18:07:50 +00001052 ci.HandleCommand(
Johnny Chenc935a892011-06-21 19:25:45 +00001053 "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
Johnny Chencd0279d2010-09-20 18:07:50 +00001054 + gdb_remote_log_option,
1055 res)
1056 if not res.Succeeded():
1057 raise Exception('log enable failed (check GDB_REMOTE_LOG env variable.')
1058
Johnny Chen067022b2011-01-19 19:31:46 +00001059def getMyCommandLine():
Johnny Chen067022b2011-01-19 19:31:46 +00001060 ps = subprocess.Popen(['ps', '-o', "command=CMD", str(os.getpid())], stdout=subprocess.PIPE).communicate()[0]
1061 lines = ps.split('\n')
1062 cmd_line = lines[1]
1063 return cmd_line
Johnny Chencd0279d2010-09-20 18:07:50 +00001064
Johnny Chend96b5682010-11-05 17:30:53 +00001065# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +00001066# #
1067# Execution of the test driver starts here #
1068# #
Johnny Chend96b5682010-11-05 17:30:53 +00001069# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +00001070
Johnny Chen2891bb02011-09-16 01:04:26 +00001071def checkDsymForUUIDIsNotOn():
Johnny Chen6a4e0872011-09-16 17:50:44 +00001072 cmd = ["defaults", "read", "com.apple.DebugSymbols"]
1073 pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1074 cmd_output = pipe.stdout.read()
Johnny Chen178c8d92011-09-16 18:03:19 +00001075 if cmd_output and "DBGFileMappedPaths = " in cmd_output:
Johnny Chen6a451482011-09-16 18:09:45 +00001076 print "%s =>" % ' '.join(cmd)
Johnny Chen6a4e0872011-09-16 17:50:44 +00001077 print cmd_output
Johnny Chen2891bb02011-09-16 01:04:26 +00001078 print "Disable automatic lookup and caching of dSYMs before running the test suite!"
1079 print "Exiting..."
1080 sys.exit(0)
1081
1082# On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
1083# does not exist before proceeding to running the test suite.
1084if sys.platform.startswith("darwin"):
1085 checkDsymForUUIDIsNotOn()
1086
Johnny Chen9707bb62010-06-25 21:14:08 +00001087#
Johnny Chenaf149a02010-09-16 17:11:30 +00001088# Start the actions by first parsing the options while setting up the test
1089# directories, followed by setting up the search paths for lldb utilities;
1090# then, we walk the directory trees and collect the tests into our test suite.
Johnny Chen9707bb62010-06-25 21:14:08 +00001091#
Johnny Chenaf149a02010-09-16 17:11:30 +00001092parseOptionsAndInitTestdirs()
Johnny Chen9707bb62010-06-25 21:14:08 +00001093setupSysPath()
Johnny Chen91960d32010-09-08 20:56:16 +00001094
1095#
1096# If '-d' is specified, do a delay of 10 seconds for the debugger to attach.
1097#
1098if delay:
Johnny Chencd0279d2010-09-20 18:07:50 +00001099 doDelay(10)
Johnny Chen91960d32010-09-08 20:56:16 +00001100
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001101#
Johnny Chen41998192010-10-01 22:59:49 +00001102# If '-l' is specified, do not skip the long running tests.
Johnny Chen028d8eb2011-11-17 19:57:27 +00001103if not skip_long_running_test:
Johnny Chen41998192010-10-01 22:59:49 +00001104 os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
1105
1106#
Johnny Chen79723352010-10-12 15:53:22 +00001107# Walk through the testdirs while collecting tests.
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001108#
Johnny Chen9707bb62010-06-25 21:14:08 +00001109for testdir in testdirs:
1110 os.path.walk(testdir, visit, 'Test')
1111
Johnny Chenb40056b2010-09-21 00:09:27 +00001112#
Johnny Chen9707bb62010-06-25 21:14:08 +00001113# Now that we have loaded all the test cases, run the whole test suite.
Johnny Chenb40056b2010-09-21 00:09:27 +00001114#
Johnny Chencd0279d2010-09-20 18:07:50 +00001115
Johnny Chen1bfbd412010-06-29 19:44:16 +00001116# For the time being, let's bracket the test runner within the
1117# lldb.SBDebugger.Initialize()/Terminate() pair.
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001118import lldb, atexit
Johnny Chen6b6f5ba2010-10-14 16:36:49 +00001119# Update: the act of importing lldb now executes lldb.SBDebugger.Initialize(),
1120# there's no need to call it a second time.
1121#lldb.SBDebugger.Initialize()
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001122atexit.register(lambda: lldb.SBDebugger.Terminate())
Johnny Chen1bfbd412010-06-29 19:44:16 +00001123
Johnny Chen909e5a62010-07-01 22:52:57 +00001124# Create a singleton SBDebugger in the lldb namespace.
1125lldb.DBG = lldb.SBDebugger.Create()
1126
Johnny Chen4f93bf12010-12-10 00:51:23 +00001127# Put the blacklist in the lldb namespace, to be used by lldb.TestBase.
Johnny Chen82e6b1e2010-12-01 22:47:54 +00001128lldb.blacklist = blacklist
1129
Johnny Chenac97a6b2012-04-16 18:55:15 +00001130# The pre_flight and post_flight come from reading a config file.
1131lldb.pre_flight = pre_flight
1132lldb.post_flight = post_flight
1133def getsource_if_available(obj):
1134 """
1135 Return the text of the source code for an object if available. Otherwise,
1136 a print representation is returned.
1137 """
1138 import inspect
1139 try:
1140 return inspect.getsource(obj)
1141 except:
1142 return repr(obj)
1143
Daniel Malea361eb432013-02-15 21:31:37 +00001144if not noHeaders:
1145 print "lldb.pre_flight:", getsource_if_available(lldb.pre_flight)
1146 print "lldb.post_flight:", getsource_if_available(lldb.post_flight)
Johnny Chenac97a6b2012-04-16 18:55:15 +00001147
Johnny Chena3ed7d82012-04-06 00:56:05 +00001148# Put all these test decorators in the lldb namespace.
Johnny Chen4f93bf12010-12-10 00:51:23 +00001149lldb.dont_do_python_api_test = dont_do_python_api_test
1150lldb.just_do_python_api_test = just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +00001151lldb.just_do_benchmarks_test = just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +00001152lldb.dont_do_dsym_test = dont_do_dsym_test
1153lldb.dont_do_dwarf_test = dont_do_dwarf_test
Johnny Chen4f93bf12010-12-10 00:51:23 +00001154
Johnny Chen028d8eb2011-11-17 19:57:27 +00001155# Do we need to skip build and cleanup?
1156lldb.skip_build_and_cleanup = skip_build_and_cleanup
1157
Johnny Chen5f2ed172011-10-20 18:43:28 +00001158# Put bmExecutable, bmBreakpointSpec, and bmIterationCount into the lldb namespace, too.
Johnny Chene00c9302011-10-10 22:03:44 +00001159lldb.bmExecutable = bmExecutable
1160lldb.bmBreakpointSpec = bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +00001161lldb.bmIterationCount = bmIterationCount
Johnny Chene00c9302011-10-10 22:03:44 +00001162
Johnny Chen38f823c2011-10-11 01:30:27 +00001163# And don't forget the runHooks!
1164lldb.runHooks = runHooks
1165
Johnny Chencd0279d2010-09-20 18:07:50 +00001166# Turn on lldb loggings if necessary.
1167lldbLoggings()
Johnny Chen909e5a62010-07-01 22:52:57 +00001168
Johnny Chen7987ac92010-08-09 20:40:52 +00001169# Install the control-c handler.
1170unittest2.signals.installHandler()
1171
Johnny Chen125fc2b2010-10-21 16:55:35 +00001172# If sdir_name is not specified through the '-s sdir_name' option, get a
1173# timestamp string and export it as LLDB_SESSION_DIR environment var. This will
1174# be used when/if we want to dump the session info of individual test cases
1175# later on.
Johnny Chence681462010-10-19 00:25:01 +00001176#
1177# See also TestBase.dumpSessionInfo() in lldbtest.py.
Johnny Chena73ad662012-08-16 19:15:21 +00001178import datetime
1179# The windows platforms don't like ':' in the pathname.
1180timestamp_started = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
Johnny Chen125fc2b2010-10-21 16:55:35 +00001181if not sdir_name:
Johnny Chena73ad662012-08-16 19:15:21 +00001182 sdir_name = timestamp_started
Peter Collingbourne132476f2011-06-20 23:55:53 +00001183os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), sdir_name)
Johnny Chen067022b2011-01-19 19:31:46 +00001184
Johnny Chenfe5f1ed2011-10-21 18:33:27 +00001185if not noHeaders:
1186 sys.stderr.write("\nSession logs for test failures/errors/unexpected successes"
1187 " will go into directory '%s'\n" % sdir_name)
1188 sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
Johnny Chence681462010-10-19 00:25:01 +00001189
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001190if not os.path.isdir(sdir_name):
1191 os.mkdir(sdir_name)
Johnny Chena73ad662012-08-16 19:15:21 +00001192fname = os.path.join(sdir_name, "TestStarted")
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001193with open(fname, "w") as f:
Johnny Chena73ad662012-08-16 19:15:21 +00001194 print >> f, "Test started at: %s\n" % timestamp_started
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001195 print >> f, svn_info
1196 print >> f, "Command invoked: %s\n" % getMyCommandLine()
1197
Johnny Chenb40056b2010-09-21 00:09:27 +00001198#
1199# Invoke the default TextTestRunner to run the test suite, possibly iterating
1200# over different configurations.
1201#
1202
Johnny Chenb40056b2010-09-21 00:09:27 +00001203iterArchs = False
Johnny Chenf032d902010-09-21 00:16:09 +00001204iterCompilers = False
Johnny Chenb40056b2010-09-21 00:09:27 +00001205
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001206if not archs and "archs" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001207 archs = config["archs"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001208
1209if isinstance(archs, list) and len(archs) >= 1:
1210 iterArchs = True
1211
1212if not compilers and "compilers" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001213 compilers = config["compilers"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001214
Johnny Chen92693b52012-03-09 02:11:37 +00001215#
1216# Add some intervention here to sanity check that the compilers requested are sane.
1217# If found not to be an executable program, the invalid one is dropped from the list.
1218for i in range(len(compilers)):
1219 c = compilers[i]
1220 if which(c):
1221 continue
1222 else:
1223 if sys.platform.startswith("darwin"):
1224 pipe = subprocess.Popen(['xcrun', '-find', c], stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1225 cmd_output = pipe.stdout.read()
1226 if cmd_output:
1227 if "not found" in cmd_output:
1228 print "dropping %s from the compilers used" % c
1229 compilers.remove(i)
1230 else:
1231 compilers[i] = cmd_output.split('\n')[0]
1232 print "'xcrun -find %s' returning %s" % (c, compilers[i])
1233
Daniel Malea361eb432013-02-15 21:31:37 +00001234if not parsable:
1235 print "compilers=%s" % str(compilers)
Johnny Chen92693b52012-03-09 02:11:37 +00001236
1237if not compilers or len(compilers) == 0:
1238 print "No eligible compiler found, exiting."
1239 sys.exit(1)
1240
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001241if isinstance(compilers, list) and len(compilers) >= 1:
1242 iterCompilers = True
Johnny Chenb40056b2010-09-21 00:09:27 +00001243
Johnny Chen953864a2010-10-12 21:35:54 +00001244# Make a shallow copy of sys.path, we need to manipulate the search paths later.
1245# This is only necessary if we are relocated and with different configurations.
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001246if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001247 old_sys_path = sys.path[:]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001248# If we iterate on archs or compilers, there is a chance we want to split stderr/stdout.
1249if iterArchs or iterCompilers:
Johnny Chen953864a2010-10-12 21:35:54 +00001250 old_stderr = sys.stderr
1251 old_stdout = sys.stdout
1252 new_stderr = None
1253 new_stdout = None
1254
Johnny Chend96b5682010-11-05 17:30:53 +00001255# Iterating over all possible architecture and compiler combinations.
Johnny Chenb40056b2010-09-21 00:09:27 +00001256for ia in range(len(archs) if iterArchs else 1):
1257 archConfig = ""
1258 if iterArchs:
Johnny Chen18a921f2010-09-30 17:11:58 +00001259 os.environ["ARCH"] = archs[ia]
Johnny Chenb40056b2010-09-21 00:09:27 +00001260 archConfig = "arch=%s" % archs[ia]
1261 for ic in range(len(compilers) if iterCompilers else 1):
1262 if iterCompilers:
Johnny Chen18a921f2010-09-30 17:11:58 +00001263 os.environ["CC"] = compilers[ic]
Johnny Chenb40056b2010-09-21 00:09:27 +00001264 configString = "%s compiler=%s" % (archConfig, compilers[ic])
1265 else:
1266 configString = archConfig
1267
Johnny Chenb40056b2010-09-21 00:09:27 +00001268 if iterArchs or iterCompilers:
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001269 # Translate ' ' to '-' for pathname component.
1270 from string import maketrans
1271 tbl = maketrans(' ', '-')
1272 configPostfix = configString.translate(tbl)
1273
1274 # Check whether we need to split stderr/stdout into configuration
1275 # specific files.
1276 if old_stderr.name != '<stderr>' and config.get('split_stderr'):
1277 if new_stderr:
1278 new_stderr.close()
1279 new_stderr = open("%s.%s" % (old_stderr.name, configPostfix), "w")
1280 sys.stderr = new_stderr
1281 if old_stdout.name != '<stdout>' and config.get('split_stdout'):
1282 if new_stdout:
1283 new_stdout.close()
1284 new_stdout = open("%s.%s" % (old_stdout.name, configPostfix), "w")
1285 sys.stdout = new_stdout
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001286
Johnny Chen953864a2010-10-12 21:35:54 +00001287 # If we specified a relocated directory to run the test suite, do
1288 # the extra housekeeping to copy the testdirs to a configStringified
1289 # directory and to update sys.path before invoking the test runner.
1290 # The purpose is to separate the configuration-specific directories
1291 # from each other.
1292 if rdir:
Johnny Chen3bc7e5e2012-04-24 21:44:10 +00001293 from shutil import copytree, rmtree, ignore_patterns
Johnny Chen953864a2010-10-12 21:35:54 +00001294
Johnny Chen953864a2010-10-12 21:35:54 +00001295 newrdir = "%s.%s" % (rdir, configPostfix)
1296
1297 # Copy the tree to a new directory with postfix name configPostfix.
Johnny Chen3bc7e5e2012-04-24 21:44:10 +00001298 if os.path.exists(newrdir):
1299 rmtree(newrdir)
Johnny Chen953864a2010-10-12 21:35:54 +00001300 copytree(rdir, newrdir, ignore=ignore_patterns('*.pyc', '*.o', '*.d'))
1301
Filipe Cabecinhas0e1d06d2012-08-08 15:23:24 +00001302 # Update the LLDB_TEST environment variable to reflect new top
Johnny Chen953864a2010-10-12 21:35:54 +00001303 # level test directory.
1304 #
1305 # See also lldbtest.TestBase.setUpClass(cls).
1306 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
1307 os.environ["LLDB_TEST"] = os.path.join(newrdir, 'test')
1308 else:
1309 os.environ["LLDB_TEST"] = newrdir
1310
1311 # And update the Python search paths for modules.
1312 sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
1313
1314 # Output the configuration.
Daniel Malea361eb432013-02-15 21:31:37 +00001315 if not parsable:
1316 sys.stderr.write("\nConfiguration: " + configString + "\n")
Johnny Chen953864a2010-10-12 21:35:54 +00001317
1318 #print "sys.stderr name is", sys.stderr.name
1319 #print "sys.stdout name is", sys.stdout.name
1320
1321 # First, write out the number of collected test cases.
Daniel Malea361eb432013-02-15 21:31:37 +00001322 if not parsable:
1323 sys.stderr.write(separator + "\n")
1324 sys.stderr.write("Collected %d test%s\n\n"
1325 % (suite.countTestCases(),
1326 suite.countTestCases() != 1 and "s" or ""))
Johnny Chen953864a2010-10-12 21:35:54 +00001327
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001328 class LLDBTestResult(unittest2.TextTestResult):
1329 """
Johnny Chen26be4532010-11-09 23:56:14 +00001330 Enforce a singleton pattern to allow introspection of test progress.
1331
1332 Overwrite addError(), addFailure(), and addExpectedFailure() methods
1333 to enable each test instance to track its failure/error status. It
1334 is used in the LLDB test framework to emit detailed trace messages
1335 to a log file for easier human inspection of test failres/errors.
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001336 """
1337 __singleton__ = None
Johnny Chen360dd372010-11-29 17:50:10 +00001338 __ignore_singleton__ = False
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001339
Enrico Granatabc0c5a62013-02-08 23:39:18 +00001340 @staticmethod
1341 def getTerminalSize():
1342 import os
1343 env = os.environ
1344 def ioctl_GWINSZ(fd):
1345 try:
1346 import fcntl, termios, struct, os
1347 cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
1348 '1234'))
1349 except:
1350 return
1351 return cr
1352 cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
1353 if not cr:
1354 try:
1355 fd = os.open(os.ctermid(), os.O_RDONLY)
1356 cr = ioctl_GWINSZ(fd)
1357 os.close(fd)
1358 except:
1359 pass
1360 if not cr:
1361 cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
1362 return int(cr[1]), int(cr[0])
1363
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001364 def __init__(self, *args):
Johnny Chen360dd372010-11-29 17:50:10 +00001365 if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
Johnny Chend2acdb32010-11-16 22:42:58 +00001366 raise Exception("LLDBTestResult instantiated more than once")
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001367 super(LLDBTestResult, self).__init__(*args)
1368 LLDBTestResult.__singleton__ = self
1369 # Now put this singleton into the lldb module namespace.
1370 lldb.test_result = self
Johnny Chen810042e2011-01-05 20:24:11 +00001371 # Computes the format string for displaying the counter.
1372 global suite
1373 counterWidth = len(str(suite.countTestCases()))
1374 self.fmt = "%" + str(counterWidth) + "d: "
Johnny Chenc87fd492011-01-05 22:50:11 +00001375 self.indentation = ' ' * (counterWidth + 2)
Johnny Chen810042e2011-01-05 20:24:11 +00001376 # This counts from 1 .. suite.countTestCases().
1377 self.counter = 0
Enrico Granatabc0c5a62013-02-08 23:39:18 +00001378 (width, height) = LLDBTestResult.getTerminalSize()
Enrico Granata77215892013-02-15 00:32:05 +00001379 self.progressbar = None
Jim Ingham75f260a2013-02-19 20:39:27 +00001380 global progress_bar
Daniel Malea361eb432013-02-15 21:31:37 +00001381 if width > 10 and not parsable and progress_bar:
Enrico Granata77215892013-02-15 00:32:05 +00001382 try:
1383 self.progressbar = progress.ProgressWithEvents(stdout=self.stream,start=0,end=suite.countTestCases(),width=width-10)
1384 except:
1385 self.progressbar = None
Johnny Chen810042e2011-01-05 20:24:11 +00001386
Daniel Malea361eb432013-02-15 21:31:37 +00001387 def _config_string(self, test):
1388 compiler = getattr(test, "getCompiler", None)
1389 arch = getattr(test, "getArchitecture", None)
1390 return "%s-%s" % (compiler() if compiler else "", arch() if arch else "")
1391
Johnny Chenbe452272012-04-19 21:33:55 +00001392 def _exc_info_to_string(self, err, test):
1393 """Overrides superclass TestResult's method in order to append
1394 our test config info string to the exception info string."""
1395 modified_exc_string = '%sConfig=%s-%s' % (super(LLDBTestResult, self)._exc_info_to_string(err, test),
1396 test.getArchitecture(),
1397 test.getCompiler())
1398 return modified_exc_string
1399
Johnny Chenc87fd492011-01-05 22:50:11 +00001400 def getDescription(self, test):
1401 doc_first_line = test.shortDescription()
1402 if self.descriptions and doc_first_line:
1403 return '\n'.join((str(test), self.indentation + doc_first_line))
1404 else:
1405 return str(test)
1406
Enrico Granataac3a8e22012-09-21 19:10:53 +00001407 def getCategoriesForTest(self,test):
Enrico Granata56e2c562013-02-27 02:37:12 +00001408 if hasattr(test,"_testMethodName"):
1409 test_method = getattr(test,"_testMethodName")
1410 test_method = getattr(test,test_method)
1411 else:
1412 test_method = None
1413 if test_method != None and hasattr(test_method,"getCategories"):
1414 test_categories = test_method.getCategories(test)
1415 elif hasattr(test,"getCategories"):
Enrico Granataac3a8e22012-09-21 19:10:53 +00001416 test_categories = test.getCategories()
1417 elif inspect.ismethod(test) and test.__self__ != None and hasattr(test.__self__,"getCategories"):
1418 test_categories = test.__self__.getCategories()
1419 else:
1420 test_categories = []
1421 if test_categories == None:
1422 test_categories = []
1423 return test_categories
1424
1425 def shouldSkipBecauseOfCategories(self,test):
1426 global useCategories
1427 import inspect
1428 if useCategories:
1429 global categoriesList
1430 test_categories = self.getCategoriesForTest(test)
1431 if len(test_categories) == 0 or len(categoriesList & set(test_categories)) == 0:
1432 return True
1433 return False
1434
1435 def hardMarkAsSkipped(self,test):
1436 getattr(test, test._testMethodName).__func__.__unittest_skip__ = True
1437 getattr(test, test._testMethodName).__func__.__unittest_skip_why__ = "test case does not fall in any category of interest for this run"
1438
Johnny Chen810042e2011-01-05 20:24:11 +00001439 def startTest(self, test):
Enrico Granataac3a8e22012-09-21 19:10:53 +00001440 if self.shouldSkipBecauseOfCategories(test):
1441 self.hardMarkAsSkipped(test)
Johnny Chen810042e2011-01-05 20:24:11 +00001442 self.counter += 1
1443 if self.showAll:
1444 self.stream.write(self.fmt % self.counter)
1445 super(LLDBTestResult, self).startTest(test)
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001446
Daniel Malea361eb432013-02-15 21:31:37 +00001447 def addSuccess(self, test):
1448 global parsable
1449 super(LLDBTestResult, self).addSuccess(test)
1450 if parsable:
1451 self.stream.write("PASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1452
Johnny Chence681462010-10-19 00:25:01 +00001453 def addError(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001454 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001455 global parsable
Johnny Chen63c2cba2010-10-29 22:20:36 +00001456 sdir_has_content = True
Johnny Chence681462010-10-19 00:25:01 +00001457 super(LLDBTestResult, self).addError(test, err)
1458 method = getattr(test, "markError", None)
1459 if method:
1460 method()
Daniel Malea361eb432013-02-15 21:31:37 +00001461 if parsable:
Daniel Maleae1dd3e52013-03-07 18:39:26 +00001462 self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
Johnny Chence681462010-10-19 00:25:01 +00001463
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001464 def addFailure(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001465 global sdir_has_content
Enrico Granataac3a8e22012-09-21 19:10:53 +00001466 global failuresPerCategory
Daniel Malea361eb432013-02-15 21:31:37 +00001467 global parsable
Johnny Chen63c2cba2010-10-29 22:20:36 +00001468 sdir_has_content = True
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001469 super(LLDBTestResult, self).addFailure(test, err)
1470 method = getattr(test, "markFailure", None)
1471 if method:
1472 method()
Daniel Malea361eb432013-02-15 21:31:37 +00001473 if parsable:
1474 self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
Enrico Granataac3a8e22012-09-21 19:10:53 +00001475 if useCategories:
1476 test_categories = self.getCategoriesForTest(test)
1477 for category in test_categories:
1478 if category in failuresPerCategory:
1479 failuresPerCategory[category] = failuresPerCategory[category] + 1
1480 else:
1481 failuresPerCategory[category] = 1
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001482
Enrico Granata21416a12013-02-23 01:05:23 +00001483 def addExpectedFailure(self, test, err, bugnumber):
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001484 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001485 global parsable
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001486 sdir_has_content = True
Enrico Granata21416a12013-02-23 01:05:23 +00001487 super(LLDBTestResult, self).addExpectedFailure(test, err, bugnumber)
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001488 method = getattr(test, "markExpectedFailure", None)
1489 if method:
Enrico Granata21416a12013-02-23 01:05:23 +00001490 method(err, bugnumber)
Daniel Malea361eb432013-02-15 21:31:37 +00001491 if parsable:
1492 self.stream.write("XFAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001493
Johnny Chenf5b89092011-08-15 23:09:08 +00001494 def addSkip(self, test, reason):
1495 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001496 global parsable
Johnny Chenf5b89092011-08-15 23:09:08 +00001497 sdir_has_content = True
1498 super(LLDBTestResult, self).addSkip(test, reason)
1499 method = getattr(test, "markSkippedTest", None)
1500 if method:
1501 method()
Daniel Malea361eb432013-02-15 21:31:37 +00001502 if parsable:
1503 self.stream.write("UNSUPPORTED: LLDB (%s) :: %s (%s) \n" % (self._config_string(test), str(test), reason))
Johnny Chenf5b89092011-08-15 23:09:08 +00001504
Enrico Granata21416a12013-02-23 01:05:23 +00001505 def addUnexpectedSuccess(self, test, bugnumber):
Johnny Chenab2f0662011-05-06 20:30:22 +00001506 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001507 global parsable
Johnny Chenab2f0662011-05-06 20:30:22 +00001508 sdir_has_content = True
Enrico Granata21416a12013-02-23 01:05:23 +00001509 super(LLDBTestResult, self).addUnexpectedSuccess(test, bugnumber)
Johnny Chenab2f0662011-05-06 20:30:22 +00001510 method = getattr(test, "markUnexpectedSuccess", None)
1511 if method:
Enrico Granata21416a12013-02-23 01:05:23 +00001512 method(bugnumber)
Daniel Malea361eb432013-02-15 21:31:37 +00001513 if parsable:
1514 self.stream.write("XPASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1515
1516 if parsable:
1517 v = 0
1518 elif progress_bar:
1519 v = 1
1520 else:
1521 v = verbose
Johnny Chenab2f0662011-05-06 20:30:22 +00001522
Johnny Chen26be4532010-11-09 23:56:14 +00001523 # Invoke the test runner.
Johnny Chend2acdb32010-11-16 22:42:58 +00001524 if count == 1:
Johnny Chen7d6d8442010-12-03 19:59:35 +00001525 result = unittest2.TextTestRunner(stream=sys.stderr,
Daniel Malea361eb432013-02-15 21:31:37 +00001526 verbosity=v,
Johnny Chen7d6d8442010-12-03 19:59:35 +00001527 failfast=failfast,
Johnny Chend2acdb32010-11-16 22:42:58 +00001528 resultclass=LLDBTestResult).run(suite)
1529 else:
Johnny Chend6e7ca22010-11-29 17:52:43 +00001530 # We are invoking the same test suite more than once. In this case,
1531 # mark __ignore_singleton__ flag as True so the signleton pattern is
1532 # not enforced.
Johnny Chen360dd372010-11-29 17:50:10 +00001533 LLDBTestResult.__ignore_singleton__ = True
Johnny Chend2acdb32010-11-16 22:42:58 +00001534 for i in range(count):
Daniel Malea361eb432013-02-15 21:31:37 +00001535
Johnny Chen7d6d8442010-12-03 19:59:35 +00001536 result = unittest2.TextTestRunner(stream=sys.stderr,
Daniel Malea361eb432013-02-15 21:31:37 +00001537 verbosity=v,
Johnny Chen7d6d8442010-12-03 19:59:35 +00001538 failfast=failfast,
Johnny Chen360dd372010-11-29 17:50:10 +00001539 resultclass=LLDBTestResult).run(suite)
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001540
Daniel Malea24765572013-02-20 20:12:11 +00001541 failed = failed or not result.wasSuccessful()
Johnny Chen1bfbd412010-06-29 19:44:16 +00001542
Daniel Malea361eb432013-02-15 21:31:37 +00001543if sdir_has_content and not parsable:
Johnny Chenab2f0662011-05-06 20:30:22 +00001544 sys.stderr.write("Session logs for test failures/errors/unexpected successes"
1545 " can be found in directory '%s'\n" % sdir_name)
Johnny Chen63c2cba2010-10-29 22:20:36 +00001546
Enrico Granataac3a8e22012-09-21 19:10:53 +00001547if useCategories and len(failuresPerCategory) > 0:
1548 sys.stderr.write("Failures per category:\n")
1549 for category in failuresPerCategory:
1550 sys.stderr.write("%s - %d\n" % (category,failuresPerCategory[category]))
1551
Johnny Chena73ad662012-08-16 19:15:21 +00001552fname = os.path.join(sdir_name, "TestFinished")
1553with open(fname, "w") as f:
1554 print >> f, "Test finished at: %s\n" % datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
1555
Johnny Chencd0279d2010-09-20 18:07:50 +00001556# Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1557# This should not be necessary now.
Johnny Chen83f6e512010-08-13 22:58:44 +00001558if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
Johnny Chen83f6e512010-08-13 22:58:44 +00001559 print "Terminating Test suite..."
1560 subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1561
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001562# Exiting.
Daniel Malea24765572013-02-20 20:12:11 +00001563sys.exit(failed)