blob: 9bf1cbad557465f5ff61eacb6145a19e1902f2f7 [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
Enrico Granata69d7c102013-05-07 00:36:28 +0000321def unique_string_match(yourentry,list):
322 candidate = None
323 for item in list:
324 if item.startswith(yourentry):
325 if candidate:
326 return None
327 candidate = item
328 return candidate
329
Johnny Chenaf149a02010-09-16 17:11:30 +0000330def parseOptionsAndInitTestdirs():
331 """Initialize the list of directories containing our unittest scripts.
332
333 '-h/--help as the first option prints out usage info and exit the program.
334 """
335
Johnny Chen4f93bf12010-12-10 00:51:23 +0000336 global dont_do_python_api_test
337 global just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000338 global just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +0000339 global dont_do_dsym_test
340 global dont_do_dwarf_test
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000341 global blacklist
342 global blacklistConfig
Enrico Granataac3a8e22012-09-21 19:10:53 +0000343 global categoriesList
344 global validCategories
345 global useCategories
Sean Callanan0acf4c62012-10-24 22:45:39 +0000346 global lldbFrameworkPath
347 global lldbExecutablePath
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000348 global configFile
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000349 global archs
350 global compilers
Johnny Chend2acdb32010-11-16 22:42:58 +0000351 global count
Johnny Chenaf149a02010-09-16 17:11:30 +0000352 global delay
Johnny Chen50bc6382011-01-29 01:16:52 +0000353 global dumpSysPath
Johnny Chene00c9302011-10-10 22:03:44 +0000354 global bmExecutable
355 global bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000356 global bmIterationCount
Johnny Chen7d6d8442010-12-03 19:59:35 +0000357 global failfast
Johnny Chenc5fa0052011-07-29 22:54:56 +0000358 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000359 global fs4all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000360 global ignore
Johnny Chen08967192011-11-18 00:19:29 +0000361 global progress_bar
Johnny Chen38f823c2011-10-11 01:30:27 +0000362 global runHooks
Johnny Chen028d8eb2011-11-17 19:57:27 +0000363 global skip_build_and_cleanup
364 global skip_long_running_test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000365 global noHeaders
Daniel Malea361eb432013-02-15 21:31:37 +0000366 global parsable
Johnny Chen7c52ff12010-09-27 23:29:54 +0000367 global regexp
Johnny Chen548aefd2010-10-11 22:25:46 +0000368 global rdir
Johnny Chen125fc2b2010-10-21 16:55:35 +0000369 global sdir_name
Enrico Granata814c8132013-04-11 23:48:00 +0000370 global svn_silent
Johnny Chenaf149a02010-09-16 17:11:30 +0000371 global verbose
372 global testdirs
373
Jim Ingham4f347cb2011-04-13 21:11:41 +0000374 do_help = False
375
Greg Clayton4793e942012-09-04 15:42:49 +0000376 parser = argparse.ArgumentParser(description='description', prefix_chars='+-', add_help=False)
377 group = None
Johnny Chenaf149a02010-09-16 17:11:30 +0000378
Greg Clayton4793e942012-09-04 15:42:49 +0000379 # Helper function for boolean options (group will point to the current group when executing X)
380 X = lambda optstr, helpstr, **kwargs: group.add_argument(optstr, help=helpstr, action='store_true', **kwargs)
381
382 group = parser.add_argument_group('Help')
383 group.add_argument('-h', '--help', dest='h', action='store_true', help="Print this help message and exit. Add '-v' for more detailed help.")
384
385 # C and Python toolchain options
386 group = parser.add_argument_group('Toolchain options')
387 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'''))
388 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.'''))
389 # FIXME? This won't work for different extra flags according to each arch.
390 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
391 suggestions: do not lump the "-A arch1 -A arch2" together such that the -E option applies to only one of the architectures'''))
392 X('-D', 'Dump the Python sys.path variable')
393
394 # Test filtering options
395 group = parser.add_argument_group('Test filtering options')
396 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")
397 X('-a', "Don't do lldb Python API tests")
398 X('+a', "Just do lldb Python API tests. Do not specify along with '+a'", dest='plus_a')
399 X('+b', 'Just do benchmark tests', dest='plus_b')
400 group.add_argument('-b', metavar='blacklist', help='Read a blacklist file specified after this option')
Enrico Granata58b03a42012-12-14 00:07:09 +0000401 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 +0000402 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')
403 X('-l', "Don't skip long running tests")
404 group.add_argument('-p', metavar='pattern', help='Specify a regexp filename pattern for inclusion in the test suite')
405 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 +0000406 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 +0000407
408 # Configuration options
409 group = parser.add_argument_group('Configuration options')
410 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 +0000411 group.add_argument('--framework', metavar='framework-path', help='The path to LLDB.framework')
412 group.add_argument('--executable', metavar='executable-path', help='The path to the lldb executable')
Greg Clayton4793e942012-09-04 15:42:49 +0000413 group.add_argument('-e', metavar='benchmark-exe', help='Specify the full path of an executable used for benchmark purposes (see also: -x)')
414 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")
415 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')
416 group.add_argument('-r', metavar='dir', help="Similar to '-R', except that the directory must not exist before running this test driver")
417 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')
418 group.add_argument('-x', metavar='breakpoint-spec', help='Specify the breakpoint specification for the benchmark executable')
419 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.")
420 group.add_argument('-#', type=int, metavar='sharp', dest='sharp', help='Repeat the test suite for a specified number of times')
421
422 # Test-suite behaviour
423 group = parser.add_argument_group('Runtime behaviour options')
424 X('-d', 'Delay startup for 10 seconds (in order for the debugger to attach)')
425 X('-F', 'Fail fast. Stop the test suite on the first error/failure')
426 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")
427 X('-n', "Don't print the headers like build dir, lldb version, and svn info at all")
Jim Ingham75f260a2013-02-19 20:39:27 +0000428 X('-P', "Use the graphic progress bar.")
Daniel Malea361eb432013-02-15 21:31:37 +0000429 X('-q', "Don't print extra output from this script.")
Greg Clayton4793e942012-09-04 15:42:49 +0000430 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")
431 X('-t', 'Turn on tracing of lldb command and other detailed test executions')
Greg Claytonb85785c2013-02-08 21:52:32 +0000432 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 +0000433 X('-v', 'Do verbose mode of unittest framework (print out each test case invocation)')
434 X('-w', 'Insert some wait time (currently 0.5 sec) between consecutive test cases')
Enrico Granata814c8132013-04-11 23:48:00 +0000435 X('-T', 'Obtain and dump svn information for this checkout of LLDB (off by default)')
Greg Clayton4793e942012-09-04 15:42:49 +0000436
437 # Remove the reference to our helper function
438 del X
439
440 group = parser.add_argument_group('Test directories')
441 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.')
442 args = parser.parse_args()
443
444 platform_system = platform.system()
445 platform_machine = platform.machine()
Enrico Granata2d329242012-10-23 22:52:49 +0000446
Greg Claytonb85785c2013-02-08 21:52:32 +0000447 if args.unset_env_varnames:
448 for env_var in args.unset_env_varnames:
449 if env_var in os.environ:
450 # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
451 # is automatically translated into a corresponding call to unsetenv().
452 del os.environ[env_var]
453 #os.unsetenv(env_var)
454
Daniel Malea361eb432013-02-15 21:31:37 +0000455 # only print the args if being verbose (and parsable is off)
456 if args.v and not args.q:
Enrico Granata2d329242012-10-23 22:52:49 +0000457 print args
Greg Clayton4793e942012-09-04 15:42:49 +0000458
459 if args.h:
460 do_help = True
461
462 if args.archs:
463 archs = args.archs
464 else:
465 if platform_system == 'Darwin' and platform_machine == 'x86_64':
466 archs = ['x86_64', 'i386']
Johnny Chenaf149a02010-09-16 17:11:30 +0000467 else:
Greg Clayton4793e942012-09-04 15:42:49 +0000468 archs = [platform_machine]
469
Enrico Granataac3a8e22012-09-21 19:10:53 +0000470 if args.categoriesList:
Enrico Granata69d7c102013-05-07 00:36:28 +0000471 finalCategoriesList = []
Enrico Granataac3a8e22012-09-21 19:10:53 +0000472 for category in args.categoriesList:
Enrico Granata69d7c102013-05-07 00:36:28 +0000473 origCategory = category
Enrico Granataac3a8e22012-09-21 19:10:53 +0000474 if not(category in validCategories):
Enrico Granata69d7c102013-05-07 00:36:28 +0000475 category = unique_string_match(category,validCategories)
476 if not(category in validCategories) or category == None:
477 print "fatal error: category '" + origCategory + "' is not a valid category"
Enrico Granata2d329242012-10-23 22:52:49 +0000478 print "if you have added a new category, please edit dotest.py, adding your new category to validCategories"
479 print "else, please specify one or more of the following: " + str(validCategories.keys())
Enrico Granataac3a8e22012-09-21 19:10:53 +0000480 sys.exit(1)
Enrico Granata69d7c102013-05-07 00:36:28 +0000481 finalCategoriesList.append(category)
482 categoriesList = set(finalCategoriesList)
Enrico Granataac3a8e22012-09-21 19:10:53 +0000483 useCategories = True
484 else:
485 categoriesList = []
486
Greg Clayton4793e942012-09-04 15:42:49 +0000487 if args.compilers:
488 compilers = args.compilers
489 else:
490 compilers = ['clang']
491
492 if args.D:
493 dumpSysPath = True
494
495 if args.E:
496 cflags_extras = args.E
497 os.environ['CFLAGS_EXTRAS'] = cflags_extras
498
499 # argparse makes sure we have correct options
500 if args.N == 'dwarf':
501 dont_do_dwarf_test = True
502 elif args.N == 'dsym':
503 dont_do_dsym_test = True
504
505 if args.a:
506 dont_do_python_api_test = True
507
508 if args.plus_a:
509 if dont_do_python_api_test:
510 print "Warning: -a and +a can't both be specified! Using only -a"
511 else:
512 just_do_python_api_test = True
513
514 if args.plus_b:
515 just_do_benchmarks_test = True
516
517 if args.b:
518 if args.b.startswith('-'):
519 usage(parser)
520 blacklistFile = args.b
521 if not os.path.isfile(blacklistFile):
522 print 'Blacklist file:', blacklistFile, 'does not exist!'
523 usage(parser)
524 # Now read the blacklist contents and assign it to blacklist.
525 execfile(blacklistFile, globals(), blacklistConfig)
526 blacklist = blacklistConfig.get('blacklist')
527
528 if args.c:
529 if args.c.startswith('-'):
530 usage(parser)
531 configFile = args.c
532 if not os.path.isfile(configFile):
533 print 'Config file:', configFile, 'does not exist!'
534 usage(parser)
535
536 if args.d:
537 delay = True
538
539 if args.e:
540 if args.e.startswith('-'):
541 usage(parser)
542 bmExecutable = args.e
543 if not is_exe(bmExecutable):
544 usage(parser)
545
546 if args.F:
547 failfast = True
548
549 if args.f:
Enrico Granata58b03a42012-12-14 00:07:09 +0000550 if any([x.startswith('-') for x in args.f]):
Greg Clayton4793e942012-09-04 15:42:49 +0000551 usage(parser)
Enrico Granata58b03a42012-12-14 00:07:09 +0000552 filters.extend(args.f)
Greg Clayton4793e942012-09-04 15:42:49 +0000553
554 if args.g:
555 fs4all = False
556
557 if args.i:
558 ignore = True
559
560 if args.k:
561 runHooks.extend(args.k)
562
563 if args.l:
564 skip_long_running_test = False
565
Sean Callanan0acf4c62012-10-24 22:45:39 +0000566 if args.framework:
567 lldbFrameworkPath = args.framework
568
569 if args.executable:
570 lldbExecutablePath = args.executable
571
Greg Clayton4793e942012-09-04 15:42:49 +0000572 if args.n:
573 noHeaders = True
574
575 if args.p:
576 if args.p.startswith('-'):
577 usage(parser)
578 regexp = args.p
579
Daniel Malea361eb432013-02-15 21:31:37 +0000580 if args.q:
581 noHeaders = True
582 parsable = True
583
Jim Ingham75f260a2013-02-19 20:39:27 +0000584 if args.P:
585 progress_bar = True
586 verbose = 0
587
Greg Clayton4793e942012-09-04 15:42:49 +0000588 if args.R:
589 if args.R.startswith('-'):
590 usage(parser)
591 rdir = os.path.abspath(args.R)
592 if os.path.exists(rdir):
593 import shutil
594 print 'Removing tree:', rdir
595 shutil.rmtree(rdir)
596
597 if args.r:
598 if args.r.startswith('-'):
599 usage(parser)
600 rdir = os.path.abspath(args.r)
601 if os.path.exists(rdir):
602 print 'Relocated directory:', rdir, 'must not exist!'
603 usage(parser)
604
605 if args.S:
606 skip_build_and_cleanup = True
607
608 if args.s:
609 if args.s.startswith('-'):
610 usage(parser)
611 sdir_name = args.s
612
613 if args.t:
614 os.environ['LLDB_COMMAND_TRACE'] = 'YES'
615
Enrico Granata814c8132013-04-11 23:48:00 +0000616 if args.T:
617 svn_silent = False
618
Greg Clayton4793e942012-09-04 15:42:49 +0000619 if args.v:
620 verbose = 2
621
622 if args.w:
623 os.environ['LLDB_WAIT_BETWEEN_TEST_CASES'] = 'YES'
624
625 if args.X:
626 if args.X.startswith('-'):
627 usage(parser)
628 excluded.add(args.X)
629
630 if args.x:
631 if args.x.startswith('-'):
632 usage(parser)
633 bmBreakpointSpec = args.x
634
635 # argparse makes sure we have a number
636 if args.y:
637 bmIterationCount = args.y
638
639 # argparse makes sure we have a number
640 if args.sharp:
641 count = args.sharp
Johnny Chenaf149a02010-09-16 17:11:30 +0000642
Jim Ingham4f347cb2011-04-13 21:11:41 +0000643 if do_help == True:
Greg Clayton4793e942012-09-04 15:42:49 +0000644 usage(parser)
Jim Ingham4f347cb2011-04-13 21:11:41 +0000645
Johnny Chencc659ad2010-12-10 19:02:23 +0000646 # Do not specify both '-a' and '+a' at the same time.
647 if dont_do_python_api_test and just_do_python_api_test:
Greg Clayton4793e942012-09-04 15:42:49 +0000648 usage(parser)
Johnny Chencc659ad2010-12-10 19:02:23 +0000649
Johnny Chenaf149a02010-09-16 17:11:30 +0000650 # Gather all the dirs passed on the command line.
Greg Clayton4793e942012-09-04 15:42:49 +0000651 if len(args.args) > 0:
652 testdirs = map(os.path.abspath, args.args)
Johnny Chenaf149a02010-09-16 17:11:30 +0000653
Johnny Chen548aefd2010-10-11 22:25:46 +0000654 # If '-r dir' is specified, the tests should be run under the relocated
655 # directory. Let's copy the testdirs over.
656 if rdir:
657 from shutil import copytree, ignore_patterns
658
659 tmpdirs = []
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000660 orig_testdirs = testdirs[:]
Johnny Chen548aefd2010-10-11 22:25:46 +0000661 for srcdir in testdirs:
Johnny Chen1abe4c02012-03-20 00:33:51 +0000662 # For example, /Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/hello_watchpoint
663 # shall be split into ['/Volumes/data/lldb/svn/ToT/', 'functionalities/watchpoint/hello_watchpoint'].
664 # Utilize the relative path to the 'test' directory to make our destination dir path.
Greg Clayton4793e942012-09-04 15:42:49 +0000665 if ("test" + os.sep) in srcdir:
666 to_split_on = "test" + os.sep
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000667 else:
668 to_split_on = "test"
669 dstdir = os.path.join(rdir, srcdir.split(to_split_on)[1])
670 dstdir = dstdir.rstrip(os.sep)
Johnny Chen548aefd2010-10-11 22:25:46 +0000671 # Don't copy the *.pyc and .svn stuffs.
672 copytree(srcdir, dstdir, ignore=ignore_patterns('*.pyc', '.svn'))
673 tmpdirs.append(dstdir)
674
675 # This will be our modified testdirs.
676 testdirs = tmpdirs
677
678 # With '-r dir' specified, there's no cleanup of intermediate test files.
679 os.environ["LLDB_DO_CLEANUP"] = 'NO'
680
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000681 # If the original testdirs is ['test'], the make directory has already been copied
Johnny Chen548aefd2010-10-11 22:25:46 +0000682 # recursively and is contained within the rdir/test dir. For anything
683 # else, we would need to copy over the make directory and its contents,
684 # so that, os.listdir(rdir) looks like, for example:
685 #
686 # array_types conditional_break make
687 #
688 # where the make directory contains the Makefile.rules file.
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000689 if len(testdirs) != 1 or os.path.basename(orig_testdirs[0]) != 'test':
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000690 scriptdir = os.path.dirname(__file__)
Johnny Chen548aefd2010-10-11 22:25:46 +0000691 # Don't copy the .svn stuffs.
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000692 copytree(os.path.join(scriptdir, 'make'), os.path.join(rdir, 'make'),
Johnny Chen548aefd2010-10-11 22:25:46 +0000693 ignore=ignore_patterns('.svn'))
694
695 #print "testdirs:", testdirs
696
Johnny Chenb40056b2010-09-21 00:09:27 +0000697 # Source the configFile if specified.
698 # The side effect, if any, will be felt from this point on. An example
699 # config file may be these simple two lines:
700 #
701 # sys.stderr = open("/tmp/lldbtest-stderr", "w")
702 # sys.stdout = open("/tmp/lldbtest-stdout", "w")
703 #
704 # which will reassign the two file objects to sys.stderr and sys.stdout,
705 # respectively.
706 #
Johnny Chen8c130642012-08-22 17:53:02 +0000707 # See also lldb-trunk/examples/test/usage-config.
Johnny Chenac97a6b2012-04-16 18:55:15 +0000708 global config, pre_flight, post_flight
Johnny Chenb40056b2010-09-21 00:09:27 +0000709 if configFile:
710 # Pass config (a dictionary) as the locals namespace for side-effect.
711 execfile(configFile, globals(), config)
Johnny Chenac97a6b2012-04-16 18:55:15 +0000712 print "config:", config
713 if "pre_flight" in config:
714 pre_flight = config["pre_flight"]
715 if not callable(pre_flight):
716 print "fatal error: pre_flight is not callable, exiting."
717 sys.exit(1)
718 if "post_flight" in config:
719 post_flight = config["post_flight"]
720 if not callable(post_flight):
721 print "fatal error: post_flight is not callable, exiting."
722 sys.exit(1)
Johnny Chenb40056b2010-09-21 00:09:27 +0000723 #print "sys.stderr:", sys.stderr
724 #print "sys.stdout:", sys.stdout
725
Johnny Chenaf149a02010-09-16 17:11:30 +0000726
Johnny Chen9707bb62010-06-25 21:14:08 +0000727def setupSysPath():
Johnny Chen8a3c0432011-03-11 20:13:06 +0000728 """
729 Add LLDB.framework/Resources/Python to the search paths for modules.
730 As a side effect, we also discover the 'lldb' executable and export it here.
731 """
Johnny Chen9707bb62010-06-25 21:14:08 +0000732
Johnny Chen548aefd2010-10-11 22:25:46 +0000733 global rdir
734 global testdirs
Johnny Chen50bc6382011-01-29 01:16:52 +0000735 global dumpSysPath
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000736 global noHeaders
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000737 global svn_info
Enrico Granata814c8132013-04-11 23:48:00 +0000738 global svn_silent
Sean Callanan0acf4c62012-10-24 22:45:39 +0000739 global lldbFrameworkPath
740 global lldbExecutablePath
Johnny Chen548aefd2010-10-11 22:25:46 +0000741
Johnny Chen9707bb62010-06-25 21:14:08 +0000742 # Get the directory containing the current script.
Johnny Chen4d162e52011-08-12 18:54:11 +0000743 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 +0000744 scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
745 else:
746 scriptPath = sys.path[0]
Johnny Chena1affab2010-07-03 03:41:59 +0000747 if not scriptPath.endswith('test'):
Johnny Chen9707bb62010-06-25 21:14:08 +0000748 print "This script expects to reside in lldb's test directory."
749 sys.exit(-1)
750
Johnny Chen548aefd2010-10-11 22:25:46 +0000751 if rdir:
752 # Set up the LLDB_TEST environment variable appropriately, so that the
753 # individual tests can be located relatively.
754 #
755 # See also lldbtest.TestBase.setUpClass(cls).
756 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
757 os.environ["LLDB_TEST"] = os.path.join(rdir, 'test')
758 else:
759 os.environ["LLDB_TEST"] = rdir
760 else:
761 os.environ["LLDB_TEST"] = scriptPath
Peter Collingbournef6c3de82011-06-20 19:06:45 +0000762
763 # Set up the LLDB_SRC environment variable, so that the tests can locate
764 # the LLDB source code.
765 os.environ["LLDB_SRC"] = os.path.join(sys.path[0], os.pardir)
766
Johnny Chen9de4ede2010-08-31 17:42:54 +0000767 pluginPath = os.path.join(scriptPath, 'plugins')
Johnny Chen8a3c0432011-03-11 20:13:06 +0000768 pexpectPath = os.path.join(scriptPath, 'pexpect-2.4')
Johnny Chen58f93922010-06-29 23:10:39 +0000769
Johnny Chen8a3c0432011-03-11 20:13:06 +0000770 # Append script dir, plugin dir, and pexpect dir to the sys.path.
Johnny Chenaf149a02010-09-16 17:11:30 +0000771 sys.path.append(scriptPath)
772 sys.path.append(pluginPath)
Johnny Chen8a3c0432011-03-11 20:13:06 +0000773 sys.path.append(pexpectPath)
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000774
Johnny Chen26901c82011-03-11 19:47:23 +0000775 # This is our base name component.
Johnny Chena1affab2010-07-03 03:41:59 +0000776 base = os.path.abspath(os.path.join(scriptPath, os.pardir))
Johnny Chen6a564a42011-02-15 18:50:19 +0000777
Johnny Chen26901c82011-03-11 19:47:23 +0000778 # These are for xcode build directories.
Johnny Chen6a564a42011-02-15 18:50:19 +0000779 xcode3_build_dir = ['build']
780 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
781 dbg = ['Debug']
Sean Callanand9d94632012-09-26 21:16:15 +0000782 dbc = ['DebugClang']
Johnny Chen6a564a42011-02-15 18:50:19 +0000783 rel = ['Release']
784 bai = ['BuildAndIntegration']
785 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
Johnny Chen26901c82011-03-11 19:47:23 +0000786
787 # Some of the tests can invoke the 'lldb' command directly.
788 # We'll try to locate the appropriate executable right here.
789
Sean Callanan0acf4c62012-10-24 22:45:39 +0000790 lldbExec = None
791 if lldbExecutablePath:
792 if is_exe(lldbExecutablePath):
793 lldbExec = lldbExecutablePath
Sean Callanan502000d2012-11-01 21:23:21 +0000794 lldbHere = lldbExec
Sean Callanan0acf4c62012-10-24 22:45:39 +0000795 else:
796 print lldbExecutablePath + " is not an executable"
797 sys.exit(-1)
Johnny Chen6033bed2011-08-26 00:00:01 +0000798 else:
Sean Callanan0acf4c62012-10-24 22:45:39 +0000799 # First, you can define an environment variable LLDB_EXEC specifying the
800 # full pathname of the lldb executable.
801 if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
802 lldbExec = os.environ["LLDB_EXEC"]
803 else:
804 lldbExec = None
805
806 executable = ['lldb']
807 dbgExec = os.path.join(base, *(xcode3_build_dir + dbg + executable))
808 dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
809 dbcExec = os.path.join(base, *(xcode3_build_dir + dbc + executable))
810 dbcExec2 = os.path.join(base, *(xcode4_build_dir + dbc + executable))
811 relExec = os.path.join(base, *(xcode3_build_dir + rel + executable))
812 relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
813 baiExec = os.path.join(base, *(xcode3_build_dir + bai + executable))
814 baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
815
816 # The 'lldb' executable built here in the source tree.
817 lldbHere = None
818 if is_exe(dbgExec):
819 lldbHere = dbgExec
820 elif is_exe(dbgExec2):
821 lldbHere = dbgExec2
822 elif is_exe(dbcExec):
823 lldbHere = dbcExec
824 elif is_exe(dbcExec2):
825 lldbHere = dbcExec2
826 elif is_exe(relExec):
827 lldbHere = relExec
828 elif is_exe(relExec2):
829 lldbHere = relExec2
830 elif is_exe(baiExec):
831 lldbHere = baiExec
832 elif is_exe(baiExec2):
833 lldbHere = baiExec2
834 elif lldbExec:
835 lldbHere = lldbExec
Sean Callanan502000d2012-11-01 21:23:21 +0000836
Sean Callanan0acf4c62012-10-24 22:45:39 +0000837 # One last chance to locate the 'lldb' executable.
838 if not lldbExec:
839 lldbExec = which('lldb')
840 if lldbHere and not lldbExec:
841 lldbExec = lldbHere
Daniel Malea2777b012013-02-06 16:55:07 +0000842 if lldbExec and not lldbHere:
843 lldbHere = lldbExec
Sean Callanan502000d2012-11-01 21:23:21 +0000844
845 if lldbHere:
846 os.environ["LLDB_HERE"] = lldbHere
Matt Kopeca964b092013-02-20 20:54:10 +0000847 os.environ["LLDB_LIB_DIR"] = os.path.split(lldbHere)[0]
Sean Callanan502000d2012-11-01 21:23:21 +0000848 if not noHeaders:
Matt Kopeca964b092013-02-20 20:54:10 +0000849 print "LLDB library dir:", os.environ["LLDB_LIB_DIR"]
Sean Callanan502000d2012-11-01 21:23:21 +0000850 os.system('%s -v' % lldbHere)
Johnny Chen26901c82011-03-11 19:47:23 +0000851
852 if not lldbExec:
853 print "The 'lldb' executable cannot be located. Some of the tests may not be run as a result."
854 else:
855 os.environ["LLDB_EXEC"] = lldbExec
Johnny Chen8904eb02011-10-28 00:59:00 +0000856 #print "The 'lldb' from PATH env variable", lldbExec
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000857
Daniel Malea2b606ab2013-03-13 20:50:05 +0000858 # Skip printing svn/git information when running in parsable (lit-test compatibility) mode
Enrico Granata814c8132013-04-11 23:48:00 +0000859 if not svn_silent and not parsable:
Daniel Malea2b606ab2013-03-13 20:50:05 +0000860 if os.path.isdir(os.path.join(base, '.svn')) and which("svn") is not None:
861 pipe = subprocess.Popen([which("svn"), "info", base], stdout = subprocess.PIPE)
862 svn_info = pipe.stdout.read()
863 elif os.path.isdir(os.path.join(base, '.git')) and which("git") is not None:
864 pipe = subprocess.Popen([which("git"), "svn", "info", base], stdout = subprocess.PIPE)
865 svn_info = pipe.stdout.read()
866 if not noHeaders:
867 print svn_info
Johnny Chen26901c82011-03-11 19:47:23 +0000868
869 global ignore
870
Johnny Chen9707bb62010-06-25 21:14:08 +0000871 lldbPath = None
Sean Callanan0acf4c62012-10-24 22:45:39 +0000872 if lldbFrameworkPath:
873 candidatePath = os.path.join(lldbFrameworkPath, 'Resources', 'Python')
874 if os.path.isfile(os.path.join(candidatePath, 'lldb/__init__.py')):
875 lldbPath = candidatePath
876 if not lldbPath:
877 print 'Resources/Python/lldb/__init__.py was not found in ' + lldbFrameworkPath
878 sys.exit(-1)
879 else:
880 # The '-i' option is used to skip looking for lldb.py in the build tree.
881 if ignore:
882 return
Jim Inghamaa93c932012-12-21 22:22:26 +0000883
884 # If our lldb supports the -P option, use it to find the python path:
885 init_in_python_dir = 'lldb/__init__.py'
886 import pexpect
887 lldb_dash_p_result = None
888
889 if lldbHere:
890 lldb_dash_p_result = pexpect.run("%s -P"%(lldbHere))
891 elif lldbExec:
892 lldb_dash_p_result = pexpect.run("%s -P"%(lldbExec))
893
894 if lldb_dash_p_result and not lldb_dash_p_result.startswith(("<", "lldb: invalid option:")):
895 lines = lldb_dash_p_result.splitlines()
896 if len(lines) == 1 and os.path.isfile(os.path.join(lines[0], init_in_python_dir)):
897 lldbPath = lines[0]
Daniel Malea21e32a62013-01-04 23:35:13 +0000898 if "linux" in sys.platform:
Matt Kopeca964b092013-02-20 20:54:10 +0000899 os.environ['LLDB_LIB_DIR'] = os.path.join(lldbPath, '..', '..')
Jim Inghamaa93c932012-12-21 22:22:26 +0000900
901 if not lldbPath:
902 dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
903 dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
904 dbcPath = os.path.join(base, *(xcode3_build_dir + dbc + python_resource_dir))
905 dbcPath2 = os.path.join(base, *(xcode4_build_dir + dbc + python_resource_dir))
906 relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
907 relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
908 baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
909 baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
Sean Callanan0acf4c62012-10-24 22:45:39 +0000910
Jim Inghamaa93c932012-12-21 22:22:26 +0000911 if os.path.isfile(os.path.join(dbgPath, init_in_python_dir)):
912 lldbPath = dbgPath
913 elif os.path.isfile(os.path.join(dbgPath2, init_in_python_dir)):
914 lldbPath = dbgPath2
915 elif os.path.isfile(os.path.join(dbcPath, init_in_python_dir)):
916 lldbPath = dbcPath
917 elif os.path.isfile(os.path.join(dbcPath2, init_in_python_dir)):
918 lldbPath = dbcPath2
919 elif os.path.isfile(os.path.join(relPath, init_in_python_dir)):
920 lldbPath = relPath
921 elif os.path.isfile(os.path.join(relPath2, init_in_python_dir)):
922 lldbPath = relPath2
923 elif os.path.isfile(os.path.join(baiPath, init_in_python_dir)):
924 lldbPath = baiPath
925 elif os.path.isfile(os.path.join(baiPath2, init_in_python_dir)):
926 lldbPath = baiPath2
927
Sean Callanan0acf4c62012-10-24 22:45:39 +0000928 if not lldbPath:
929 print 'This script requires lldb.py to be in either ' + dbgPath + ',',
930 print relPath + ', or ' + baiPath
931 sys.exit(-1)
Johnny Chen9707bb62010-06-25 21:14:08 +0000932
Jim Inghamaa93c932012-12-21 22:22:26 +0000933 # Some of the code that uses this path assumes it hasn't resolved the Versions... link.
934 # If the path we've constructed looks like that, then we'll strip out the Versions/A part.
935 (before, frameWithVersion, after) = lldbPath.rpartition("LLDB.framework/Versions/A")
936 if frameWithVersion != "" :
937 lldbPath = before + "LLDB.framework" + after
938
Enrico Granata0ad92972013-04-11 23:40:59 +0000939 lldbPath = os.path.abspath(lldbPath)
940
Enrico Granata01458ca2012-10-23 00:09:02 +0000941 # If tests need to find LLDB_FRAMEWORK, now they can do it
942 os.environ["LLDB_FRAMEWORK"] = os.path.dirname(os.path.dirname(lldbPath))
943
Johnny Chenaf149a02010-09-16 17:11:30 +0000944 # This is to locate the lldb.py module. Insert it right after sys.path[0].
945 sys.path[1:1] = [lldbPath]
Johnny Chen50bc6382011-01-29 01:16:52 +0000946 if dumpSysPath:
947 print "sys.path:", sys.path
Johnny Chen9707bb62010-06-25 21:14:08 +0000948
Johnny Chen9707bb62010-06-25 21:14:08 +0000949
Johnny Chencd0279d2010-09-20 18:07:50 +0000950def doDelay(delta):
951 """Delaying startup for delta-seconds to facilitate debugger attachment."""
952 def alarm_handler(*args):
953 raise Exception("timeout")
954
955 signal.signal(signal.SIGALRM, alarm_handler)
956 signal.alarm(delta)
957 sys.stdout.write("pid=%d\n" % os.getpid())
958 sys.stdout.write("Enter RET to proceed (or timeout after %d seconds):" %
959 delta)
960 sys.stdout.flush()
961 try:
962 text = sys.stdin.readline()
963 except:
964 text = ""
965 signal.alarm(0)
966 sys.stdout.write("proceeding...\n")
967 pass
968
969
Johnny Chen9707bb62010-06-25 21:14:08 +0000970def visit(prefix, dir, names):
971 """Visitor function for os.path.walk(path, visit, arg)."""
972
973 global suite
Johnny Chen7c52ff12010-09-27 23:29:54 +0000974 global regexp
Johnny Chenc5fa0052011-07-29 22:54:56 +0000975 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000976 global fs4all
Johnny Chene9eae812012-01-18 05:15:00 +0000977 global excluded
978
979 if set(dir.split(os.sep)).intersection(excluded):
980 #print "Detected an excluded dir component: %s" % dir
981 return
Johnny Chen9707bb62010-06-25 21:14:08 +0000982
983 for name in names:
984 if os.path.isdir(os.path.join(dir, name)):
985 continue
986
987 if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
Johnny Chen7c52ff12010-09-27 23:29:54 +0000988 # Try to match the regexp pattern, if specified.
989 if regexp:
990 import re
991 if re.search(regexp, name):
992 #print "Filename: '%s' matches pattern: '%s'" % (name, regexp)
993 pass
994 else:
995 #print "Filename: '%s' does not match pattern: '%s'" % (name, regexp)
996 continue
997
Johnny Chen953864a2010-10-12 21:35:54 +0000998 # We found a match for our test. Add it to the suite.
Johnny Chen79723352010-10-12 15:53:22 +0000999
1000 # Update the sys.path first.
Johnny Chena85d7ee2010-06-26 00:19:32 +00001001 if not sys.path.count(dir):
Johnny Chen548aefd2010-10-11 22:25:46 +00001002 sys.path.insert(0, dir)
Johnny Chen9707bb62010-06-25 21:14:08 +00001003 base = os.path.splitext(name)[0]
Johnny Chenb62436b2010-10-06 20:40:56 +00001004
1005 # Thoroughly check the filterspec against the base module and admit
1006 # the (base, filterspec) combination only when it makes sense.
Johnny Chenc5fa0052011-07-29 22:54:56 +00001007 filterspec = None
1008 for filterspec in filters:
Johnny Chenb62436b2010-10-06 20:40:56 +00001009 # Optimistically set the flag to True.
1010 filtered = True
1011 module = __import__(base)
1012 parts = filterspec.split('.')
1013 obj = module
1014 for part in parts:
1015 try:
1016 parent, obj = obj, getattr(obj, part)
1017 except AttributeError:
1018 # The filterspec has failed.
1019 filtered = False
1020 break
Johnny Chenc5fa0052011-07-29 22:54:56 +00001021
Johnny Chendb4be602011-08-12 23:55:07 +00001022 # If filtered, we have a good filterspec. Add it.
Johnny Chenc5fa0052011-07-29 22:54:56 +00001023 if filtered:
Johnny Chendb4be602011-08-12 23:55:07 +00001024 #print "adding filter spec %s to module %s" % (filterspec, module)
1025 suite.addTests(
1026 unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
1027 continue
Johnny Chenc5fa0052011-07-29 22:54:56 +00001028
1029 # Forgo this module if the (base, filterspec) combo is invalid
1030 # and no '-g' option is specified
1031 if filters and fs4all and not filtered:
1032 continue
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001033
Johnny Chendb4be602011-08-12 23:55:07 +00001034 # Add either the filtered test case(s) (which is done before) or the entire test class.
1035 if not filterspec or not filtered:
Johnny Chenb62436b2010-10-06 20:40:56 +00001036 # A simple case of just the module name. Also the failover case
1037 # from the filterspec branch when the (base, filterspec) combo
1038 # doesn't make sense.
1039 suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
Johnny Chen9707bb62010-06-25 21:14:08 +00001040
1041
Johnny Chencd0279d2010-09-20 18:07:50 +00001042def lldbLoggings():
1043 """Check and do lldb loggings if necessary."""
1044
1045 # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
1046 # defined. Use ${LLDB_LOG} to specify the log file.
1047 ci = lldb.DBG.GetCommandInterpreter()
1048 res = lldb.SBCommandReturnObject()
1049 if ("LLDB_LOG" in os.environ):
1050 if ("LLDB_LOG_OPTION" in os.environ):
1051 lldb_log_option = os.environ["LLDB_LOG_OPTION"]
1052 else:
Johnny Chen8fd886c2010-12-08 01:25:21 +00001053 lldb_log_option = "event process expr state api"
Johnny Chencd0279d2010-09-20 18:07:50 +00001054 ci.HandleCommand(
Greg Clayton940b1032011-02-23 00:35:02 +00001055 "log enable -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option,
Johnny Chencd0279d2010-09-20 18:07:50 +00001056 res)
1057 if not res.Succeeded():
1058 raise Exception('log enable failed (check LLDB_LOG env variable.')
1059 # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
1060 # Use ${GDB_REMOTE_LOG} to specify the log file.
1061 if ("GDB_REMOTE_LOG" in os.environ):
1062 if ("GDB_REMOTE_LOG_OPTION" in os.environ):
1063 gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
1064 else:
Johnny Chen7ab8c852010-12-02 18:35:13 +00001065 gdb_remote_log_option = "packets process"
Johnny Chencd0279d2010-09-20 18:07:50 +00001066 ci.HandleCommand(
Johnny Chenc935a892011-06-21 19:25:45 +00001067 "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
Johnny Chencd0279d2010-09-20 18:07:50 +00001068 + gdb_remote_log_option,
1069 res)
1070 if not res.Succeeded():
1071 raise Exception('log enable failed (check GDB_REMOTE_LOG env variable.')
1072
Johnny Chen067022b2011-01-19 19:31:46 +00001073def getMyCommandLine():
Daniel Malea782e4742013-05-30 21:48:58 +00001074 ps = subprocess.Popen([which('ps'), '-o', "command=CMD", str(os.getpid())], stdout=subprocess.PIPE).communicate()[0]
Johnny Chen067022b2011-01-19 19:31:46 +00001075 lines = ps.split('\n')
1076 cmd_line = lines[1]
1077 return cmd_line
Johnny Chencd0279d2010-09-20 18:07:50 +00001078
Johnny Chend96b5682010-11-05 17:30:53 +00001079# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +00001080# #
1081# Execution of the test driver starts here #
1082# #
Johnny Chend96b5682010-11-05 17:30:53 +00001083# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +00001084
Johnny Chen2891bb02011-09-16 01:04:26 +00001085def checkDsymForUUIDIsNotOn():
Johnny Chen6a4e0872011-09-16 17:50:44 +00001086 cmd = ["defaults", "read", "com.apple.DebugSymbols"]
1087 pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1088 cmd_output = pipe.stdout.read()
Johnny Chen178c8d92011-09-16 18:03:19 +00001089 if cmd_output and "DBGFileMappedPaths = " in cmd_output:
Johnny Chen6a451482011-09-16 18:09:45 +00001090 print "%s =>" % ' '.join(cmd)
Johnny Chen6a4e0872011-09-16 17:50:44 +00001091 print cmd_output
Johnny Chen2891bb02011-09-16 01:04:26 +00001092 print "Disable automatic lookup and caching of dSYMs before running the test suite!"
1093 print "Exiting..."
1094 sys.exit(0)
1095
1096# On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
1097# does not exist before proceeding to running the test suite.
1098if sys.platform.startswith("darwin"):
1099 checkDsymForUUIDIsNotOn()
1100
Johnny Chen9707bb62010-06-25 21:14:08 +00001101#
Johnny Chenaf149a02010-09-16 17:11:30 +00001102# Start the actions by first parsing the options while setting up the test
1103# directories, followed by setting up the search paths for lldb utilities;
1104# then, we walk the directory trees and collect the tests into our test suite.
Johnny Chen9707bb62010-06-25 21:14:08 +00001105#
Johnny Chenaf149a02010-09-16 17:11:30 +00001106parseOptionsAndInitTestdirs()
Johnny Chen9707bb62010-06-25 21:14:08 +00001107setupSysPath()
Johnny Chen91960d32010-09-08 20:56:16 +00001108
1109#
1110# If '-d' is specified, do a delay of 10 seconds for the debugger to attach.
1111#
1112if delay:
Johnny Chencd0279d2010-09-20 18:07:50 +00001113 doDelay(10)
Johnny Chen91960d32010-09-08 20:56:16 +00001114
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001115#
Johnny Chen41998192010-10-01 22:59:49 +00001116# If '-l' is specified, do not skip the long running tests.
Johnny Chen028d8eb2011-11-17 19:57:27 +00001117if not skip_long_running_test:
Johnny Chen41998192010-10-01 22:59:49 +00001118 os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
1119
1120#
Johnny Chen79723352010-10-12 15:53:22 +00001121# Walk through the testdirs while collecting tests.
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001122#
Johnny Chen9707bb62010-06-25 21:14:08 +00001123for testdir in testdirs:
1124 os.path.walk(testdir, visit, 'Test')
1125
Johnny Chenb40056b2010-09-21 00:09:27 +00001126#
Johnny Chen9707bb62010-06-25 21:14:08 +00001127# Now that we have loaded all the test cases, run the whole test suite.
Johnny Chenb40056b2010-09-21 00:09:27 +00001128#
Johnny Chencd0279d2010-09-20 18:07:50 +00001129
Johnny Chen1bfbd412010-06-29 19:44:16 +00001130# For the time being, let's bracket the test runner within the
1131# lldb.SBDebugger.Initialize()/Terminate() pair.
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001132import lldb, atexit
Johnny Chen6b6f5ba2010-10-14 16:36:49 +00001133# Update: the act of importing lldb now executes lldb.SBDebugger.Initialize(),
1134# there's no need to call it a second time.
1135#lldb.SBDebugger.Initialize()
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001136atexit.register(lambda: lldb.SBDebugger.Terminate())
Johnny Chen1bfbd412010-06-29 19:44:16 +00001137
Johnny Chen909e5a62010-07-01 22:52:57 +00001138# Create a singleton SBDebugger in the lldb namespace.
1139lldb.DBG = lldb.SBDebugger.Create()
1140
Johnny Chen4f93bf12010-12-10 00:51:23 +00001141# Put the blacklist in the lldb namespace, to be used by lldb.TestBase.
Johnny Chen82e6b1e2010-12-01 22:47:54 +00001142lldb.blacklist = blacklist
1143
Johnny Chenac97a6b2012-04-16 18:55:15 +00001144# The pre_flight and post_flight come from reading a config file.
1145lldb.pre_flight = pre_flight
1146lldb.post_flight = post_flight
1147def getsource_if_available(obj):
1148 """
1149 Return the text of the source code for an object if available. Otherwise,
1150 a print representation is returned.
1151 """
1152 import inspect
1153 try:
1154 return inspect.getsource(obj)
1155 except:
1156 return repr(obj)
1157
Daniel Malea361eb432013-02-15 21:31:37 +00001158if not noHeaders:
1159 print "lldb.pre_flight:", getsource_if_available(lldb.pre_flight)
1160 print "lldb.post_flight:", getsource_if_available(lldb.post_flight)
Johnny Chenac97a6b2012-04-16 18:55:15 +00001161
Johnny Chena3ed7d82012-04-06 00:56:05 +00001162# Put all these test decorators in the lldb namespace.
Johnny Chen4f93bf12010-12-10 00:51:23 +00001163lldb.dont_do_python_api_test = dont_do_python_api_test
1164lldb.just_do_python_api_test = just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +00001165lldb.just_do_benchmarks_test = just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +00001166lldb.dont_do_dsym_test = dont_do_dsym_test
1167lldb.dont_do_dwarf_test = dont_do_dwarf_test
Johnny Chen4f93bf12010-12-10 00:51:23 +00001168
Johnny Chen028d8eb2011-11-17 19:57:27 +00001169# Do we need to skip build and cleanup?
1170lldb.skip_build_and_cleanup = skip_build_and_cleanup
1171
Johnny Chen5f2ed172011-10-20 18:43:28 +00001172# Put bmExecutable, bmBreakpointSpec, and bmIterationCount into the lldb namespace, too.
Johnny Chene00c9302011-10-10 22:03:44 +00001173lldb.bmExecutable = bmExecutable
1174lldb.bmBreakpointSpec = bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +00001175lldb.bmIterationCount = bmIterationCount
Johnny Chene00c9302011-10-10 22:03:44 +00001176
Johnny Chen38f823c2011-10-11 01:30:27 +00001177# And don't forget the runHooks!
1178lldb.runHooks = runHooks
1179
Johnny Chencd0279d2010-09-20 18:07:50 +00001180# Turn on lldb loggings if necessary.
1181lldbLoggings()
Johnny Chen909e5a62010-07-01 22:52:57 +00001182
Johnny Chen7987ac92010-08-09 20:40:52 +00001183# Install the control-c handler.
1184unittest2.signals.installHandler()
1185
Johnny Chen125fc2b2010-10-21 16:55:35 +00001186# If sdir_name is not specified through the '-s sdir_name' option, get a
1187# timestamp string and export it as LLDB_SESSION_DIR environment var. This will
1188# be used when/if we want to dump the session info of individual test cases
1189# later on.
Johnny Chence681462010-10-19 00:25:01 +00001190#
1191# See also TestBase.dumpSessionInfo() in lldbtest.py.
Johnny Chena73ad662012-08-16 19:15:21 +00001192import datetime
1193# The windows platforms don't like ':' in the pathname.
1194timestamp_started = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
Johnny Chen125fc2b2010-10-21 16:55:35 +00001195if not sdir_name:
Johnny Chena73ad662012-08-16 19:15:21 +00001196 sdir_name = timestamp_started
Peter Collingbourne132476f2011-06-20 23:55:53 +00001197os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), sdir_name)
Johnny Chen067022b2011-01-19 19:31:46 +00001198
Johnny Chenfe5f1ed2011-10-21 18:33:27 +00001199if not noHeaders:
1200 sys.stderr.write("\nSession logs for test failures/errors/unexpected successes"
1201 " will go into directory '%s'\n" % sdir_name)
1202 sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
Johnny Chence681462010-10-19 00:25:01 +00001203
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001204if not os.path.isdir(sdir_name):
1205 os.mkdir(sdir_name)
Johnny Chena73ad662012-08-16 19:15:21 +00001206fname = os.path.join(sdir_name, "TestStarted")
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001207with open(fname, "w") as f:
Johnny Chena73ad662012-08-16 19:15:21 +00001208 print >> f, "Test started at: %s\n" % timestamp_started
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001209 print >> f, svn_info
1210 print >> f, "Command invoked: %s\n" % getMyCommandLine()
1211
Johnny Chenb40056b2010-09-21 00:09:27 +00001212#
1213# Invoke the default TextTestRunner to run the test suite, possibly iterating
1214# over different configurations.
1215#
1216
Johnny Chenb40056b2010-09-21 00:09:27 +00001217iterArchs = False
Johnny Chenf032d902010-09-21 00:16:09 +00001218iterCompilers = False
Johnny Chenb40056b2010-09-21 00:09:27 +00001219
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001220if not archs and "archs" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001221 archs = config["archs"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001222
1223if isinstance(archs, list) and len(archs) >= 1:
1224 iterArchs = True
1225
1226if not compilers and "compilers" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001227 compilers = config["compilers"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001228
Johnny Chen92693b52012-03-09 02:11:37 +00001229#
1230# Add some intervention here to sanity check that the compilers requested are sane.
1231# If found not to be an executable program, the invalid one is dropped from the list.
1232for i in range(len(compilers)):
1233 c = compilers[i]
1234 if which(c):
1235 continue
1236 else:
1237 if sys.platform.startswith("darwin"):
1238 pipe = subprocess.Popen(['xcrun', '-find', c], stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1239 cmd_output = pipe.stdout.read()
1240 if cmd_output:
1241 if "not found" in cmd_output:
1242 print "dropping %s from the compilers used" % c
1243 compilers.remove(i)
1244 else:
1245 compilers[i] = cmd_output.split('\n')[0]
1246 print "'xcrun -find %s' returning %s" % (c, compilers[i])
1247
Daniel Malea361eb432013-02-15 21:31:37 +00001248if not parsable:
1249 print "compilers=%s" % str(compilers)
Johnny Chen92693b52012-03-09 02:11:37 +00001250
1251if not compilers or len(compilers) == 0:
1252 print "No eligible compiler found, exiting."
1253 sys.exit(1)
1254
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001255if isinstance(compilers, list) and len(compilers) >= 1:
1256 iterCompilers = True
Johnny Chenb40056b2010-09-21 00:09:27 +00001257
Johnny Chen953864a2010-10-12 21:35:54 +00001258# Make a shallow copy of sys.path, we need to manipulate the search paths later.
1259# This is only necessary if we are relocated and with different configurations.
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001260if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001261 old_sys_path = sys.path[:]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001262# If we iterate on archs or compilers, there is a chance we want to split stderr/stdout.
1263if iterArchs or iterCompilers:
Johnny Chen953864a2010-10-12 21:35:54 +00001264 old_stderr = sys.stderr
1265 old_stdout = sys.stdout
1266 new_stderr = None
1267 new_stdout = None
1268
Johnny Chend96b5682010-11-05 17:30:53 +00001269# Iterating over all possible architecture and compiler combinations.
Johnny Chenb40056b2010-09-21 00:09:27 +00001270for ia in range(len(archs) if iterArchs else 1):
1271 archConfig = ""
1272 if iterArchs:
Johnny Chen18a921f2010-09-30 17:11:58 +00001273 os.environ["ARCH"] = archs[ia]
Johnny Chenb40056b2010-09-21 00:09:27 +00001274 archConfig = "arch=%s" % archs[ia]
1275 for ic in range(len(compilers) if iterCompilers else 1):
1276 if iterCompilers:
Johnny Chen18a921f2010-09-30 17:11:58 +00001277 os.environ["CC"] = compilers[ic]
Johnny Chenb40056b2010-09-21 00:09:27 +00001278 configString = "%s compiler=%s" % (archConfig, compilers[ic])
1279 else:
1280 configString = archConfig
1281
Johnny Chenb40056b2010-09-21 00:09:27 +00001282 if iterArchs or iterCompilers:
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001283 # Translate ' ' to '-' for pathname component.
1284 from string import maketrans
1285 tbl = maketrans(' ', '-')
1286 configPostfix = configString.translate(tbl)
1287
1288 # Check whether we need to split stderr/stdout into configuration
1289 # specific files.
1290 if old_stderr.name != '<stderr>' and config.get('split_stderr'):
1291 if new_stderr:
1292 new_stderr.close()
1293 new_stderr = open("%s.%s" % (old_stderr.name, configPostfix), "w")
1294 sys.stderr = new_stderr
1295 if old_stdout.name != '<stdout>' and config.get('split_stdout'):
1296 if new_stdout:
1297 new_stdout.close()
1298 new_stdout = open("%s.%s" % (old_stdout.name, configPostfix), "w")
1299 sys.stdout = new_stdout
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001300
Johnny Chen953864a2010-10-12 21:35:54 +00001301 # If we specified a relocated directory to run the test suite, do
1302 # the extra housekeeping to copy the testdirs to a configStringified
1303 # directory and to update sys.path before invoking the test runner.
1304 # The purpose is to separate the configuration-specific directories
1305 # from each other.
1306 if rdir:
Johnny Chen3bc7e5e2012-04-24 21:44:10 +00001307 from shutil import copytree, rmtree, ignore_patterns
Johnny Chen953864a2010-10-12 21:35:54 +00001308
Johnny Chen953864a2010-10-12 21:35:54 +00001309 newrdir = "%s.%s" % (rdir, configPostfix)
1310
1311 # Copy the tree to a new directory with postfix name configPostfix.
Johnny Chen3bc7e5e2012-04-24 21:44:10 +00001312 if os.path.exists(newrdir):
1313 rmtree(newrdir)
Johnny Chen953864a2010-10-12 21:35:54 +00001314 copytree(rdir, newrdir, ignore=ignore_patterns('*.pyc', '*.o', '*.d'))
1315
Filipe Cabecinhas0e1d06d2012-08-08 15:23:24 +00001316 # Update the LLDB_TEST environment variable to reflect new top
Johnny Chen953864a2010-10-12 21:35:54 +00001317 # level test directory.
1318 #
1319 # See also lldbtest.TestBase.setUpClass(cls).
1320 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
1321 os.environ["LLDB_TEST"] = os.path.join(newrdir, 'test')
1322 else:
1323 os.environ["LLDB_TEST"] = newrdir
1324
1325 # And update the Python search paths for modules.
1326 sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
1327
1328 # Output the configuration.
Daniel Malea361eb432013-02-15 21:31:37 +00001329 if not parsable:
1330 sys.stderr.write("\nConfiguration: " + configString + "\n")
Johnny Chen953864a2010-10-12 21:35:54 +00001331
1332 #print "sys.stderr name is", sys.stderr.name
1333 #print "sys.stdout name is", sys.stdout.name
1334
1335 # First, write out the number of collected test cases.
Daniel Malea361eb432013-02-15 21:31:37 +00001336 if not parsable:
1337 sys.stderr.write(separator + "\n")
1338 sys.stderr.write("Collected %d test%s\n\n"
1339 % (suite.countTestCases(),
1340 suite.countTestCases() != 1 and "s" or ""))
Johnny Chen953864a2010-10-12 21:35:54 +00001341
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001342 class LLDBTestResult(unittest2.TextTestResult):
1343 """
Johnny Chen26be4532010-11-09 23:56:14 +00001344 Enforce a singleton pattern to allow introspection of test progress.
1345
1346 Overwrite addError(), addFailure(), and addExpectedFailure() methods
1347 to enable each test instance to track its failure/error status. It
1348 is used in the LLDB test framework to emit detailed trace messages
1349 to a log file for easier human inspection of test failres/errors.
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001350 """
1351 __singleton__ = None
Johnny Chen360dd372010-11-29 17:50:10 +00001352 __ignore_singleton__ = False
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001353
Enrico Granatabc0c5a62013-02-08 23:39:18 +00001354 @staticmethod
1355 def getTerminalSize():
1356 import os
1357 env = os.environ
1358 def ioctl_GWINSZ(fd):
1359 try:
1360 import fcntl, termios, struct, os
1361 cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
1362 '1234'))
1363 except:
1364 return
1365 return cr
1366 cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
1367 if not cr:
1368 try:
1369 fd = os.open(os.ctermid(), os.O_RDONLY)
1370 cr = ioctl_GWINSZ(fd)
1371 os.close(fd)
1372 except:
1373 pass
1374 if not cr:
1375 cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
1376 return int(cr[1]), int(cr[0])
1377
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001378 def __init__(self, *args):
Johnny Chen360dd372010-11-29 17:50:10 +00001379 if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
Johnny Chend2acdb32010-11-16 22:42:58 +00001380 raise Exception("LLDBTestResult instantiated more than once")
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001381 super(LLDBTestResult, self).__init__(*args)
1382 LLDBTestResult.__singleton__ = self
1383 # Now put this singleton into the lldb module namespace.
1384 lldb.test_result = self
Johnny Chen810042e2011-01-05 20:24:11 +00001385 # Computes the format string for displaying the counter.
1386 global suite
1387 counterWidth = len(str(suite.countTestCases()))
1388 self.fmt = "%" + str(counterWidth) + "d: "
Johnny Chenc87fd492011-01-05 22:50:11 +00001389 self.indentation = ' ' * (counterWidth + 2)
Johnny Chen810042e2011-01-05 20:24:11 +00001390 # This counts from 1 .. suite.countTestCases().
1391 self.counter = 0
Enrico Granatabc0c5a62013-02-08 23:39:18 +00001392 (width, height) = LLDBTestResult.getTerminalSize()
Enrico Granata77215892013-02-15 00:32:05 +00001393 self.progressbar = None
Jim Ingham75f260a2013-02-19 20:39:27 +00001394 global progress_bar
Daniel Malea361eb432013-02-15 21:31:37 +00001395 if width > 10 and not parsable and progress_bar:
Enrico Granata77215892013-02-15 00:32:05 +00001396 try:
1397 self.progressbar = progress.ProgressWithEvents(stdout=self.stream,start=0,end=suite.countTestCases(),width=width-10)
1398 except:
1399 self.progressbar = None
Johnny Chen810042e2011-01-05 20:24:11 +00001400
Daniel Malea361eb432013-02-15 21:31:37 +00001401 def _config_string(self, test):
1402 compiler = getattr(test, "getCompiler", None)
1403 arch = getattr(test, "getArchitecture", None)
1404 return "%s-%s" % (compiler() if compiler else "", arch() if arch else "")
1405
Johnny Chenbe452272012-04-19 21:33:55 +00001406 def _exc_info_to_string(self, err, test):
1407 """Overrides superclass TestResult's method in order to append
1408 our test config info string to the exception info string."""
1409 modified_exc_string = '%sConfig=%s-%s' % (super(LLDBTestResult, self)._exc_info_to_string(err, test),
1410 test.getArchitecture(),
1411 test.getCompiler())
1412 return modified_exc_string
1413
Johnny Chenc87fd492011-01-05 22:50:11 +00001414 def getDescription(self, test):
1415 doc_first_line = test.shortDescription()
1416 if self.descriptions and doc_first_line:
1417 return '\n'.join((str(test), self.indentation + doc_first_line))
1418 else:
1419 return str(test)
1420
Enrico Granataac3a8e22012-09-21 19:10:53 +00001421 def getCategoriesForTest(self,test):
Enrico Granata56e2c562013-02-27 02:37:12 +00001422 if hasattr(test,"_testMethodName"):
1423 test_method = getattr(test,"_testMethodName")
1424 test_method = getattr(test,test_method)
1425 else:
1426 test_method = None
1427 if test_method != None and hasattr(test_method,"getCategories"):
1428 test_categories = test_method.getCategories(test)
1429 elif hasattr(test,"getCategories"):
Enrico Granataac3a8e22012-09-21 19:10:53 +00001430 test_categories = test.getCategories()
1431 elif inspect.ismethod(test) and test.__self__ != None and hasattr(test.__self__,"getCategories"):
1432 test_categories = test.__self__.getCategories()
1433 else:
1434 test_categories = []
1435 if test_categories == None:
1436 test_categories = []
1437 return test_categories
1438
1439 def shouldSkipBecauseOfCategories(self,test):
1440 global useCategories
1441 import inspect
1442 if useCategories:
1443 global categoriesList
1444 test_categories = self.getCategoriesForTest(test)
1445 if len(test_categories) == 0 or len(categoriesList & set(test_categories)) == 0:
1446 return True
1447 return False
1448
1449 def hardMarkAsSkipped(self,test):
1450 getattr(test, test._testMethodName).__func__.__unittest_skip__ = True
1451 getattr(test, test._testMethodName).__func__.__unittest_skip_why__ = "test case does not fall in any category of interest for this run"
1452
Johnny Chen810042e2011-01-05 20:24:11 +00001453 def startTest(self, test):
Enrico Granataac3a8e22012-09-21 19:10:53 +00001454 if self.shouldSkipBecauseOfCategories(test):
1455 self.hardMarkAsSkipped(test)
Johnny Chen810042e2011-01-05 20:24:11 +00001456 self.counter += 1
1457 if self.showAll:
1458 self.stream.write(self.fmt % self.counter)
1459 super(LLDBTestResult, self).startTest(test)
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001460
Daniel Malea361eb432013-02-15 21:31:37 +00001461 def addSuccess(self, test):
1462 global parsable
1463 super(LLDBTestResult, self).addSuccess(test)
1464 if parsable:
1465 self.stream.write("PASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1466
Johnny Chence681462010-10-19 00:25:01 +00001467 def addError(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001468 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001469 global parsable
Johnny Chen63c2cba2010-10-29 22:20:36 +00001470 sdir_has_content = True
Johnny Chence681462010-10-19 00:25:01 +00001471 super(LLDBTestResult, self).addError(test, err)
1472 method = getattr(test, "markError", None)
1473 if method:
1474 method()
Daniel Malea361eb432013-02-15 21:31:37 +00001475 if parsable:
Daniel Maleae1dd3e52013-03-07 18:39:26 +00001476 self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
Johnny Chence681462010-10-19 00:25:01 +00001477
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001478 def addFailure(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001479 global sdir_has_content
Enrico Granataac3a8e22012-09-21 19:10:53 +00001480 global failuresPerCategory
Daniel Malea361eb432013-02-15 21:31:37 +00001481 global parsable
Johnny Chen63c2cba2010-10-29 22:20:36 +00001482 sdir_has_content = True
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001483 super(LLDBTestResult, self).addFailure(test, err)
1484 method = getattr(test, "markFailure", None)
1485 if method:
1486 method()
Daniel Malea361eb432013-02-15 21:31:37 +00001487 if parsable:
1488 self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
Enrico Granataac3a8e22012-09-21 19:10:53 +00001489 if useCategories:
1490 test_categories = self.getCategoriesForTest(test)
1491 for category in test_categories:
1492 if category in failuresPerCategory:
1493 failuresPerCategory[category] = failuresPerCategory[category] + 1
1494 else:
1495 failuresPerCategory[category] = 1
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001496
Enrico Granata21416a12013-02-23 01:05:23 +00001497 def addExpectedFailure(self, test, err, bugnumber):
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001498 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001499 global parsable
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001500 sdir_has_content = True
Enrico Granata21416a12013-02-23 01:05:23 +00001501 super(LLDBTestResult, self).addExpectedFailure(test, err, bugnumber)
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001502 method = getattr(test, "markExpectedFailure", None)
1503 if method:
Enrico Granata21416a12013-02-23 01:05:23 +00001504 method(err, bugnumber)
Daniel Malea361eb432013-02-15 21:31:37 +00001505 if parsable:
1506 self.stream.write("XFAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001507
Johnny Chenf5b89092011-08-15 23:09:08 +00001508 def addSkip(self, test, reason):
1509 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001510 global parsable
Johnny Chenf5b89092011-08-15 23:09:08 +00001511 sdir_has_content = True
1512 super(LLDBTestResult, self).addSkip(test, reason)
1513 method = getattr(test, "markSkippedTest", None)
1514 if method:
1515 method()
Daniel Malea361eb432013-02-15 21:31:37 +00001516 if parsable:
1517 self.stream.write("UNSUPPORTED: LLDB (%s) :: %s (%s) \n" % (self._config_string(test), str(test), reason))
Johnny Chenf5b89092011-08-15 23:09:08 +00001518
Enrico Granata21416a12013-02-23 01:05:23 +00001519 def addUnexpectedSuccess(self, test, bugnumber):
Johnny Chenab2f0662011-05-06 20:30:22 +00001520 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001521 global parsable
Johnny Chenab2f0662011-05-06 20:30:22 +00001522 sdir_has_content = True
Enrico Granata21416a12013-02-23 01:05:23 +00001523 super(LLDBTestResult, self).addUnexpectedSuccess(test, bugnumber)
Johnny Chenab2f0662011-05-06 20:30:22 +00001524 method = getattr(test, "markUnexpectedSuccess", None)
1525 if method:
Enrico Granata21416a12013-02-23 01:05:23 +00001526 method(bugnumber)
Daniel Malea361eb432013-02-15 21:31:37 +00001527 if parsable:
1528 self.stream.write("XPASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1529
1530 if parsable:
1531 v = 0
1532 elif progress_bar:
1533 v = 1
1534 else:
1535 v = verbose
Johnny Chenab2f0662011-05-06 20:30:22 +00001536
Johnny Chen26be4532010-11-09 23:56:14 +00001537 # Invoke the test runner.
Johnny Chend2acdb32010-11-16 22:42:58 +00001538 if count == 1:
Johnny Chen7d6d8442010-12-03 19:59:35 +00001539 result = unittest2.TextTestRunner(stream=sys.stderr,
Daniel Malea361eb432013-02-15 21:31:37 +00001540 verbosity=v,
Johnny Chen7d6d8442010-12-03 19:59:35 +00001541 failfast=failfast,
Johnny Chend2acdb32010-11-16 22:42:58 +00001542 resultclass=LLDBTestResult).run(suite)
1543 else:
Johnny Chend6e7ca22010-11-29 17:52:43 +00001544 # We are invoking the same test suite more than once. In this case,
1545 # mark __ignore_singleton__ flag as True so the signleton pattern is
1546 # not enforced.
Johnny Chen360dd372010-11-29 17:50:10 +00001547 LLDBTestResult.__ignore_singleton__ = True
Johnny Chend2acdb32010-11-16 22:42:58 +00001548 for i in range(count):
Daniel Malea361eb432013-02-15 21:31:37 +00001549
Johnny Chen7d6d8442010-12-03 19:59:35 +00001550 result = unittest2.TextTestRunner(stream=sys.stderr,
Daniel Malea361eb432013-02-15 21:31:37 +00001551 verbosity=v,
Johnny Chen7d6d8442010-12-03 19:59:35 +00001552 failfast=failfast,
Johnny Chen360dd372010-11-29 17:50:10 +00001553 resultclass=LLDBTestResult).run(suite)
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001554
Daniel Malea24765572013-02-20 20:12:11 +00001555 failed = failed or not result.wasSuccessful()
Johnny Chen1bfbd412010-06-29 19:44:16 +00001556
Daniel Malea361eb432013-02-15 21:31:37 +00001557if sdir_has_content and not parsable:
Johnny Chenab2f0662011-05-06 20:30:22 +00001558 sys.stderr.write("Session logs for test failures/errors/unexpected successes"
1559 " can be found in directory '%s'\n" % sdir_name)
Johnny Chen63c2cba2010-10-29 22:20:36 +00001560
Enrico Granataac3a8e22012-09-21 19:10:53 +00001561if useCategories and len(failuresPerCategory) > 0:
1562 sys.stderr.write("Failures per category:\n")
1563 for category in failuresPerCategory:
1564 sys.stderr.write("%s - %d\n" % (category,failuresPerCategory[category]))
1565
Johnny Chena73ad662012-08-16 19:15:21 +00001566fname = os.path.join(sdir_name, "TestFinished")
1567with open(fname, "w") as f:
1568 print >> f, "Test finished at: %s\n" % datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
1569
Johnny Chencd0279d2010-09-20 18:07:50 +00001570# Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1571# This should not be necessary now.
Johnny Chen83f6e512010-08-13 22:58:44 +00001572if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
Johnny Chen83f6e512010-08-13 22:58:44 +00001573 print "Terminating Test suite..."
1574 subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1575
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001576# Exiting.
Daniel Malea24765572013-02-20 20:12:11 +00001577sys.exit(failed)