blob: 77c1cabded3233afe88d0ea1deda122ed075ae99 [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
Johnny Chen9707bb62010-06-25 21:14:08 +0000219# Default verbosity is 0.
Jim Ingham75f260a2013-02-19 20:39:27 +0000220verbose = 1
Johnny Chen9707bb62010-06-25 21:14:08 +0000221
Johnny Chen08967192011-11-18 00:19:29 +0000222# Set to True only if verbose is 0 and LLDB trace mode is off.
223progress_bar = False
224
Peter Collingbourne61aca482011-06-20 19:06:29 +0000225# By default, search from the script directory.
226testdirs = [ sys.path[0] ]
Johnny Chen9707bb62010-06-25 21:14:08 +0000227
Johnny Chen877c7e42010-08-07 00:16:07 +0000228# Separator string.
229separator = '-' * 70
230
Daniel Malea24765572013-02-20 20:12:11 +0000231failed = False
Johnny Chen9707bb62010-06-25 21:14:08 +0000232
Greg Clayton4793e942012-09-04 15:42:49 +0000233def usage(parser):
234 parser.print_help()
Jim Ingham4f347cb2011-04-13 21:11:41 +0000235 if verbose > 0:
236 print """
Johnny Chen9656ab22010-10-22 19:00:18 +0000237Examples:
238
Johnny Chena224cd12010-11-08 01:21:03 +0000239This is an example of using the -f option to pinpoint to a specfic test class
240and test method to be run:
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000241
Johnny Chena224cd12010-11-08 01:21:03 +0000242$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000243----------------------------------------------------------------------
244Collected 1 test
245
246test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
247Test 'frame variable this' when stopped on a class constructor. ... ok
248
249----------------------------------------------------------------------
250Ran 1 test in 1.396s
251
252OK
Johnny Chen9656ab22010-10-22 19:00:18 +0000253
254And this is an example of using the -p option to run a single file (the filename
255matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
256
257$ ./dotest.py -v -p ObjC
258----------------------------------------------------------------------
259Collected 4 tests
260
261test_break_with_dsym (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000262Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000263test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000264Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000265test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
266Lookup objective-c data types and evaluate expressions. ... ok
267test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
268Lookup objective-c data types and evaluate expressions. ... ok
269
270----------------------------------------------------------------------
271Ran 4 tests in 16.661s
272
273OK
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000274
Johnny Chen58f93922010-06-29 23:10:39 +0000275Running of this script also sets up the LLDB_TEST environment variable so that
Johnny Chenaf149a02010-09-16 17:11:30 +0000276individual test cases can locate their supporting files correctly. The script
277tries to set up Python's search paths for modules by looking at the build tree
Johnny Chena85859f2010-11-11 22:14:56 +0000278relative to this script. See also the '-i' option in the following example.
279
280Finally, this is an example of using the lldb.py module distributed/installed by
281Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
282option to add some delay between two tests. It uses ARCH=x86_64 to specify that
283as the architecture and CC=clang to specify the compiler used for the test run:
284
285$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
286
287Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
288----------------------------------------------------------------------
289Collected 2 tests
290
291test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
292Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
293test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
294Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
295
296----------------------------------------------------------------------
297Ran 2 tests in 5.659s
298
299OK
300
301The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
302notify the directory containing the session logs for test failures or errors.
303In case there is any test failure/error, a similar message is appended at the
304end of the stderr output for your convenience.
Johnny Chenfde69bc2010-09-14 22:01:40 +0000305
306Environment variables related to loggings:
307
308o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
309 with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
310
311o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
312 'process.gdb-remote' subsystem with a default option of 'packets' if
313 GDB_REMOTE_LOG_OPTION is not defined.
Johnny Chen9707bb62010-06-25 21:14:08 +0000314"""
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000315 sys.exit(0)
Johnny Chen9707bb62010-06-25 21:14:08 +0000316
317
Johnny Chenaf149a02010-09-16 17:11:30 +0000318def parseOptionsAndInitTestdirs():
319 """Initialize the list of directories containing our unittest scripts.
320
321 '-h/--help as the first option prints out usage info and exit the program.
322 """
323
Johnny Chen4f93bf12010-12-10 00:51:23 +0000324 global dont_do_python_api_test
325 global just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000326 global just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +0000327 global dont_do_dsym_test
328 global dont_do_dwarf_test
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000329 global blacklist
330 global blacklistConfig
Enrico Granataac3a8e22012-09-21 19:10:53 +0000331 global categoriesList
332 global validCategories
333 global useCategories
Sean Callanan0acf4c62012-10-24 22:45:39 +0000334 global lldbFrameworkPath
335 global lldbExecutablePath
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000336 global configFile
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000337 global archs
338 global compilers
Johnny Chend2acdb32010-11-16 22:42:58 +0000339 global count
Johnny Chenaf149a02010-09-16 17:11:30 +0000340 global delay
Johnny Chen50bc6382011-01-29 01:16:52 +0000341 global dumpSysPath
Johnny Chene00c9302011-10-10 22:03:44 +0000342 global bmExecutable
343 global bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000344 global bmIterationCount
Johnny Chen7d6d8442010-12-03 19:59:35 +0000345 global failfast
Johnny Chenc5fa0052011-07-29 22:54:56 +0000346 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000347 global fs4all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000348 global ignore
Johnny Chen08967192011-11-18 00:19:29 +0000349 global progress_bar
Johnny Chen38f823c2011-10-11 01:30:27 +0000350 global runHooks
Johnny Chen028d8eb2011-11-17 19:57:27 +0000351 global skip_build_and_cleanup
352 global skip_long_running_test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000353 global noHeaders
Daniel Malea361eb432013-02-15 21:31:37 +0000354 global parsable
Johnny Chen7c52ff12010-09-27 23:29:54 +0000355 global regexp
Johnny Chen548aefd2010-10-11 22:25:46 +0000356 global rdir
Johnny Chen125fc2b2010-10-21 16:55:35 +0000357 global sdir_name
Johnny Chenaf149a02010-09-16 17:11:30 +0000358 global verbose
359 global testdirs
360
Jim Ingham4f347cb2011-04-13 21:11:41 +0000361 do_help = False
362
Greg Clayton4793e942012-09-04 15:42:49 +0000363 parser = argparse.ArgumentParser(description='description', prefix_chars='+-', add_help=False)
364 group = None
Johnny Chenaf149a02010-09-16 17:11:30 +0000365
Greg Clayton4793e942012-09-04 15:42:49 +0000366 # Helper function for boolean options (group will point to the current group when executing X)
367 X = lambda optstr, helpstr, **kwargs: group.add_argument(optstr, help=helpstr, action='store_true', **kwargs)
368
369 group = parser.add_argument_group('Help')
370 group.add_argument('-h', '--help', dest='h', action='store_true', help="Print this help message and exit. Add '-v' for more detailed help.")
371
372 # C and Python toolchain options
373 group = parser.add_argument_group('Toolchain options')
374 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'''))
375 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.'''))
376 # FIXME? This won't work for different extra flags according to each arch.
377 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
378 suggestions: do not lump the "-A arch1 -A arch2" together such that the -E option applies to only one of the architectures'''))
379 X('-D', 'Dump the Python sys.path variable')
380
381 # Test filtering options
382 group = parser.add_argument_group('Test filtering options')
383 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")
384 X('-a', "Don't do lldb Python API tests")
385 X('+a', "Just do lldb Python API tests. Do not specify along with '+a'", dest='plus_a')
386 X('+b', 'Just do benchmark tests', dest='plus_b')
387 group.add_argument('-b', metavar='blacklist', help='Read a blacklist file specified after this option')
Enrico Granata58b03a42012-12-14 00:07:09 +0000388 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 +0000389 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')
390 X('-l', "Don't skip long running tests")
391 group.add_argument('-p', metavar='pattern', help='Specify a regexp filename pattern for inclusion in the test suite')
392 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 +0000393 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 +0000394
395 # Configuration options
396 group = parser.add_argument_group('Configuration options')
397 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 +0000398 group.add_argument('--framework', metavar='framework-path', help='The path to LLDB.framework')
399 group.add_argument('--executable', metavar='executable-path', help='The path to the lldb executable')
Greg Clayton4793e942012-09-04 15:42:49 +0000400 group.add_argument('-e', metavar='benchmark-exe', help='Specify the full path of an executable used for benchmark purposes (see also: -x)')
401 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")
402 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')
403 group.add_argument('-r', metavar='dir', help="Similar to '-R', except that the directory must not exist before running this test driver")
404 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')
405 group.add_argument('-x', metavar='breakpoint-spec', help='Specify the breakpoint specification for the benchmark executable')
406 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.")
407 group.add_argument('-#', type=int, metavar='sharp', dest='sharp', help='Repeat the test suite for a specified number of times')
408
409 # Test-suite behaviour
410 group = parser.add_argument_group('Runtime behaviour options')
411 X('-d', 'Delay startup for 10 seconds (in order for the debugger to attach)')
412 X('-F', 'Fail fast. Stop the test suite on the first error/failure')
413 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")
414 X('-n', "Don't print the headers like build dir, lldb version, and svn info at all")
Jim Ingham75f260a2013-02-19 20:39:27 +0000415 X('-P', "Use the graphic progress bar.")
Daniel Malea361eb432013-02-15 21:31:37 +0000416 X('-q', "Don't print extra output from this script.")
Greg Clayton4793e942012-09-04 15:42:49 +0000417 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")
418 X('-t', 'Turn on tracing of lldb command and other detailed test executions')
Greg Claytonb85785c2013-02-08 21:52:32 +0000419 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 +0000420 X('-v', 'Do verbose mode of unittest framework (print out each test case invocation)')
421 X('-w', 'Insert some wait time (currently 0.5 sec) between consecutive test cases')
422
423 # Remove the reference to our helper function
424 del X
425
426 group = parser.add_argument_group('Test directories')
427 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.')
428 args = parser.parse_args()
429
430 platform_system = platform.system()
431 platform_machine = platform.machine()
Enrico Granata2d329242012-10-23 22:52:49 +0000432
Greg Claytonb85785c2013-02-08 21:52:32 +0000433 if args.unset_env_varnames:
434 for env_var in args.unset_env_varnames:
435 if env_var in os.environ:
436 # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
437 # is automatically translated into a corresponding call to unsetenv().
438 del os.environ[env_var]
439 #os.unsetenv(env_var)
440
Daniel Malea361eb432013-02-15 21:31:37 +0000441 # only print the args if being verbose (and parsable is off)
442 if args.v and not args.q:
Enrico Granata2d329242012-10-23 22:52:49 +0000443 print args
Greg Clayton4793e942012-09-04 15:42:49 +0000444
445 if args.h:
446 do_help = True
447
448 if args.archs:
449 archs = args.archs
450 else:
451 if platform_system == 'Darwin' and platform_machine == 'x86_64':
452 archs = ['x86_64', 'i386']
Johnny Chenaf149a02010-09-16 17:11:30 +0000453 else:
Greg Clayton4793e942012-09-04 15:42:49 +0000454 archs = [platform_machine]
455
Enrico Granataac3a8e22012-09-21 19:10:53 +0000456 if args.categoriesList:
457 for category in args.categoriesList:
458 if not(category in validCategories):
Enrico Granata2d329242012-10-23 22:52:49 +0000459 print "fatal error: category '" + category + "' is not a valid category"
460 print "if you have added a new category, please edit dotest.py, adding your new category to validCategories"
461 print "else, please specify one or more of the following: " + str(validCategories.keys())
Enrico Granataac3a8e22012-09-21 19:10:53 +0000462 sys.exit(1)
463 categoriesList = set(args.categoriesList)
464 useCategories = True
465 else:
466 categoriesList = []
467
Greg Clayton4793e942012-09-04 15:42:49 +0000468 if args.compilers:
469 compilers = args.compilers
470 else:
471 compilers = ['clang']
472
473 if args.D:
474 dumpSysPath = True
475
476 if args.E:
477 cflags_extras = args.E
478 os.environ['CFLAGS_EXTRAS'] = cflags_extras
479
480 # argparse makes sure we have correct options
481 if args.N == 'dwarf':
482 dont_do_dwarf_test = True
483 elif args.N == 'dsym':
484 dont_do_dsym_test = True
485
486 if args.a:
487 dont_do_python_api_test = True
488
489 if args.plus_a:
490 if dont_do_python_api_test:
491 print "Warning: -a and +a can't both be specified! Using only -a"
492 else:
493 just_do_python_api_test = True
494
495 if args.plus_b:
496 just_do_benchmarks_test = True
497
498 if args.b:
499 if args.b.startswith('-'):
500 usage(parser)
501 blacklistFile = args.b
502 if not os.path.isfile(blacklistFile):
503 print 'Blacklist file:', blacklistFile, 'does not exist!'
504 usage(parser)
505 # Now read the blacklist contents and assign it to blacklist.
506 execfile(blacklistFile, globals(), blacklistConfig)
507 blacklist = blacklistConfig.get('blacklist')
508
509 if args.c:
510 if args.c.startswith('-'):
511 usage(parser)
512 configFile = args.c
513 if not os.path.isfile(configFile):
514 print 'Config file:', configFile, 'does not exist!'
515 usage(parser)
516
517 if args.d:
518 delay = True
519
520 if args.e:
521 if args.e.startswith('-'):
522 usage(parser)
523 bmExecutable = args.e
524 if not is_exe(bmExecutable):
525 usage(parser)
526
527 if args.F:
528 failfast = True
529
530 if args.f:
Enrico Granata58b03a42012-12-14 00:07:09 +0000531 if any([x.startswith('-') for x in args.f]):
Greg Clayton4793e942012-09-04 15:42:49 +0000532 usage(parser)
Enrico Granata58b03a42012-12-14 00:07:09 +0000533 filters.extend(args.f)
Greg Clayton4793e942012-09-04 15:42:49 +0000534
535 if args.g:
536 fs4all = False
537
538 if args.i:
539 ignore = True
540
541 if args.k:
542 runHooks.extend(args.k)
543
544 if args.l:
545 skip_long_running_test = False
546
Sean Callanan0acf4c62012-10-24 22:45:39 +0000547 if args.framework:
548 lldbFrameworkPath = args.framework
549
550 if args.executable:
551 lldbExecutablePath = args.executable
552
Greg Clayton4793e942012-09-04 15:42:49 +0000553 if args.n:
554 noHeaders = True
555
556 if args.p:
557 if args.p.startswith('-'):
558 usage(parser)
559 regexp = args.p
560
Daniel Malea361eb432013-02-15 21:31:37 +0000561 if args.q:
562 noHeaders = True
563 parsable = True
564
Jim Ingham75f260a2013-02-19 20:39:27 +0000565 if args.P:
566 progress_bar = True
567 verbose = 0
568
Greg Clayton4793e942012-09-04 15:42:49 +0000569 if args.R:
570 if args.R.startswith('-'):
571 usage(parser)
572 rdir = os.path.abspath(args.R)
573 if os.path.exists(rdir):
574 import shutil
575 print 'Removing tree:', rdir
576 shutil.rmtree(rdir)
577
578 if args.r:
579 if args.r.startswith('-'):
580 usage(parser)
581 rdir = os.path.abspath(args.r)
582 if os.path.exists(rdir):
583 print 'Relocated directory:', rdir, 'must not exist!'
584 usage(parser)
585
586 if args.S:
587 skip_build_and_cleanup = True
588
589 if args.s:
590 if args.s.startswith('-'):
591 usage(parser)
592 sdir_name = args.s
593
594 if args.t:
595 os.environ['LLDB_COMMAND_TRACE'] = 'YES'
596
Greg Clayton4793e942012-09-04 15:42:49 +0000597 if args.v:
598 verbose = 2
599
600 if args.w:
601 os.environ['LLDB_WAIT_BETWEEN_TEST_CASES'] = 'YES'
602
603 if args.X:
604 if args.X.startswith('-'):
605 usage(parser)
606 excluded.add(args.X)
607
608 if args.x:
609 if args.x.startswith('-'):
610 usage(parser)
611 bmBreakpointSpec = args.x
612
613 # argparse makes sure we have a number
614 if args.y:
615 bmIterationCount = args.y
616
617 # argparse makes sure we have a number
618 if args.sharp:
619 count = args.sharp
Johnny Chenaf149a02010-09-16 17:11:30 +0000620
Jim Ingham4f347cb2011-04-13 21:11:41 +0000621 if do_help == True:
Greg Clayton4793e942012-09-04 15:42:49 +0000622 usage(parser)
Jim Ingham4f347cb2011-04-13 21:11:41 +0000623
Johnny Chencc659ad2010-12-10 19:02:23 +0000624 # Do not specify both '-a' and '+a' at the same time.
625 if dont_do_python_api_test and just_do_python_api_test:
Greg Clayton4793e942012-09-04 15:42:49 +0000626 usage(parser)
Johnny Chencc659ad2010-12-10 19:02:23 +0000627
Johnny Chenaf149a02010-09-16 17:11:30 +0000628 # Gather all the dirs passed on the command line.
Greg Clayton4793e942012-09-04 15:42:49 +0000629 if len(args.args) > 0:
630 testdirs = map(os.path.abspath, args.args)
Johnny Chenaf149a02010-09-16 17:11:30 +0000631
Johnny Chen548aefd2010-10-11 22:25:46 +0000632 # If '-r dir' is specified, the tests should be run under the relocated
633 # directory. Let's copy the testdirs over.
634 if rdir:
635 from shutil import copytree, ignore_patterns
636
637 tmpdirs = []
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000638 orig_testdirs = testdirs[:]
Johnny Chen548aefd2010-10-11 22:25:46 +0000639 for srcdir in testdirs:
Johnny Chen1abe4c02012-03-20 00:33:51 +0000640 # For example, /Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/hello_watchpoint
641 # shall be split into ['/Volumes/data/lldb/svn/ToT/', 'functionalities/watchpoint/hello_watchpoint'].
642 # Utilize the relative path to the 'test' directory to make our destination dir path.
Greg Clayton4793e942012-09-04 15:42:49 +0000643 if ("test" + os.sep) in srcdir:
644 to_split_on = "test" + os.sep
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000645 else:
646 to_split_on = "test"
647 dstdir = os.path.join(rdir, srcdir.split(to_split_on)[1])
648 dstdir = dstdir.rstrip(os.sep)
Johnny Chen548aefd2010-10-11 22:25:46 +0000649 # Don't copy the *.pyc and .svn stuffs.
650 copytree(srcdir, dstdir, ignore=ignore_patterns('*.pyc', '.svn'))
651 tmpdirs.append(dstdir)
652
653 # This will be our modified testdirs.
654 testdirs = tmpdirs
655
656 # With '-r dir' specified, there's no cleanup of intermediate test files.
657 os.environ["LLDB_DO_CLEANUP"] = 'NO'
658
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000659 # If the original testdirs is ['test'], the make directory has already been copied
Johnny Chen548aefd2010-10-11 22:25:46 +0000660 # recursively and is contained within the rdir/test dir. For anything
661 # else, we would need to copy over the make directory and its contents,
662 # so that, os.listdir(rdir) looks like, for example:
663 #
664 # array_types conditional_break make
665 #
666 # where the make directory contains the Makefile.rules file.
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000667 if len(testdirs) != 1 or os.path.basename(orig_testdirs[0]) != 'test':
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000668 scriptdir = os.path.dirname(__file__)
Johnny Chen548aefd2010-10-11 22:25:46 +0000669 # Don't copy the .svn stuffs.
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000670 copytree(os.path.join(scriptdir, 'make'), os.path.join(rdir, 'make'),
Johnny Chen548aefd2010-10-11 22:25:46 +0000671 ignore=ignore_patterns('.svn'))
672
673 #print "testdirs:", testdirs
674
Johnny Chenb40056b2010-09-21 00:09:27 +0000675 # Source the configFile if specified.
676 # The side effect, if any, will be felt from this point on. An example
677 # config file may be these simple two lines:
678 #
679 # sys.stderr = open("/tmp/lldbtest-stderr", "w")
680 # sys.stdout = open("/tmp/lldbtest-stdout", "w")
681 #
682 # which will reassign the two file objects to sys.stderr and sys.stdout,
683 # respectively.
684 #
Johnny Chen8c130642012-08-22 17:53:02 +0000685 # See also lldb-trunk/examples/test/usage-config.
Johnny Chenac97a6b2012-04-16 18:55:15 +0000686 global config, pre_flight, post_flight
Johnny Chenb40056b2010-09-21 00:09:27 +0000687 if configFile:
688 # Pass config (a dictionary) as the locals namespace for side-effect.
689 execfile(configFile, globals(), config)
Johnny Chenac97a6b2012-04-16 18:55:15 +0000690 print "config:", config
691 if "pre_flight" in config:
692 pre_flight = config["pre_flight"]
693 if not callable(pre_flight):
694 print "fatal error: pre_flight is not callable, exiting."
695 sys.exit(1)
696 if "post_flight" in config:
697 post_flight = config["post_flight"]
698 if not callable(post_flight):
699 print "fatal error: post_flight is not callable, exiting."
700 sys.exit(1)
Johnny Chenb40056b2010-09-21 00:09:27 +0000701 #print "sys.stderr:", sys.stderr
702 #print "sys.stdout:", sys.stdout
703
Johnny Chenaf149a02010-09-16 17:11:30 +0000704
Johnny Chen9707bb62010-06-25 21:14:08 +0000705def setupSysPath():
Johnny Chen8a3c0432011-03-11 20:13:06 +0000706 """
707 Add LLDB.framework/Resources/Python to the search paths for modules.
708 As a side effect, we also discover the 'lldb' executable and export it here.
709 """
Johnny Chen9707bb62010-06-25 21:14:08 +0000710
Johnny Chen548aefd2010-10-11 22:25:46 +0000711 global rdir
712 global testdirs
Johnny Chen50bc6382011-01-29 01:16:52 +0000713 global dumpSysPath
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000714 global noHeaders
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000715 global svn_info
Sean Callanan0acf4c62012-10-24 22:45:39 +0000716 global lldbFrameworkPath
717 global lldbExecutablePath
Johnny Chen548aefd2010-10-11 22:25:46 +0000718
Johnny Chen9707bb62010-06-25 21:14:08 +0000719 # Get the directory containing the current script.
Johnny Chen4d162e52011-08-12 18:54:11 +0000720 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 +0000721 scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
722 else:
723 scriptPath = sys.path[0]
Johnny Chena1affab2010-07-03 03:41:59 +0000724 if not scriptPath.endswith('test'):
Johnny Chen9707bb62010-06-25 21:14:08 +0000725 print "This script expects to reside in lldb's test directory."
726 sys.exit(-1)
727
Johnny Chen548aefd2010-10-11 22:25:46 +0000728 if rdir:
729 # Set up the LLDB_TEST environment variable appropriately, so that the
730 # individual tests can be located relatively.
731 #
732 # See also lldbtest.TestBase.setUpClass(cls).
733 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
734 os.environ["LLDB_TEST"] = os.path.join(rdir, 'test')
735 else:
736 os.environ["LLDB_TEST"] = rdir
737 else:
738 os.environ["LLDB_TEST"] = scriptPath
Peter Collingbournef6c3de82011-06-20 19:06:45 +0000739
740 # Set up the LLDB_SRC environment variable, so that the tests can locate
741 # the LLDB source code.
742 os.environ["LLDB_SRC"] = os.path.join(sys.path[0], os.pardir)
743
Johnny Chen9de4ede2010-08-31 17:42:54 +0000744 pluginPath = os.path.join(scriptPath, 'plugins')
Johnny Chen8a3c0432011-03-11 20:13:06 +0000745 pexpectPath = os.path.join(scriptPath, 'pexpect-2.4')
Johnny Chen58f93922010-06-29 23:10:39 +0000746
Johnny Chen8a3c0432011-03-11 20:13:06 +0000747 # Append script dir, plugin dir, and pexpect dir to the sys.path.
Johnny Chenaf149a02010-09-16 17:11:30 +0000748 sys.path.append(scriptPath)
749 sys.path.append(pluginPath)
Johnny Chen8a3c0432011-03-11 20:13:06 +0000750 sys.path.append(pexpectPath)
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000751
Johnny Chen26901c82011-03-11 19:47:23 +0000752 # This is our base name component.
Johnny Chena1affab2010-07-03 03:41:59 +0000753 base = os.path.abspath(os.path.join(scriptPath, os.pardir))
Johnny Chen6a564a42011-02-15 18:50:19 +0000754
Johnny Chen26901c82011-03-11 19:47:23 +0000755 # These are for xcode build directories.
Johnny Chen6a564a42011-02-15 18:50:19 +0000756 xcode3_build_dir = ['build']
757 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
758 dbg = ['Debug']
Sean Callanand9d94632012-09-26 21:16:15 +0000759 dbc = ['DebugClang']
Johnny Chen6a564a42011-02-15 18:50:19 +0000760 rel = ['Release']
761 bai = ['BuildAndIntegration']
762 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
Johnny Chen26901c82011-03-11 19:47:23 +0000763
764 # Some of the tests can invoke the 'lldb' command directly.
765 # We'll try to locate the appropriate executable right here.
766
Sean Callanan0acf4c62012-10-24 22:45:39 +0000767 lldbExec = None
768 if lldbExecutablePath:
769 if is_exe(lldbExecutablePath):
770 lldbExec = lldbExecutablePath
Sean Callanan502000d2012-11-01 21:23:21 +0000771 lldbHere = lldbExec
Sean Callanan0acf4c62012-10-24 22:45:39 +0000772 else:
773 print lldbExecutablePath + " is not an executable"
774 sys.exit(-1)
Johnny Chen6033bed2011-08-26 00:00:01 +0000775 else:
Sean Callanan0acf4c62012-10-24 22:45:39 +0000776 # First, you can define an environment variable LLDB_EXEC specifying the
777 # full pathname of the lldb executable.
778 if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
779 lldbExec = os.environ["LLDB_EXEC"]
780 else:
781 lldbExec = None
782
783 executable = ['lldb']
784 dbgExec = os.path.join(base, *(xcode3_build_dir + dbg + executable))
785 dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
786 dbcExec = os.path.join(base, *(xcode3_build_dir + dbc + executable))
787 dbcExec2 = os.path.join(base, *(xcode4_build_dir + dbc + executable))
788 relExec = os.path.join(base, *(xcode3_build_dir + rel + executable))
789 relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
790 baiExec = os.path.join(base, *(xcode3_build_dir + bai + executable))
791 baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
792
793 # The 'lldb' executable built here in the source tree.
794 lldbHere = None
795 if is_exe(dbgExec):
796 lldbHere = dbgExec
797 elif is_exe(dbgExec2):
798 lldbHere = dbgExec2
799 elif is_exe(dbcExec):
800 lldbHere = dbcExec
801 elif is_exe(dbcExec2):
802 lldbHere = dbcExec2
803 elif is_exe(relExec):
804 lldbHere = relExec
805 elif is_exe(relExec2):
806 lldbHere = relExec2
807 elif is_exe(baiExec):
808 lldbHere = baiExec
809 elif is_exe(baiExec2):
810 lldbHere = baiExec2
811 elif lldbExec:
812 lldbHere = lldbExec
Sean Callanan502000d2012-11-01 21:23:21 +0000813
Sean Callanan0acf4c62012-10-24 22:45:39 +0000814 # One last chance to locate the 'lldb' executable.
815 if not lldbExec:
816 lldbExec = which('lldb')
817 if lldbHere and not lldbExec:
818 lldbExec = lldbHere
Daniel Malea2777b012013-02-06 16:55:07 +0000819 if lldbExec and not lldbHere:
820 lldbHere = lldbExec
Sean Callanan502000d2012-11-01 21:23:21 +0000821
822 if lldbHere:
823 os.environ["LLDB_HERE"] = lldbHere
Matt Kopeca964b092013-02-20 20:54:10 +0000824 os.environ["LLDB_LIB_DIR"] = os.path.split(lldbHere)[0]
Sean Callanan502000d2012-11-01 21:23:21 +0000825 if not noHeaders:
Matt Kopeca964b092013-02-20 20:54:10 +0000826 print "LLDB library dir:", os.environ["LLDB_LIB_DIR"]
Sean Callanan502000d2012-11-01 21:23:21 +0000827 os.system('%s -v' % lldbHere)
Johnny Chen26901c82011-03-11 19:47:23 +0000828
829 if not lldbExec:
830 print "The 'lldb' executable cannot be located. Some of the tests may not be run as a result."
831 else:
832 os.environ["LLDB_EXEC"] = lldbExec
Johnny Chen8904eb02011-10-28 00:59:00 +0000833 #print "The 'lldb' from PATH env variable", lldbExec
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000834
Daniel Malea2b606ab2013-03-13 20:50:05 +0000835 # Skip printing svn/git information when running in parsable (lit-test compatibility) mode
836 if not parsable:
837 if os.path.isdir(os.path.join(base, '.svn')) and which("svn") is not None:
838 pipe = subprocess.Popen([which("svn"), "info", base], stdout = subprocess.PIPE)
839 svn_info = pipe.stdout.read()
840 elif os.path.isdir(os.path.join(base, '.git')) and which("git") is not None:
841 pipe = subprocess.Popen([which("git"), "svn", "info", base], stdout = subprocess.PIPE)
842 svn_info = pipe.stdout.read()
843 if not noHeaders:
844 print svn_info
Johnny Chen26901c82011-03-11 19:47:23 +0000845
846 global ignore
847
Johnny Chen9707bb62010-06-25 21:14:08 +0000848 lldbPath = None
Sean Callanan0acf4c62012-10-24 22:45:39 +0000849 if lldbFrameworkPath:
850 candidatePath = os.path.join(lldbFrameworkPath, 'Resources', 'Python')
851 if os.path.isfile(os.path.join(candidatePath, 'lldb/__init__.py')):
852 lldbPath = candidatePath
853 if not lldbPath:
854 print 'Resources/Python/lldb/__init__.py was not found in ' + lldbFrameworkPath
855 sys.exit(-1)
856 else:
857 # The '-i' option is used to skip looking for lldb.py in the build tree.
858 if ignore:
859 return
Jim Inghamaa93c932012-12-21 22:22:26 +0000860
861 # If our lldb supports the -P option, use it to find the python path:
862 init_in_python_dir = 'lldb/__init__.py'
863 import pexpect
864 lldb_dash_p_result = None
865
866 if lldbHere:
867 lldb_dash_p_result = pexpect.run("%s -P"%(lldbHere))
868 elif lldbExec:
869 lldb_dash_p_result = pexpect.run("%s -P"%(lldbExec))
870
871 if lldb_dash_p_result and not lldb_dash_p_result.startswith(("<", "lldb: invalid option:")):
872 lines = lldb_dash_p_result.splitlines()
873 if len(lines) == 1 and os.path.isfile(os.path.join(lines[0], init_in_python_dir)):
874 lldbPath = lines[0]
Daniel Malea21e32a62013-01-04 23:35:13 +0000875 if "linux" in sys.platform:
Matt Kopeca964b092013-02-20 20:54:10 +0000876 os.environ['LLDB_LIB_DIR'] = os.path.join(lldbPath, '..', '..')
Jim Inghamaa93c932012-12-21 22:22:26 +0000877
878 if not lldbPath:
879 dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
880 dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
881 dbcPath = os.path.join(base, *(xcode3_build_dir + dbc + python_resource_dir))
882 dbcPath2 = os.path.join(base, *(xcode4_build_dir + dbc + python_resource_dir))
883 relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
884 relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
885 baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
886 baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
Sean Callanan0acf4c62012-10-24 22:45:39 +0000887
Jim Inghamaa93c932012-12-21 22:22:26 +0000888 if os.path.isfile(os.path.join(dbgPath, init_in_python_dir)):
889 lldbPath = dbgPath
890 elif os.path.isfile(os.path.join(dbgPath2, init_in_python_dir)):
891 lldbPath = dbgPath2
892 elif os.path.isfile(os.path.join(dbcPath, init_in_python_dir)):
893 lldbPath = dbcPath
894 elif os.path.isfile(os.path.join(dbcPath2, init_in_python_dir)):
895 lldbPath = dbcPath2
896 elif os.path.isfile(os.path.join(relPath, init_in_python_dir)):
897 lldbPath = relPath
898 elif os.path.isfile(os.path.join(relPath2, init_in_python_dir)):
899 lldbPath = relPath2
900 elif os.path.isfile(os.path.join(baiPath, init_in_python_dir)):
901 lldbPath = baiPath
902 elif os.path.isfile(os.path.join(baiPath2, init_in_python_dir)):
903 lldbPath = baiPath2
904
Sean Callanan0acf4c62012-10-24 22:45:39 +0000905 if not lldbPath:
906 print 'This script requires lldb.py to be in either ' + dbgPath + ',',
907 print relPath + ', or ' + baiPath
908 sys.exit(-1)
Johnny Chen9707bb62010-06-25 21:14:08 +0000909
Jim Inghamaa93c932012-12-21 22:22:26 +0000910 # Some of the code that uses this path assumes it hasn't resolved the Versions... link.
911 # If the path we've constructed looks like that, then we'll strip out the Versions/A part.
912 (before, frameWithVersion, after) = lldbPath.rpartition("LLDB.framework/Versions/A")
913 if frameWithVersion != "" :
914 lldbPath = before + "LLDB.framework" + after
915
Enrico Granata0ad92972013-04-11 23:40:59 +0000916 lldbPath = os.path.abspath(lldbPath)
917
Enrico Granata01458ca2012-10-23 00:09:02 +0000918 # If tests need to find LLDB_FRAMEWORK, now they can do it
919 os.environ["LLDB_FRAMEWORK"] = os.path.dirname(os.path.dirname(lldbPath))
920
Johnny Chenaf149a02010-09-16 17:11:30 +0000921 # This is to locate the lldb.py module. Insert it right after sys.path[0].
922 sys.path[1:1] = [lldbPath]
Johnny Chen50bc6382011-01-29 01:16:52 +0000923 if dumpSysPath:
924 print "sys.path:", sys.path
Johnny Chen9707bb62010-06-25 21:14:08 +0000925
Johnny Chen9707bb62010-06-25 21:14:08 +0000926
Johnny Chencd0279d2010-09-20 18:07:50 +0000927def doDelay(delta):
928 """Delaying startup for delta-seconds to facilitate debugger attachment."""
929 def alarm_handler(*args):
930 raise Exception("timeout")
931
932 signal.signal(signal.SIGALRM, alarm_handler)
933 signal.alarm(delta)
934 sys.stdout.write("pid=%d\n" % os.getpid())
935 sys.stdout.write("Enter RET to proceed (or timeout after %d seconds):" %
936 delta)
937 sys.stdout.flush()
938 try:
939 text = sys.stdin.readline()
940 except:
941 text = ""
942 signal.alarm(0)
943 sys.stdout.write("proceeding...\n")
944 pass
945
946
Johnny Chen9707bb62010-06-25 21:14:08 +0000947def visit(prefix, dir, names):
948 """Visitor function for os.path.walk(path, visit, arg)."""
949
950 global suite
Johnny Chen7c52ff12010-09-27 23:29:54 +0000951 global regexp
Johnny Chenc5fa0052011-07-29 22:54:56 +0000952 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000953 global fs4all
Johnny Chene9eae812012-01-18 05:15:00 +0000954 global excluded
955
956 if set(dir.split(os.sep)).intersection(excluded):
957 #print "Detected an excluded dir component: %s" % dir
958 return
Johnny Chen9707bb62010-06-25 21:14:08 +0000959
960 for name in names:
961 if os.path.isdir(os.path.join(dir, name)):
962 continue
963
964 if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
Johnny Chen7c52ff12010-09-27 23:29:54 +0000965 # Try to match the regexp pattern, if specified.
966 if regexp:
967 import re
968 if re.search(regexp, name):
969 #print "Filename: '%s' matches pattern: '%s'" % (name, regexp)
970 pass
971 else:
972 #print "Filename: '%s' does not match pattern: '%s'" % (name, regexp)
973 continue
974
Johnny Chen953864a2010-10-12 21:35:54 +0000975 # We found a match for our test. Add it to the suite.
Johnny Chen79723352010-10-12 15:53:22 +0000976
977 # Update the sys.path first.
Johnny Chena85d7ee2010-06-26 00:19:32 +0000978 if not sys.path.count(dir):
Johnny Chen548aefd2010-10-11 22:25:46 +0000979 sys.path.insert(0, dir)
Johnny Chen9707bb62010-06-25 21:14:08 +0000980 base = os.path.splitext(name)[0]
Johnny Chenb62436b2010-10-06 20:40:56 +0000981
982 # Thoroughly check the filterspec against the base module and admit
983 # the (base, filterspec) combination only when it makes sense.
Johnny Chenc5fa0052011-07-29 22:54:56 +0000984 filterspec = None
985 for filterspec in filters:
Johnny Chenb62436b2010-10-06 20:40:56 +0000986 # Optimistically set the flag to True.
987 filtered = True
988 module = __import__(base)
989 parts = filterspec.split('.')
990 obj = module
991 for part in parts:
992 try:
993 parent, obj = obj, getattr(obj, part)
994 except AttributeError:
995 # The filterspec has failed.
996 filtered = False
997 break
Johnny Chenc5fa0052011-07-29 22:54:56 +0000998
Johnny Chendb4be602011-08-12 23:55:07 +0000999 # If filtered, we have a good filterspec. Add it.
Johnny Chenc5fa0052011-07-29 22:54:56 +00001000 if filtered:
Johnny Chendb4be602011-08-12 23:55:07 +00001001 #print "adding filter spec %s to module %s" % (filterspec, module)
1002 suite.addTests(
1003 unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
1004 continue
Johnny Chenc5fa0052011-07-29 22:54:56 +00001005
1006 # Forgo this module if the (base, filterspec) combo is invalid
1007 # and no '-g' option is specified
1008 if filters and fs4all and not filtered:
1009 continue
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001010
Johnny Chendb4be602011-08-12 23:55:07 +00001011 # Add either the filtered test case(s) (which is done before) or the entire test class.
1012 if not filterspec or not filtered:
Johnny Chenb62436b2010-10-06 20:40:56 +00001013 # A simple case of just the module name. Also the failover case
1014 # from the filterspec branch when the (base, filterspec) combo
1015 # doesn't make sense.
1016 suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
Johnny Chen9707bb62010-06-25 21:14:08 +00001017
1018
Johnny Chencd0279d2010-09-20 18:07:50 +00001019def lldbLoggings():
1020 """Check and do lldb loggings if necessary."""
1021
1022 # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
1023 # defined. Use ${LLDB_LOG} to specify the log file.
1024 ci = lldb.DBG.GetCommandInterpreter()
1025 res = lldb.SBCommandReturnObject()
1026 if ("LLDB_LOG" in os.environ):
1027 if ("LLDB_LOG_OPTION" in os.environ):
1028 lldb_log_option = os.environ["LLDB_LOG_OPTION"]
1029 else:
Johnny Chen8fd886c2010-12-08 01:25:21 +00001030 lldb_log_option = "event process expr state api"
Johnny Chencd0279d2010-09-20 18:07:50 +00001031 ci.HandleCommand(
Greg Clayton940b1032011-02-23 00:35:02 +00001032 "log enable -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option,
Johnny Chencd0279d2010-09-20 18:07:50 +00001033 res)
1034 if not res.Succeeded():
1035 raise Exception('log enable failed (check LLDB_LOG env variable.')
1036 # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
1037 # Use ${GDB_REMOTE_LOG} to specify the log file.
1038 if ("GDB_REMOTE_LOG" in os.environ):
1039 if ("GDB_REMOTE_LOG_OPTION" in os.environ):
1040 gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
1041 else:
Johnny Chen7ab8c852010-12-02 18:35:13 +00001042 gdb_remote_log_option = "packets process"
Johnny Chencd0279d2010-09-20 18:07:50 +00001043 ci.HandleCommand(
Johnny Chenc935a892011-06-21 19:25:45 +00001044 "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
Johnny Chencd0279d2010-09-20 18:07:50 +00001045 + gdb_remote_log_option,
1046 res)
1047 if not res.Succeeded():
1048 raise Exception('log enable failed (check GDB_REMOTE_LOG env variable.')
1049
Johnny Chen067022b2011-01-19 19:31:46 +00001050def getMyCommandLine():
Johnny Chen067022b2011-01-19 19:31:46 +00001051 ps = subprocess.Popen(['ps', '-o', "command=CMD", str(os.getpid())], stdout=subprocess.PIPE).communicate()[0]
1052 lines = ps.split('\n')
1053 cmd_line = lines[1]
1054 return cmd_line
Johnny Chencd0279d2010-09-20 18:07:50 +00001055
Johnny Chend96b5682010-11-05 17:30:53 +00001056# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +00001057# #
1058# Execution of the test driver starts here #
1059# #
Johnny Chend96b5682010-11-05 17:30:53 +00001060# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +00001061
Johnny Chen2891bb02011-09-16 01:04:26 +00001062def checkDsymForUUIDIsNotOn():
Johnny Chen6a4e0872011-09-16 17:50:44 +00001063 cmd = ["defaults", "read", "com.apple.DebugSymbols"]
1064 pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1065 cmd_output = pipe.stdout.read()
Johnny Chen178c8d92011-09-16 18:03:19 +00001066 if cmd_output and "DBGFileMappedPaths = " in cmd_output:
Johnny Chen6a451482011-09-16 18:09:45 +00001067 print "%s =>" % ' '.join(cmd)
Johnny Chen6a4e0872011-09-16 17:50:44 +00001068 print cmd_output
Johnny Chen2891bb02011-09-16 01:04:26 +00001069 print "Disable automatic lookup and caching of dSYMs before running the test suite!"
1070 print "Exiting..."
1071 sys.exit(0)
1072
1073# On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
1074# does not exist before proceeding to running the test suite.
1075if sys.platform.startswith("darwin"):
1076 checkDsymForUUIDIsNotOn()
1077
Johnny Chen9707bb62010-06-25 21:14:08 +00001078#
Johnny Chenaf149a02010-09-16 17:11:30 +00001079# Start the actions by first parsing the options while setting up the test
1080# directories, followed by setting up the search paths for lldb utilities;
1081# then, we walk the directory trees and collect the tests into our test suite.
Johnny Chen9707bb62010-06-25 21:14:08 +00001082#
Johnny Chenaf149a02010-09-16 17:11:30 +00001083parseOptionsAndInitTestdirs()
Johnny Chen9707bb62010-06-25 21:14:08 +00001084setupSysPath()
Johnny Chen91960d32010-09-08 20:56:16 +00001085
1086#
1087# If '-d' is specified, do a delay of 10 seconds for the debugger to attach.
1088#
1089if delay:
Johnny Chencd0279d2010-09-20 18:07:50 +00001090 doDelay(10)
Johnny Chen91960d32010-09-08 20:56:16 +00001091
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001092#
Johnny Chen41998192010-10-01 22:59:49 +00001093# If '-l' is specified, do not skip the long running tests.
Johnny Chen028d8eb2011-11-17 19:57:27 +00001094if not skip_long_running_test:
Johnny Chen41998192010-10-01 22:59:49 +00001095 os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
1096
1097#
Johnny Chen79723352010-10-12 15:53:22 +00001098# Walk through the testdirs while collecting tests.
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001099#
Johnny Chen9707bb62010-06-25 21:14:08 +00001100for testdir in testdirs:
1101 os.path.walk(testdir, visit, 'Test')
1102
Johnny Chenb40056b2010-09-21 00:09:27 +00001103#
Johnny Chen9707bb62010-06-25 21:14:08 +00001104# Now that we have loaded all the test cases, run the whole test suite.
Johnny Chenb40056b2010-09-21 00:09:27 +00001105#
Johnny Chencd0279d2010-09-20 18:07:50 +00001106
Johnny Chen1bfbd412010-06-29 19:44:16 +00001107# For the time being, let's bracket the test runner within the
1108# lldb.SBDebugger.Initialize()/Terminate() pair.
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001109import lldb, atexit
Johnny Chen6b6f5ba2010-10-14 16:36:49 +00001110# Update: the act of importing lldb now executes lldb.SBDebugger.Initialize(),
1111# there's no need to call it a second time.
1112#lldb.SBDebugger.Initialize()
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001113atexit.register(lambda: lldb.SBDebugger.Terminate())
Johnny Chen1bfbd412010-06-29 19:44:16 +00001114
Johnny Chen909e5a62010-07-01 22:52:57 +00001115# Create a singleton SBDebugger in the lldb namespace.
1116lldb.DBG = lldb.SBDebugger.Create()
1117
Johnny Chen4f93bf12010-12-10 00:51:23 +00001118# Put the blacklist in the lldb namespace, to be used by lldb.TestBase.
Johnny Chen82e6b1e2010-12-01 22:47:54 +00001119lldb.blacklist = blacklist
1120
Johnny Chenac97a6b2012-04-16 18:55:15 +00001121# The pre_flight and post_flight come from reading a config file.
1122lldb.pre_flight = pre_flight
1123lldb.post_flight = post_flight
1124def getsource_if_available(obj):
1125 """
1126 Return the text of the source code for an object if available. Otherwise,
1127 a print representation is returned.
1128 """
1129 import inspect
1130 try:
1131 return inspect.getsource(obj)
1132 except:
1133 return repr(obj)
1134
Daniel Malea361eb432013-02-15 21:31:37 +00001135if not noHeaders:
1136 print "lldb.pre_flight:", getsource_if_available(lldb.pre_flight)
1137 print "lldb.post_flight:", getsource_if_available(lldb.post_flight)
Johnny Chenac97a6b2012-04-16 18:55:15 +00001138
Johnny Chena3ed7d82012-04-06 00:56:05 +00001139# Put all these test decorators in the lldb namespace.
Johnny Chen4f93bf12010-12-10 00:51:23 +00001140lldb.dont_do_python_api_test = dont_do_python_api_test
1141lldb.just_do_python_api_test = just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +00001142lldb.just_do_benchmarks_test = just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +00001143lldb.dont_do_dsym_test = dont_do_dsym_test
1144lldb.dont_do_dwarf_test = dont_do_dwarf_test
Johnny Chen4f93bf12010-12-10 00:51:23 +00001145
Johnny Chen028d8eb2011-11-17 19:57:27 +00001146# Do we need to skip build and cleanup?
1147lldb.skip_build_and_cleanup = skip_build_and_cleanup
1148
Johnny Chen5f2ed172011-10-20 18:43:28 +00001149# Put bmExecutable, bmBreakpointSpec, and bmIterationCount into the lldb namespace, too.
Johnny Chene00c9302011-10-10 22:03:44 +00001150lldb.bmExecutable = bmExecutable
1151lldb.bmBreakpointSpec = bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +00001152lldb.bmIterationCount = bmIterationCount
Johnny Chene00c9302011-10-10 22:03:44 +00001153
Johnny Chen38f823c2011-10-11 01:30:27 +00001154# And don't forget the runHooks!
1155lldb.runHooks = runHooks
1156
Johnny Chencd0279d2010-09-20 18:07:50 +00001157# Turn on lldb loggings if necessary.
1158lldbLoggings()
Johnny Chen909e5a62010-07-01 22:52:57 +00001159
Johnny Chen7987ac92010-08-09 20:40:52 +00001160# Install the control-c handler.
1161unittest2.signals.installHandler()
1162
Johnny Chen125fc2b2010-10-21 16:55:35 +00001163# If sdir_name is not specified through the '-s sdir_name' option, get a
1164# timestamp string and export it as LLDB_SESSION_DIR environment var. This will
1165# be used when/if we want to dump the session info of individual test cases
1166# later on.
Johnny Chence681462010-10-19 00:25:01 +00001167#
1168# See also TestBase.dumpSessionInfo() in lldbtest.py.
Johnny Chena73ad662012-08-16 19:15:21 +00001169import datetime
1170# The windows platforms don't like ':' in the pathname.
1171timestamp_started = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
Johnny Chen125fc2b2010-10-21 16:55:35 +00001172if not sdir_name:
Johnny Chena73ad662012-08-16 19:15:21 +00001173 sdir_name = timestamp_started
Peter Collingbourne132476f2011-06-20 23:55:53 +00001174os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), sdir_name)
Johnny Chen067022b2011-01-19 19:31:46 +00001175
Johnny Chenfe5f1ed2011-10-21 18:33:27 +00001176if not noHeaders:
1177 sys.stderr.write("\nSession logs for test failures/errors/unexpected successes"
1178 " will go into directory '%s'\n" % sdir_name)
1179 sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
Johnny Chence681462010-10-19 00:25:01 +00001180
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001181if not os.path.isdir(sdir_name):
1182 os.mkdir(sdir_name)
Johnny Chena73ad662012-08-16 19:15:21 +00001183fname = os.path.join(sdir_name, "TestStarted")
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001184with open(fname, "w") as f:
Johnny Chena73ad662012-08-16 19:15:21 +00001185 print >> f, "Test started at: %s\n" % timestamp_started
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001186 print >> f, svn_info
1187 print >> f, "Command invoked: %s\n" % getMyCommandLine()
1188
Johnny Chenb40056b2010-09-21 00:09:27 +00001189#
1190# Invoke the default TextTestRunner to run the test suite, possibly iterating
1191# over different configurations.
1192#
1193
Johnny Chenb40056b2010-09-21 00:09:27 +00001194iterArchs = False
Johnny Chenf032d902010-09-21 00:16:09 +00001195iterCompilers = False
Johnny Chenb40056b2010-09-21 00:09:27 +00001196
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001197if not archs and "archs" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001198 archs = config["archs"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001199
1200if isinstance(archs, list) and len(archs) >= 1:
1201 iterArchs = True
1202
1203if not compilers and "compilers" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001204 compilers = config["compilers"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001205
Johnny Chen92693b52012-03-09 02:11:37 +00001206#
1207# Add some intervention here to sanity check that the compilers requested are sane.
1208# If found not to be an executable program, the invalid one is dropped from the list.
1209for i in range(len(compilers)):
1210 c = compilers[i]
1211 if which(c):
1212 continue
1213 else:
1214 if sys.platform.startswith("darwin"):
1215 pipe = subprocess.Popen(['xcrun', '-find', c], stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1216 cmd_output = pipe.stdout.read()
1217 if cmd_output:
1218 if "not found" in cmd_output:
1219 print "dropping %s from the compilers used" % c
1220 compilers.remove(i)
1221 else:
1222 compilers[i] = cmd_output.split('\n')[0]
1223 print "'xcrun -find %s' returning %s" % (c, compilers[i])
1224
Daniel Malea361eb432013-02-15 21:31:37 +00001225if not parsable:
1226 print "compilers=%s" % str(compilers)
Johnny Chen92693b52012-03-09 02:11:37 +00001227
1228if not compilers or len(compilers) == 0:
1229 print "No eligible compiler found, exiting."
1230 sys.exit(1)
1231
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001232if isinstance(compilers, list) and len(compilers) >= 1:
1233 iterCompilers = True
Johnny Chenb40056b2010-09-21 00:09:27 +00001234
Johnny Chen953864a2010-10-12 21:35:54 +00001235# Make a shallow copy of sys.path, we need to manipulate the search paths later.
1236# This is only necessary if we are relocated and with different configurations.
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001237if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001238 old_sys_path = sys.path[:]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001239# If we iterate on archs or compilers, there is a chance we want to split stderr/stdout.
1240if iterArchs or iterCompilers:
Johnny Chen953864a2010-10-12 21:35:54 +00001241 old_stderr = sys.stderr
1242 old_stdout = sys.stdout
1243 new_stderr = None
1244 new_stdout = None
1245
Johnny Chend96b5682010-11-05 17:30:53 +00001246# Iterating over all possible architecture and compiler combinations.
Johnny Chenb40056b2010-09-21 00:09:27 +00001247for ia in range(len(archs) if iterArchs else 1):
1248 archConfig = ""
1249 if iterArchs:
Johnny Chen18a921f2010-09-30 17:11:58 +00001250 os.environ["ARCH"] = archs[ia]
Johnny Chenb40056b2010-09-21 00:09:27 +00001251 archConfig = "arch=%s" % archs[ia]
1252 for ic in range(len(compilers) if iterCompilers else 1):
1253 if iterCompilers:
Johnny Chen18a921f2010-09-30 17:11:58 +00001254 os.environ["CC"] = compilers[ic]
Johnny Chenb40056b2010-09-21 00:09:27 +00001255 configString = "%s compiler=%s" % (archConfig, compilers[ic])
1256 else:
1257 configString = archConfig
1258
Johnny Chenb40056b2010-09-21 00:09:27 +00001259 if iterArchs or iterCompilers:
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001260 # Translate ' ' to '-' for pathname component.
1261 from string import maketrans
1262 tbl = maketrans(' ', '-')
1263 configPostfix = configString.translate(tbl)
1264
1265 # Check whether we need to split stderr/stdout into configuration
1266 # specific files.
1267 if old_stderr.name != '<stderr>' and config.get('split_stderr'):
1268 if new_stderr:
1269 new_stderr.close()
1270 new_stderr = open("%s.%s" % (old_stderr.name, configPostfix), "w")
1271 sys.stderr = new_stderr
1272 if old_stdout.name != '<stdout>' and config.get('split_stdout'):
1273 if new_stdout:
1274 new_stdout.close()
1275 new_stdout = open("%s.%s" % (old_stdout.name, configPostfix), "w")
1276 sys.stdout = new_stdout
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001277
Johnny Chen953864a2010-10-12 21:35:54 +00001278 # If we specified a relocated directory to run the test suite, do
1279 # the extra housekeeping to copy the testdirs to a configStringified
1280 # directory and to update sys.path before invoking the test runner.
1281 # The purpose is to separate the configuration-specific directories
1282 # from each other.
1283 if rdir:
Johnny Chen3bc7e5e2012-04-24 21:44:10 +00001284 from shutil import copytree, rmtree, ignore_patterns
Johnny Chen953864a2010-10-12 21:35:54 +00001285
Johnny Chen953864a2010-10-12 21:35:54 +00001286 newrdir = "%s.%s" % (rdir, configPostfix)
1287
1288 # Copy the tree to a new directory with postfix name configPostfix.
Johnny Chen3bc7e5e2012-04-24 21:44:10 +00001289 if os.path.exists(newrdir):
1290 rmtree(newrdir)
Johnny Chen953864a2010-10-12 21:35:54 +00001291 copytree(rdir, newrdir, ignore=ignore_patterns('*.pyc', '*.o', '*.d'))
1292
Filipe Cabecinhas0e1d06d2012-08-08 15:23:24 +00001293 # Update the LLDB_TEST environment variable to reflect new top
Johnny Chen953864a2010-10-12 21:35:54 +00001294 # level test directory.
1295 #
1296 # See also lldbtest.TestBase.setUpClass(cls).
1297 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
1298 os.environ["LLDB_TEST"] = os.path.join(newrdir, 'test')
1299 else:
1300 os.environ["LLDB_TEST"] = newrdir
1301
1302 # And update the Python search paths for modules.
1303 sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
1304
1305 # Output the configuration.
Daniel Malea361eb432013-02-15 21:31:37 +00001306 if not parsable:
1307 sys.stderr.write("\nConfiguration: " + configString + "\n")
Johnny Chen953864a2010-10-12 21:35:54 +00001308
1309 #print "sys.stderr name is", sys.stderr.name
1310 #print "sys.stdout name is", sys.stdout.name
1311
1312 # First, write out the number of collected test cases.
Daniel Malea361eb432013-02-15 21:31:37 +00001313 if not parsable:
1314 sys.stderr.write(separator + "\n")
1315 sys.stderr.write("Collected %d test%s\n\n"
1316 % (suite.countTestCases(),
1317 suite.countTestCases() != 1 and "s" or ""))
Johnny Chen953864a2010-10-12 21:35:54 +00001318
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001319 class LLDBTestResult(unittest2.TextTestResult):
1320 """
Johnny Chen26be4532010-11-09 23:56:14 +00001321 Enforce a singleton pattern to allow introspection of test progress.
1322
1323 Overwrite addError(), addFailure(), and addExpectedFailure() methods
1324 to enable each test instance to track its failure/error status. It
1325 is used in the LLDB test framework to emit detailed trace messages
1326 to a log file for easier human inspection of test failres/errors.
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001327 """
1328 __singleton__ = None
Johnny Chen360dd372010-11-29 17:50:10 +00001329 __ignore_singleton__ = False
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001330
Enrico Granatabc0c5a62013-02-08 23:39:18 +00001331 @staticmethod
1332 def getTerminalSize():
1333 import os
1334 env = os.environ
1335 def ioctl_GWINSZ(fd):
1336 try:
1337 import fcntl, termios, struct, os
1338 cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
1339 '1234'))
1340 except:
1341 return
1342 return cr
1343 cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
1344 if not cr:
1345 try:
1346 fd = os.open(os.ctermid(), os.O_RDONLY)
1347 cr = ioctl_GWINSZ(fd)
1348 os.close(fd)
1349 except:
1350 pass
1351 if not cr:
1352 cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
1353 return int(cr[1]), int(cr[0])
1354
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001355 def __init__(self, *args):
Johnny Chen360dd372010-11-29 17:50:10 +00001356 if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
Johnny Chend2acdb32010-11-16 22:42:58 +00001357 raise Exception("LLDBTestResult instantiated more than once")
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001358 super(LLDBTestResult, self).__init__(*args)
1359 LLDBTestResult.__singleton__ = self
1360 # Now put this singleton into the lldb module namespace.
1361 lldb.test_result = self
Johnny Chen810042e2011-01-05 20:24:11 +00001362 # Computes the format string for displaying the counter.
1363 global suite
1364 counterWidth = len(str(suite.countTestCases()))
1365 self.fmt = "%" + str(counterWidth) + "d: "
Johnny Chenc87fd492011-01-05 22:50:11 +00001366 self.indentation = ' ' * (counterWidth + 2)
Johnny Chen810042e2011-01-05 20:24:11 +00001367 # This counts from 1 .. suite.countTestCases().
1368 self.counter = 0
Enrico Granatabc0c5a62013-02-08 23:39:18 +00001369 (width, height) = LLDBTestResult.getTerminalSize()
Enrico Granata77215892013-02-15 00:32:05 +00001370 self.progressbar = None
Jim Ingham75f260a2013-02-19 20:39:27 +00001371 global progress_bar
Daniel Malea361eb432013-02-15 21:31:37 +00001372 if width > 10 and not parsable and progress_bar:
Enrico Granata77215892013-02-15 00:32:05 +00001373 try:
1374 self.progressbar = progress.ProgressWithEvents(stdout=self.stream,start=0,end=suite.countTestCases(),width=width-10)
1375 except:
1376 self.progressbar = None
Johnny Chen810042e2011-01-05 20:24:11 +00001377
Daniel Malea361eb432013-02-15 21:31:37 +00001378 def _config_string(self, test):
1379 compiler = getattr(test, "getCompiler", None)
1380 arch = getattr(test, "getArchitecture", None)
1381 return "%s-%s" % (compiler() if compiler else "", arch() if arch else "")
1382
Johnny Chenbe452272012-04-19 21:33:55 +00001383 def _exc_info_to_string(self, err, test):
1384 """Overrides superclass TestResult's method in order to append
1385 our test config info string to the exception info string."""
1386 modified_exc_string = '%sConfig=%s-%s' % (super(LLDBTestResult, self)._exc_info_to_string(err, test),
1387 test.getArchitecture(),
1388 test.getCompiler())
1389 return modified_exc_string
1390
Johnny Chenc87fd492011-01-05 22:50:11 +00001391 def getDescription(self, test):
1392 doc_first_line = test.shortDescription()
1393 if self.descriptions and doc_first_line:
1394 return '\n'.join((str(test), self.indentation + doc_first_line))
1395 else:
1396 return str(test)
1397
Enrico Granataac3a8e22012-09-21 19:10:53 +00001398 def getCategoriesForTest(self,test):
Enrico Granata56e2c562013-02-27 02:37:12 +00001399 if hasattr(test,"_testMethodName"):
1400 test_method = getattr(test,"_testMethodName")
1401 test_method = getattr(test,test_method)
1402 else:
1403 test_method = None
1404 if test_method != None and hasattr(test_method,"getCategories"):
1405 test_categories = test_method.getCategories(test)
1406 elif hasattr(test,"getCategories"):
Enrico Granataac3a8e22012-09-21 19:10:53 +00001407 test_categories = test.getCategories()
1408 elif inspect.ismethod(test) and test.__self__ != None and hasattr(test.__self__,"getCategories"):
1409 test_categories = test.__self__.getCategories()
1410 else:
1411 test_categories = []
1412 if test_categories == None:
1413 test_categories = []
1414 return test_categories
1415
1416 def shouldSkipBecauseOfCategories(self,test):
1417 global useCategories
1418 import inspect
1419 if useCategories:
1420 global categoriesList
1421 test_categories = self.getCategoriesForTest(test)
1422 if len(test_categories) == 0 or len(categoriesList & set(test_categories)) == 0:
1423 return True
1424 return False
1425
1426 def hardMarkAsSkipped(self,test):
1427 getattr(test, test._testMethodName).__func__.__unittest_skip__ = True
1428 getattr(test, test._testMethodName).__func__.__unittest_skip_why__ = "test case does not fall in any category of interest for this run"
1429
Johnny Chen810042e2011-01-05 20:24:11 +00001430 def startTest(self, test):
Enrico Granataac3a8e22012-09-21 19:10:53 +00001431 if self.shouldSkipBecauseOfCategories(test):
1432 self.hardMarkAsSkipped(test)
Johnny Chen810042e2011-01-05 20:24:11 +00001433 self.counter += 1
1434 if self.showAll:
1435 self.stream.write(self.fmt % self.counter)
1436 super(LLDBTestResult, self).startTest(test)
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001437
Daniel Malea361eb432013-02-15 21:31:37 +00001438 def addSuccess(self, test):
1439 global parsable
1440 super(LLDBTestResult, self).addSuccess(test)
1441 if parsable:
1442 self.stream.write("PASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1443
Johnny Chence681462010-10-19 00:25:01 +00001444 def addError(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001445 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001446 global parsable
Johnny Chen63c2cba2010-10-29 22:20:36 +00001447 sdir_has_content = True
Johnny Chence681462010-10-19 00:25:01 +00001448 super(LLDBTestResult, self).addError(test, err)
1449 method = getattr(test, "markError", None)
1450 if method:
1451 method()
Daniel Malea361eb432013-02-15 21:31:37 +00001452 if parsable:
Daniel Maleae1dd3e52013-03-07 18:39:26 +00001453 self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
Johnny Chence681462010-10-19 00:25:01 +00001454
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001455 def addFailure(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001456 global sdir_has_content
Enrico Granataac3a8e22012-09-21 19:10:53 +00001457 global failuresPerCategory
Daniel Malea361eb432013-02-15 21:31:37 +00001458 global parsable
Johnny Chen63c2cba2010-10-29 22:20:36 +00001459 sdir_has_content = True
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001460 super(LLDBTestResult, self).addFailure(test, err)
1461 method = getattr(test, "markFailure", None)
1462 if method:
1463 method()
Daniel Malea361eb432013-02-15 21:31:37 +00001464 if parsable:
1465 self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
Enrico Granataac3a8e22012-09-21 19:10:53 +00001466 if useCategories:
1467 test_categories = self.getCategoriesForTest(test)
1468 for category in test_categories:
1469 if category in failuresPerCategory:
1470 failuresPerCategory[category] = failuresPerCategory[category] + 1
1471 else:
1472 failuresPerCategory[category] = 1
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001473
Enrico Granata21416a12013-02-23 01:05:23 +00001474 def addExpectedFailure(self, test, err, bugnumber):
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001475 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001476 global parsable
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001477 sdir_has_content = True
Enrico Granata21416a12013-02-23 01:05:23 +00001478 super(LLDBTestResult, self).addExpectedFailure(test, err, bugnumber)
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001479 method = getattr(test, "markExpectedFailure", None)
1480 if method:
Enrico Granata21416a12013-02-23 01:05:23 +00001481 method(err, bugnumber)
Daniel Malea361eb432013-02-15 21:31:37 +00001482 if parsable:
1483 self.stream.write("XFAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001484
Johnny Chenf5b89092011-08-15 23:09:08 +00001485 def addSkip(self, test, reason):
1486 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001487 global parsable
Johnny Chenf5b89092011-08-15 23:09:08 +00001488 sdir_has_content = True
1489 super(LLDBTestResult, self).addSkip(test, reason)
1490 method = getattr(test, "markSkippedTest", None)
1491 if method:
1492 method()
Daniel Malea361eb432013-02-15 21:31:37 +00001493 if parsable:
1494 self.stream.write("UNSUPPORTED: LLDB (%s) :: %s (%s) \n" % (self._config_string(test), str(test), reason))
Johnny Chenf5b89092011-08-15 23:09:08 +00001495
Enrico Granata21416a12013-02-23 01:05:23 +00001496 def addUnexpectedSuccess(self, test, bugnumber):
Johnny Chenab2f0662011-05-06 20:30:22 +00001497 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001498 global parsable
Johnny Chenab2f0662011-05-06 20:30:22 +00001499 sdir_has_content = True
Enrico Granata21416a12013-02-23 01:05:23 +00001500 super(LLDBTestResult, self).addUnexpectedSuccess(test, bugnumber)
Johnny Chenab2f0662011-05-06 20:30:22 +00001501 method = getattr(test, "markUnexpectedSuccess", None)
1502 if method:
Enrico Granata21416a12013-02-23 01:05:23 +00001503 method(bugnumber)
Daniel Malea361eb432013-02-15 21:31:37 +00001504 if parsable:
1505 self.stream.write("XPASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1506
1507 if parsable:
1508 v = 0
1509 elif progress_bar:
1510 v = 1
1511 else:
1512 v = verbose
Johnny Chenab2f0662011-05-06 20:30:22 +00001513
Johnny Chen26be4532010-11-09 23:56:14 +00001514 # Invoke the test runner.
Johnny Chend2acdb32010-11-16 22:42:58 +00001515 if count == 1:
Johnny Chen7d6d8442010-12-03 19:59:35 +00001516 result = unittest2.TextTestRunner(stream=sys.stderr,
Daniel Malea361eb432013-02-15 21:31:37 +00001517 verbosity=v,
Johnny Chen7d6d8442010-12-03 19:59:35 +00001518 failfast=failfast,
Johnny Chend2acdb32010-11-16 22:42:58 +00001519 resultclass=LLDBTestResult).run(suite)
1520 else:
Johnny Chend6e7ca22010-11-29 17:52:43 +00001521 # We are invoking the same test suite more than once. In this case,
1522 # mark __ignore_singleton__ flag as True so the signleton pattern is
1523 # not enforced.
Johnny Chen360dd372010-11-29 17:50:10 +00001524 LLDBTestResult.__ignore_singleton__ = True
Johnny Chend2acdb32010-11-16 22:42:58 +00001525 for i in range(count):
Daniel Malea361eb432013-02-15 21:31:37 +00001526
Johnny Chen7d6d8442010-12-03 19:59:35 +00001527 result = unittest2.TextTestRunner(stream=sys.stderr,
Daniel Malea361eb432013-02-15 21:31:37 +00001528 verbosity=v,
Johnny Chen7d6d8442010-12-03 19:59:35 +00001529 failfast=failfast,
Johnny Chen360dd372010-11-29 17:50:10 +00001530 resultclass=LLDBTestResult).run(suite)
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001531
Daniel Malea24765572013-02-20 20:12:11 +00001532 failed = failed or not result.wasSuccessful()
Johnny Chen1bfbd412010-06-29 19:44:16 +00001533
Daniel Malea361eb432013-02-15 21:31:37 +00001534if sdir_has_content and not parsable:
Johnny Chenab2f0662011-05-06 20:30:22 +00001535 sys.stderr.write("Session logs for test failures/errors/unexpected successes"
1536 " can be found in directory '%s'\n" % sdir_name)
Johnny Chen63c2cba2010-10-29 22:20:36 +00001537
Enrico Granataac3a8e22012-09-21 19:10:53 +00001538if useCategories and len(failuresPerCategory) > 0:
1539 sys.stderr.write("Failures per category:\n")
1540 for category in failuresPerCategory:
1541 sys.stderr.write("%s - %d\n" % (category,failuresPerCategory[category]))
1542
Johnny Chena73ad662012-08-16 19:15:21 +00001543fname = os.path.join(sdir_name, "TestFinished")
1544with open(fname, "w") as f:
1545 print >> f, "Test finished at: %s\n" % datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
1546
Johnny Chencd0279d2010-09-20 18:07:50 +00001547# Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1548# This should not be necessary now.
Johnny Chen83f6e512010-08-13 22:58:44 +00001549if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
Johnny Chen83f6e512010-08-13 22:58:44 +00001550 print "Terminating Test suite..."
1551 subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1552
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001553# Exiting.
Daniel Malea24765572013-02-20 20:12:11 +00001554sys.exit(failed)