blob: 2d6f0b55ac3c0c26f22910f3df5e870892fd1139 [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',
Enrico Granata3cb3fe32013-06-18 00:22:27 +000083'basic_process': 'Basic process execution sniff tests.',
84'cmdline' : 'Tests related to the LLDB command-line interface'
Enrico Granataac3a8e22012-09-21 19:10:53 +000085}
86
Johnny Chen9707bb62010-06-25 21:14:08 +000087# The test suite.
Johnny Chen75e28f92010-08-05 23:42:46 +000088suite = unittest2.TestSuite()
Johnny Chen9707bb62010-06-25 21:14:08 +000089
Johnny Chen4f93bf12010-12-10 00:51:23 +000090# By default, both command line and Python API tests are performed.
Johnny Chen3ebdacc2010-12-10 18:52:10 +000091# Use @python_api_test decorator, defined in lldbtest.py, to mark a test as
92# a Python API test.
Johnny Chen4f93bf12010-12-10 00:51:23 +000093dont_do_python_api_test = False
94
95# By default, both command line and Python API tests are performed.
Johnny Chen4f93bf12010-12-10 00:51:23 +000096just_do_python_api_test = False
97
Johnny Chen82ccf402011-07-30 01:39:58 +000098# By default, benchmarks tests are not run.
99just_do_benchmarks_test = False
100
Johnny Chena3ed7d82012-04-06 00:56:05 +0000101# By default, both dsym and dwarf tests are performed.
102# Use @dsym_test or @dwarf_test decorators, defined in lldbtest.py, to mark a test
103# as a dsym or dwarf test. Use '-N dsym' or '-N dwarf' to exclude dsym or dwarf
104# tests from running.
Daniel Maleab8106282012-11-20 16:07:33 +0000105dont_do_dsym_test = "linux" in sys.platform
Johnny Chena3ed7d82012-04-06 00:56:05 +0000106dont_do_dwarf_test = False
107
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000108# The blacklist is optional (-b blacklistFile) and allows a central place to skip
109# testclass's and/or testclass.testmethod's.
110blacklist = None
111
112# The dictionary as a result of sourcing blacklistFile.
113blacklistConfig = {}
114
Enrico Granataac3a8e22012-09-21 19:10:53 +0000115# The list of categories we said we care about
116categoriesList = None
117# set to true if we are going to use categories for cherry-picking test cases
118useCategories = False
119# use this to track per-category failures
120failuresPerCategory = {}
121
Sean Callanan0acf4c62012-10-24 22:45:39 +0000122# The path to LLDB.framework is optional.
123lldbFrameworkPath = None
124
125# The path to lldb is optional
126lldbExecutablePath = None
127
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000128# The config file is optional.
129configFile = None
130
Johnny Chend2acdb32010-11-16 22:42:58 +0000131# Test suite repeat count. Can be overwritten with '-# count'.
132count = 1
133
Johnny Chenb40056b2010-09-21 00:09:27 +0000134# The dictionary as a result of sourcing configFile.
135config = {}
Johnny Chenac97a6b2012-04-16 18:55:15 +0000136# The pre_flight and post_flight functions come from reading a config file.
137pre_flight = None
138post_flight = None
Johnny Chenb40056b2010-09-21 00:09:27 +0000139
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000140# The 'archs' and 'compilers' can be specified via either command line or configFile,
Greg Clayton4793e942012-09-04 15:42:49 +0000141# with the command line overriding the configFile. The corresponding options can be
Filipe Cabecinhasd3eb8372013-02-16 09:05:23 +0000142# specified more than once. For example, "-A x86_64 -A i386" => archs=['x86_64', 'i386']
Greg Clayton4793e942012-09-04 15:42:49 +0000143# and "-C gcc -C clang" => compilers=['gcc', 'clang'].
144archs = None # Must be initialized after option parsing
145compilers = None # Must be initialized after option parsing
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000146
Johnny Chen1abe4c02012-03-20 00:33:51 +0000147# The arch might dictate some specific CFLAGS to be passed to the toolchain to build
148# the inferior programs. The global variable cflags_extras provides a hook to do
149# just that.
150cflags_extras = ''
151
Johnny Chen91960d32010-09-08 20:56:16 +0000152# Delay startup in order for the debugger to attach.
153delay = False
154
Johnny Chend5362332011-01-29 01:21:04 +0000155# Dump the Python sys.path variable. Use '-D' to dump sys.path.
Johnny Chen50bc6382011-01-29 01:16:52 +0000156dumpSysPath = False
157
Johnny Chene00c9302011-10-10 22:03:44 +0000158# Full path of the benchmark executable, as specified by the '-e' option.
159bmExecutable = None
160# The breakpoint specification of bmExecutable, as specified by the '-x' option.
161bmBreakpointSpec = None
Johnny Chen5f2ed172011-10-20 18:43:28 +0000162# The benchamrk iteration count, as specified by the '-y' option.
163bmIterationCount = -1
Johnny Chene00c9302011-10-10 22:03:44 +0000164
Johnny Chene9eae812012-01-18 05:15:00 +0000165# By default, don't exclude any directories. Use '-X' to add one excluded directory.
166excluded = set(['.svn', '.git'])
167
Johnny Chen7d6d8442010-12-03 19:59:35 +0000168# By default, failfast is False. Use '-F' to overwrite it.
169failfast = False
170
Johnny Chenc5fa0052011-07-29 22:54:56 +0000171# The filters (testclass.testmethod) used to admit tests into our test suite.
172filters = []
Johnny Chenb62436b2010-10-06 20:40:56 +0000173
Johnny Chen38f823c2011-10-11 01:30:27 +0000174# The runhooks is a list of lldb commands specifically for the debugger.
175# Use '-k' to specify a runhook.
176runHooks = []
177
Johnny Chena224cd12010-11-08 01:21:03 +0000178# If '-g' is specified, the filterspec is not exclusive. If a test module does
179# not contain testclass.testmethod which matches the filterspec, the whole test
180# module is still admitted into our test suite. fs4all flag defaults to True.
181fs4all = True
Johnny Chenb62436b2010-10-06 20:40:56 +0000182
Johnny Chenaf149a02010-09-16 17:11:30 +0000183# Ignore the build search path relative to this script to locate the lldb.py module.
184ignore = False
185
Johnny Chen028d8eb2011-11-17 19:57:27 +0000186# By default, we do not skip build and cleanup. Use '-S' option to override.
187skip_build_and_cleanup = False
188
Johnny Chen548aefd2010-10-11 22:25:46 +0000189# By default, we skip long running test case. Use '-l' option to override.
Johnny Chen028d8eb2011-11-17 19:57:27 +0000190skip_long_running_test = True
Johnny Chen41998192010-10-01 22:59:49 +0000191
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000192# By default, we print the build dir, lldb version, and svn info. Use '-n' option to
193# turn it off.
194noHeaders = False
195
Daniel Malea361eb432013-02-15 21:31:37 +0000196# Parsable mode silences headers, and any other output this script might generate, and instead
197# prints machine-readable output similar to what clang tests produce.
198parsable = False
199
Johnny Chen7c52ff12010-09-27 23:29:54 +0000200# The regular expression pattern to match against eligible filenames as our test cases.
201regexp = None
202
Johnny Chen548aefd2010-10-11 22:25:46 +0000203# By default, tests are executed in place and cleanups are performed afterwards.
204# Use '-r dir' option to relocate the tests and their intermediate files to a
205# different directory and to forgo any cleanups. The directory specified must
206# not exist yet.
207rdir = None
208
Johnny Chen125fc2b2010-10-21 16:55:35 +0000209# By default, recorded session info for errored/failed test are dumped into its
210# own file under a session directory named after the timestamp of the test suite
211# run. Use '-s session-dir-name' to specify a specific dir name.
212sdir_name = None
213
Johnny Chen63c2cba2010-10-29 22:20:36 +0000214# Set this flag if there is any session info dumped during the test run.
215sdir_has_content = False
216
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000217# svn_info stores the output from 'svn info lldb.base.dir'.
218svn_info = ''
219
Enrico Granata814c8132013-04-11 23:48:00 +0000220# svn_silent means do not try to obtain svn status
221svn_silent = True
222
Johnny Chen9707bb62010-06-25 21:14:08 +0000223# Default verbosity is 0.
Jim Ingham75f260a2013-02-19 20:39:27 +0000224verbose = 1
Johnny Chen9707bb62010-06-25 21:14:08 +0000225
Johnny Chen08967192011-11-18 00:19:29 +0000226# Set to True only if verbose is 0 and LLDB trace mode is off.
227progress_bar = False
228
Peter Collingbourne61aca482011-06-20 19:06:29 +0000229# By default, search from the script directory.
230testdirs = [ sys.path[0] ]
Johnny Chen9707bb62010-06-25 21:14:08 +0000231
Johnny Chen877c7e42010-08-07 00:16:07 +0000232# Separator string.
233separator = '-' * 70
234
Daniel Malea24765572013-02-20 20:12:11 +0000235failed = False
Johnny Chen9707bb62010-06-25 21:14:08 +0000236
Greg Clayton4793e942012-09-04 15:42:49 +0000237def usage(parser):
238 parser.print_help()
Jim Ingham4f347cb2011-04-13 21:11:41 +0000239 if verbose > 0:
240 print """
Johnny Chen9656ab22010-10-22 19:00:18 +0000241Examples:
242
Johnny Chena224cd12010-11-08 01:21:03 +0000243This is an example of using the -f option to pinpoint to a specfic test class
244and test method to be run:
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000245
Johnny Chena224cd12010-11-08 01:21:03 +0000246$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000247----------------------------------------------------------------------
248Collected 1 test
249
250test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
251Test 'frame variable this' when stopped on a class constructor. ... ok
252
253----------------------------------------------------------------------
254Ran 1 test in 1.396s
255
256OK
Johnny Chen9656ab22010-10-22 19:00:18 +0000257
258And this is an example of using the -p option to run a single file (the filename
259matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
260
261$ ./dotest.py -v -p ObjC
262----------------------------------------------------------------------
263Collected 4 tests
264
265test_break_with_dsym (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000266Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000267test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000268Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
Johnny Chen9656ab22010-10-22 19:00:18 +0000269test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
270Lookup objective-c data types and evaluate expressions. ... ok
271test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
272Lookup objective-c data types and evaluate expressions. ... ok
273
274----------------------------------------------------------------------
275Ran 4 tests in 16.661s
276
277OK
Johnny Chen6ad7e5e2010-10-21 00:47:52 +0000278
Johnny Chen58f93922010-06-29 23:10:39 +0000279Running of this script also sets up the LLDB_TEST environment variable so that
Johnny Chenaf149a02010-09-16 17:11:30 +0000280individual test cases can locate their supporting files correctly. The script
281tries to set up Python's search paths for modules by looking at the build tree
Johnny Chena85859f2010-11-11 22:14:56 +0000282relative to this script. See also the '-i' option in the following example.
283
284Finally, this is an example of using the lldb.py module distributed/installed by
285Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
286option to add some delay between two tests. It uses ARCH=x86_64 to specify that
287as the architecture and CC=clang to specify the compiler used for the test run:
288
289$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
290
291Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
292----------------------------------------------------------------------
293Collected 2 tests
294
295test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
296Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
297test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
298Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
299
300----------------------------------------------------------------------
301Ran 2 tests in 5.659s
302
303OK
304
305The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
306notify the directory containing the session logs for test failures or errors.
307In case there is any test failure/error, a similar message is appended at the
308end of the stderr output for your convenience.
Johnny Chenfde69bc2010-09-14 22:01:40 +0000309
310Environment variables related to loggings:
311
312o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
313 with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
314
315o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
316 'process.gdb-remote' subsystem with a default option of 'packets' if
317 GDB_REMOTE_LOG_OPTION is not defined.
Johnny Chen9707bb62010-06-25 21:14:08 +0000318"""
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000319 sys.exit(0)
Johnny Chen9707bb62010-06-25 21:14:08 +0000320
321
Enrico Granata69d7c102013-05-07 00:36:28 +0000322def unique_string_match(yourentry,list):
323 candidate = None
324 for item in list:
325 if item.startswith(yourentry):
326 if candidate:
327 return None
328 candidate = item
329 return candidate
330
Johnny Chenaf149a02010-09-16 17:11:30 +0000331def parseOptionsAndInitTestdirs():
332 """Initialize the list of directories containing our unittest scripts.
333
334 '-h/--help as the first option prints out usage info and exit the program.
335 """
336
Johnny Chen4f93bf12010-12-10 00:51:23 +0000337 global dont_do_python_api_test
338 global just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +0000339 global just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +0000340 global dont_do_dsym_test
341 global dont_do_dwarf_test
Johnny Chen82e6b1e2010-12-01 22:47:54 +0000342 global blacklist
343 global blacklistConfig
Enrico Granataac3a8e22012-09-21 19:10:53 +0000344 global categoriesList
345 global validCategories
346 global useCategories
Sean Callanan0acf4c62012-10-24 22:45:39 +0000347 global lldbFrameworkPath
348 global lldbExecutablePath
Johnny Chen9fdb0a92010-09-18 00:16:47 +0000349 global configFile
Johnny Chen1a4d5e72011-03-04 01:35:22 +0000350 global archs
351 global compilers
Johnny Chend2acdb32010-11-16 22:42:58 +0000352 global count
Johnny Chenaf149a02010-09-16 17:11:30 +0000353 global delay
Johnny Chen50bc6382011-01-29 01:16:52 +0000354 global dumpSysPath
Johnny Chene00c9302011-10-10 22:03:44 +0000355 global bmExecutable
356 global bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +0000357 global bmIterationCount
Johnny Chen7d6d8442010-12-03 19:59:35 +0000358 global failfast
Johnny Chenc5fa0052011-07-29 22:54:56 +0000359 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000360 global fs4all
Johnny Chen7c52ff12010-09-27 23:29:54 +0000361 global ignore
Johnny Chen08967192011-11-18 00:19:29 +0000362 global progress_bar
Johnny Chen38f823c2011-10-11 01:30:27 +0000363 global runHooks
Johnny Chen028d8eb2011-11-17 19:57:27 +0000364 global skip_build_and_cleanup
365 global skip_long_running_test
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000366 global noHeaders
Daniel Malea361eb432013-02-15 21:31:37 +0000367 global parsable
Johnny Chen7c52ff12010-09-27 23:29:54 +0000368 global regexp
Johnny Chen548aefd2010-10-11 22:25:46 +0000369 global rdir
Johnny Chen125fc2b2010-10-21 16:55:35 +0000370 global sdir_name
Enrico Granata814c8132013-04-11 23:48:00 +0000371 global svn_silent
Johnny Chenaf149a02010-09-16 17:11:30 +0000372 global verbose
373 global testdirs
374
Jim Ingham4f347cb2011-04-13 21:11:41 +0000375 do_help = False
376
Greg Clayton4793e942012-09-04 15:42:49 +0000377 parser = argparse.ArgumentParser(description='description', prefix_chars='+-', add_help=False)
378 group = None
Johnny Chenaf149a02010-09-16 17:11:30 +0000379
Greg Clayton4793e942012-09-04 15:42:49 +0000380 # Helper function for boolean options (group will point to the current group when executing X)
381 X = lambda optstr, helpstr, **kwargs: group.add_argument(optstr, help=helpstr, action='store_true', **kwargs)
382
383 group = parser.add_argument_group('Help')
384 group.add_argument('-h', '--help', dest='h', action='store_true', help="Print this help message and exit. Add '-v' for more detailed help.")
385
386 # C and Python toolchain options
387 group = parser.add_argument_group('Toolchain options')
388 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'''))
389 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.'''))
390 # FIXME? This won't work for different extra flags according to each arch.
391 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
392 suggestions: do not lump the "-A arch1 -A arch2" together such that the -E option applies to only one of the architectures'''))
393 X('-D', 'Dump the Python sys.path variable')
394
395 # Test filtering options
396 group = parser.add_argument_group('Test filtering options')
397 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")
398 X('-a', "Don't do lldb Python API tests")
399 X('+a', "Just do lldb Python API tests. Do not specify along with '+a'", dest='plus_a')
400 X('+b', 'Just do benchmark tests', dest='plus_b')
401 group.add_argument('-b', metavar='blacklist', help='Read a blacklist file specified after this option')
Enrico Granata58b03a42012-12-14 00:07:09 +0000402 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 +0000403 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')
404 X('-l', "Don't skip long running tests")
405 group.add_argument('-p', metavar='pattern', help='Specify a regexp filename pattern for inclusion in the test suite')
406 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 +0000407 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 +0000408
409 # Configuration options
410 group = parser.add_argument_group('Configuration options')
411 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 +0000412 group.add_argument('--framework', metavar='framework-path', help='The path to LLDB.framework')
413 group.add_argument('--executable', metavar='executable-path', help='The path to the lldb executable')
Greg Clayton4793e942012-09-04 15:42:49 +0000414 group.add_argument('-e', metavar='benchmark-exe', help='Specify the full path of an executable used for benchmark purposes (see also: -x)')
415 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")
416 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')
417 group.add_argument('-r', metavar='dir', help="Similar to '-R', except that the directory must not exist before running this test driver")
418 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')
419 group.add_argument('-x', metavar='breakpoint-spec', help='Specify the breakpoint specification for the benchmark executable')
420 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.")
421 group.add_argument('-#', type=int, metavar='sharp', dest='sharp', help='Repeat the test suite for a specified number of times')
422
423 # Test-suite behaviour
424 group = parser.add_argument_group('Runtime behaviour options')
425 X('-d', 'Delay startup for 10 seconds (in order for the debugger to attach)')
426 X('-F', 'Fail fast. Stop the test suite on the first error/failure')
427 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")
428 X('-n', "Don't print the headers like build dir, lldb version, and svn info at all")
Jim Ingham75f260a2013-02-19 20:39:27 +0000429 X('-P', "Use the graphic progress bar.")
Daniel Malea361eb432013-02-15 21:31:37 +0000430 X('-q', "Don't print extra output from this script.")
Greg Clayton4793e942012-09-04 15:42:49 +0000431 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")
432 X('-t', 'Turn on tracing of lldb command and other detailed test executions')
Greg Claytonb85785c2013-02-08 21:52:32 +0000433 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 +0000434 X('-v', 'Do verbose mode of unittest framework (print out each test case invocation)')
435 X('-w', 'Insert some wait time (currently 0.5 sec) between consecutive test cases')
Enrico Granata814c8132013-04-11 23:48:00 +0000436 X('-T', 'Obtain and dump svn information for this checkout of LLDB (off by default)')
Greg Clayton4793e942012-09-04 15:42:49 +0000437
438 # Remove the reference to our helper function
439 del X
440
441 group = parser.add_argument_group('Test directories')
442 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.')
443 args = parser.parse_args()
444
445 platform_system = platform.system()
446 platform_machine = platform.machine()
Enrico Granata2d329242012-10-23 22:52:49 +0000447
Greg Claytonb85785c2013-02-08 21:52:32 +0000448 if args.unset_env_varnames:
449 for env_var in args.unset_env_varnames:
450 if env_var in os.environ:
451 # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
452 # is automatically translated into a corresponding call to unsetenv().
453 del os.environ[env_var]
454 #os.unsetenv(env_var)
455
Daniel Malea361eb432013-02-15 21:31:37 +0000456 # only print the args if being verbose (and parsable is off)
457 if args.v and not args.q:
Enrico Granata2d329242012-10-23 22:52:49 +0000458 print args
Greg Clayton4793e942012-09-04 15:42:49 +0000459
460 if args.h:
461 do_help = True
462
463 if args.archs:
464 archs = args.archs
465 else:
466 if platform_system == 'Darwin' and platform_machine == 'x86_64':
467 archs = ['x86_64', 'i386']
Johnny Chenaf149a02010-09-16 17:11:30 +0000468 else:
Greg Clayton4793e942012-09-04 15:42:49 +0000469 archs = [platform_machine]
470
Enrico Granataac3a8e22012-09-21 19:10:53 +0000471 if args.categoriesList:
Enrico Granata69d7c102013-05-07 00:36:28 +0000472 finalCategoriesList = []
Enrico Granataac3a8e22012-09-21 19:10:53 +0000473 for category in args.categoriesList:
Enrico Granata69d7c102013-05-07 00:36:28 +0000474 origCategory = category
Enrico Granataac3a8e22012-09-21 19:10:53 +0000475 if not(category in validCategories):
Enrico Granata69d7c102013-05-07 00:36:28 +0000476 category = unique_string_match(category,validCategories)
477 if not(category in validCategories) or category == None:
478 print "fatal error: category '" + origCategory + "' is not a valid category"
Enrico Granata2d329242012-10-23 22:52:49 +0000479 print "if you have added a new category, please edit dotest.py, adding your new category to validCategories"
480 print "else, please specify one or more of the following: " + str(validCategories.keys())
Enrico Granataac3a8e22012-09-21 19:10:53 +0000481 sys.exit(1)
Enrico Granata69d7c102013-05-07 00:36:28 +0000482 finalCategoriesList.append(category)
483 categoriesList = set(finalCategoriesList)
Enrico Granataac3a8e22012-09-21 19:10:53 +0000484 useCategories = True
485 else:
486 categoriesList = []
487
Greg Clayton4793e942012-09-04 15:42:49 +0000488 if args.compilers:
489 compilers = args.compilers
490 else:
491 compilers = ['clang']
492
493 if args.D:
494 dumpSysPath = True
495
496 if args.E:
497 cflags_extras = args.E
498 os.environ['CFLAGS_EXTRAS'] = cflags_extras
499
500 # argparse makes sure we have correct options
501 if args.N == 'dwarf':
502 dont_do_dwarf_test = True
503 elif args.N == 'dsym':
504 dont_do_dsym_test = True
505
506 if args.a:
507 dont_do_python_api_test = True
508
509 if args.plus_a:
510 if dont_do_python_api_test:
511 print "Warning: -a and +a can't both be specified! Using only -a"
512 else:
513 just_do_python_api_test = True
514
515 if args.plus_b:
516 just_do_benchmarks_test = True
517
518 if args.b:
519 if args.b.startswith('-'):
520 usage(parser)
521 blacklistFile = args.b
522 if not os.path.isfile(blacklistFile):
523 print 'Blacklist file:', blacklistFile, 'does not exist!'
524 usage(parser)
525 # Now read the blacklist contents and assign it to blacklist.
526 execfile(blacklistFile, globals(), blacklistConfig)
527 blacklist = blacklistConfig.get('blacklist')
528
529 if args.c:
530 if args.c.startswith('-'):
531 usage(parser)
532 configFile = args.c
533 if not os.path.isfile(configFile):
534 print 'Config file:', configFile, 'does not exist!'
535 usage(parser)
536
537 if args.d:
538 delay = True
539
540 if args.e:
541 if args.e.startswith('-'):
542 usage(parser)
543 bmExecutable = args.e
544 if not is_exe(bmExecutable):
545 usage(parser)
546
547 if args.F:
548 failfast = True
549
550 if args.f:
Enrico Granata58b03a42012-12-14 00:07:09 +0000551 if any([x.startswith('-') for x in args.f]):
Greg Clayton4793e942012-09-04 15:42:49 +0000552 usage(parser)
Enrico Granata58b03a42012-12-14 00:07:09 +0000553 filters.extend(args.f)
Greg Clayton4793e942012-09-04 15:42:49 +0000554
555 if args.g:
556 fs4all = False
557
558 if args.i:
559 ignore = True
560
561 if args.k:
562 runHooks.extend(args.k)
563
564 if args.l:
565 skip_long_running_test = False
566
Sean Callanan0acf4c62012-10-24 22:45:39 +0000567 if args.framework:
568 lldbFrameworkPath = args.framework
569
570 if args.executable:
571 lldbExecutablePath = args.executable
572
Greg Clayton4793e942012-09-04 15:42:49 +0000573 if args.n:
574 noHeaders = True
575
576 if args.p:
577 if args.p.startswith('-'):
578 usage(parser)
579 regexp = args.p
580
Daniel Malea361eb432013-02-15 21:31:37 +0000581 if args.q:
582 noHeaders = True
583 parsable = True
584
Jim Ingham75f260a2013-02-19 20:39:27 +0000585 if args.P:
586 progress_bar = True
587 verbose = 0
588
Greg Clayton4793e942012-09-04 15:42:49 +0000589 if args.R:
590 if args.R.startswith('-'):
591 usage(parser)
592 rdir = os.path.abspath(args.R)
593 if os.path.exists(rdir):
594 import shutil
595 print 'Removing tree:', rdir
596 shutil.rmtree(rdir)
597
598 if args.r:
599 if args.r.startswith('-'):
600 usage(parser)
601 rdir = os.path.abspath(args.r)
602 if os.path.exists(rdir):
603 print 'Relocated directory:', rdir, 'must not exist!'
604 usage(parser)
605
606 if args.S:
607 skip_build_and_cleanup = True
608
609 if args.s:
610 if args.s.startswith('-'):
611 usage(parser)
612 sdir_name = args.s
613
614 if args.t:
615 os.environ['LLDB_COMMAND_TRACE'] = 'YES'
616
Enrico Granata814c8132013-04-11 23:48:00 +0000617 if args.T:
618 svn_silent = False
619
Greg Clayton4793e942012-09-04 15:42:49 +0000620 if args.v:
621 verbose = 2
622
623 if args.w:
624 os.environ['LLDB_WAIT_BETWEEN_TEST_CASES'] = 'YES'
625
626 if args.X:
627 if args.X.startswith('-'):
628 usage(parser)
629 excluded.add(args.X)
630
631 if args.x:
632 if args.x.startswith('-'):
633 usage(parser)
634 bmBreakpointSpec = args.x
635
636 # argparse makes sure we have a number
637 if args.y:
638 bmIterationCount = args.y
639
640 # argparse makes sure we have a number
641 if args.sharp:
642 count = args.sharp
Johnny Chenaf149a02010-09-16 17:11:30 +0000643
Jim Ingham4f347cb2011-04-13 21:11:41 +0000644 if do_help == True:
Greg Clayton4793e942012-09-04 15:42:49 +0000645 usage(parser)
Jim Ingham4f347cb2011-04-13 21:11:41 +0000646
Johnny Chencc659ad2010-12-10 19:02:23 +0000647 # Do not specify both '-a' and '+a' at the same time.
648 if dont_do_python_api_test and just_do_python_api_test:
Greg Clayton4793e942012-09-04 15:42:49 +0000649 usage(parser)
Johnny Chencc659ad2010-12-10 19:02:23 +0000650
Johnny Chenaf149a02010-09-16 17:11:30 +0000651 # Gather all the dirs passed on the command line.
Greg Clayton4793e942012-09-04 15:42:49 +0000652 if len(args.args) > 0:
653 testdirs = map(os.path.abspath, args.args)
Johnny Chenaf149a02010-09-16 17:11:30 +0000654
Johnny Chen548aefd2010-10-11 22:25:46 +0000655 # If '-r dir' is specified, the tests should be run under the relocated
656 # directory. Let's copy the testdirs over.
657 if rdir:
658 from shutil import copytree, ignore_patterns
659
660 tmpdirs = []
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000661 orig_testdirs = testdirs[:]
Johnny Chen548aefd2010-10-11 22:25:46 +0000662 for srcdir in testdirs:
Johnny Chen1abe4c02012-03-20 00:33:51 +0000663 # For example, /Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/hello_watchpoint
664 # shall be split into ['/Volumes/data/lldb/svn/ToT/', 'functionalities/watchpoint/hello_watchpoint'].
665 # Utilize the relative path to the 'test' directory to make our destination dir path.
Greg Clayton4793e942012-09-04 15:42:49 +0000666 if ("test" + os.sep) in srcdir:
667 to_split_on = "test" + os.sep
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000668 else:
669 to_split_on = "test"
670 dstdir = os.path.join(rdir, srcdir.split(to_split_on)[1])
671 dstdir = dstdir.rstrip(os.sep)
Johnny Chen548aefd2010-10-11 22:25:46 +0000672 # Don't copy the *.pyc and .svn stuffs.
673 copytree(srcdir, dstdir, ignore=ignore_patterns('*.pyc', '.svn'))
674 tmpdirs.append(dstdir)
675
676 # This will be our modified testdirs.
677 testdirs = tmpdirs
678
679 # With '-r dir' specified, there's no cleanup of intermediate test files.
680 os.environ["LLDB_DO_CLEANUP"] = 'NO'
681
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000682 # If the original testdirs is ['test'], the make directory has already been copied
Johnny Chen548aefd2010-10-11 22:25:46 +0000683 # recursively and is contained within the rdir/test dir. For anything
684 # else, we would need to copy over the make directory and its contents,
685 # so that, os.listdir(rdir) looks like, for example:
686 #
687 # array_types conditional_break make
688 #
689 # where the make directory contains the Makefile.rules file.
Johnny Chen3bc7e5e2012-04-24 21:44:10 +0000690 if len(testdirs) != 1 or os.path.basename(orig_testdirs[0]) != 'test':
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000691 scriptdir = os.path.dirname(__file__)
Johnny Chen548aefd2010-10-11 22:25:46 +0000692 # Don't copy the .svn stuffs.
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000693 copytree(os.path.join(scriptdir, 'make'), os.path.join(rdir, 'make'),
Johnny Chen548aefd2010-10-11 22:25:46 +0000694 ignore=ignore_patterns('.svn'))
695
696 #print "testdirs:", testdirs
697
Johnny Chenb40056b2010-09-21 00:09:27 +0000698 # Source the configFile if specified.
699 # The side effect, if any, will be felt from this point on. An example
700 # config file may be these simple two lines:
701 #
702 # sys.stderr = open("/tmp/lldbtest-stderr", "w")
703 # sys.stdout = open("/tmp/lldbtest-stdout", "w")
704 #
705 # which will reassign the two file objects to sys.stderr and sys.stdout,
706 # respectively.
707 #
Johnny Chen8c130642012-08-22 17:53:02 +0000708 # See also lldb-trunk/examples/test/usage-config.
Johnny Chenac97a6b2012-04-16 18:55:15 +0000709 global config, pre_flight, post_flight
Johnny Chenb40056b2010-09-21 00:09:27 +0000710 if configFile:
711 # Pass config (a dictionary) as the locals namespace for side-effect.
712 execfile(configFile, globals(), config)
Johnny Chenac97a6b2012-04-16 18:55:15 +0000713 print "config:", config
714 if "pre_flight" in config:
715 pre_flight = config["pre_flight"]
716 if not callable(pre_flight):
717 print "fatal error: pre_flight is not callable, exiting."
718 sys.exit(1)
719 if "post_flight" in config:
720 post_flight = config["post_flight"]
721 if not callable(post_flight):
722 print "fatal error: post_flight is not callable, exiting."
723 sys.exit(1)
Johnny Chenb40056b2010-09-21 00:09:27 +0000724 #print "sys.stderr:", sys.stderr
725 #print "sys.stdout:", sys.stdout
726
Johnny Chenaf149a02010-09-16 17:11:30 +0000727
Johnny Chen9707bb62010-06-25 21:14:08 +0000728def setupSysPath():
Johnny Chen8a3c0432011-03-11 20:13:06 +0000729 """
730 Add LLDB.framework/Resources/Python to the search paths for modules.
731 As a side effect, we also discover the 'lldb' executable and export it here.
732 """
Johnny Chen9707bb62010-06-25 21:14:08 +0000733
Johnny Chen548aefd2010-10-11 22:25:46 +0000734 global rdir
735 global testdirs
Johnny Chen50bc6382011-01-29 01:16:52 +0000736 global dumpSysPath
Johnny Chenfe5f1ed2011-10-21 18:33:27 +0000737 global noHeaders
Johnny Chenb5fe80c2011-05-17 22:58:50 +0000738 global svn_info
Enrico Granata814c8132013-04-11 23:48:00 +0000739 global svn_silent
Sean Callanan0acf4c62012-10-24 22:45:39 +0000740 global lldbFrameworkPath
741 global lldbExecutablePath
Johnny Chen548aefd2010-10-11 22:25:46 +0000742
Johnny Chen9707bb62010-06-25 21:14:08 +0000743 # Get the directory containing the current script.
Johnny Chen4d162e52011-08-12 18:54:11 +0000744 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 +0000745 scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
746 else:
747 scriptPath = sys.path[0]
Johnny Chena1affab2010-07-03 03:41:59 +0000748 if not scriptPath.endswith('test'):
Johnny Chen9707bb62010-06-25 21:14:08 +0000749 print "This script expects to reside in lldb's test directory."
750 sys.exit(-1)
751
Johnny Chen548aefd2010-10-11 22:25:46 +0000752 if rdir:
753 # Set up the LLDB_TEST environment variable appropriately, so that the
754 # individual tests can be located relatively.
755 #
756 # See also lldbtest.TestBase.setUpClass(cls).
757 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
758 os.environ["LLDB_TEST"] = os.path.join(rdir, 'test')
759 else:
760 os.environ["LLDB_TEST"] = rdir
761 else:
762 os.environ["LLDB_TEST"] = scriptPath
Peter Collingbournef6c3de82011-06-20 19:06:45 +0000763
764 # Set up the LLDB_SRC environment variable, so that the tests can locate
765 # the LLDB source code.
766 os.environ["LLDB_SRC"] = os.path.join(sys.path[0], os.pardir)
767
Johnny Chen9de4ede2010-08-31 17:42:54 +0000768 pluginPath = os.path.join(scriptPath, 'plugins')
Johnny Chen8a3c0432011-03-11 20:13:06 +0000769 pexpectPath = os.path.join(scriptPath, 'pexpect-2.4')
Johnny Chen58f93922010-06-29 23:10:39 +0000770
Johnny Chen8a3c0432011-03-11 20:13:06 +0000771 # Append script dir, plugin dir, and pexpect dir to the sys.path.
Johnny Chenaf149a02010-09-16 17:11:30 +0000772 sys.path.append(scriptPath)
773 sys.path.append(pluginPath)
Johnny Chen8a3c0432011-03-11 20:13:06 +0000774 sys.path.append(pexpectPath)
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000775
Johnny Chen26901c82011-03-11 19:47:23 +0000776 # This is our base name component.
Johnny Chena1affab2010-07-03 03:41:59 +0000777 base = os.path.abspath(os.path.join(scriptPath, os.pardir))
Johnny Chen6a564a42011-02-15 18:50:19 +0000778
Johnny Chen26901c82011-03-11 19:47:23 +0000779 # These are for xcode build directories.
Johnny Chen6a564a42011-02-15 18:50:19 +0000780 xcode3_build_dir = ['build']
781 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
782 dbg = ['Debug']
Sean Callanand9d94632012-09-26 21:16:15 +0000783 dbc = ['DebugClang']
Johnny Chen6a564a42011-02-15 18:50:19 +0000784 rel = ['Release']
785 bai = ['BuildAndIntegration']
786 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
Johnny Chen26901c82011-03-11 19:47:23 +0000787
788 # Some of the tests can invoke the 'lldb' command directly.
789 # We'll try to locate the appropriate executable right here.
790
Sean Callanan0acf4c62012-10-24 22:45:39 +0000791 lldbExec = None
792 if lldbExecutablePath:
793 if is_exe(lldbExecutablePath):
794 lldbExec = lldbExecutablePath
Sean Callanan502000d2012-11-01 21:23:21 +0000795 lldbHere = lldbExec
Sean Callanan0acf4c62012-10-24 22:45:39 +0000796 else:
797 print lldbExecutablePath + " is not an executable"
798 sys.exit(-1)
Johnny Chen6033bed2011-08-26 00:00:01 +0000799 else:
Sean Callanan0acf4c62012-10-24 22:45:39 +0000800 # First, you can define an environment variable LLDB_EXEC specifying the
801 # full pathname of the lldb executable.
802 if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
803 lldbExec = os.environ["LLDB_EXEC"]
804 else:
805 lldbExec = None
806
807 executable = ['lldb']
808 dbgExec = os.path.join(base, *(xcode3_build_dir + dbg + executable))
809 dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
810 dbcExec = os.path.join(base, *(xcode3_build_dir + dbc + executable))
811 dbcExec2 = os.path.join(base, *(xcode4_build_dir + dbc + executable))
812 relExec = os.path.join(base, *(xcode3_build_dir + rel + executable))
813 relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
814 baiExec = os.path.join(base, *(xcode3_build_dir + bai + executable))
815 baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
816
817 # The 'lldb' executable built here in the source tree.
818 lldbHere = None
819 if is_exe(dbgExec):
820 lldbHere = dbgExec
821 elif is_exe(dbgExec2):
822 lldbHere = dbgExec2
823 elif is_exe(dbcExec):
824 lldbHere = dbcExec
825 elif is_exe(dbcExec2):
826 lldbHere = dbcExec2
827 elif is_exe(relExec):
828 lldbHere = relExec
829 elif is_exe(relExec2):
830 lldbHere = relExec2
831 elif is_exe(baiExec):
832 lldbHere = baiExec
833 elif is_exe(baiExec2):
834 lldbHere = baiExec2
835 elif lldbExec:
836 lldbHere = lldbExec
Sean Callanan502000d2012-11-01 21:23:21 +0000837
Sean Callanan0acf4c62012-10-24 22:45:39 +0000838 # One last chance to locate the 'lldb' executable.
839 if not lldbExec:
840 lldbExec = which('lldb')
841 if lldbHere and not lldbExec:
842 lldbExec = lldbHere
Daniel Malea2777b012013-02-06 16:55:07 +0000843 if lldbExec and not lldbHere:
844 lldbHere = lldbExec
Sean Callanan502000d2012-11-01 21:23:21 +0000845
846 if lldbHere:
847 os.environ["LLDB_HERE"] = lldbHere
Matt Kopeca964b092013-02-20 20:54:10 +0000848 os.environ["LLDB_LIB_DIR"] = os.path.split(lldbHere)[0]
Sean Callanan502000d2012-11-01 21:23:21 +0000849 if not noHeaders:
Matt Kopeca964b092013-02-20 20:54:10 +0000850 print "LLDB library dir:", os.environ["LLDB_LIB_DIR"]
Sean Callanan502000d2012-11-01 21:23:21 +0000851 os.system('%s -v' % lldbHere)
Johnny Chen26901c82011-03-11 19:47:23 +0000852
853 if not lldbExec:
854 print "The 'lldb' executable cannot be located. Some of the tests may not be run as a result."
855 else:
856 os.environ["LLDB_EXEC"] = lldbExec
Johnny Chen8904eb02011-10-28 00:59:00 +0000857 #print "The 'lldb' from PATH env variable", lldbExec
Filipe Cabecinhasc0566642012-08-08 15:05:04 +0000858
Daniel Malea2b606ab2013-03-13 20:50:05 +0000859 # Skip printing svn/git information when running in parsable (lit-test compatibility) mode
Enrico Granata814c8132013-04-11 23:48:00 +0000860 if not svn_silent and not parsable:
Daniel Malea2b606ab2013-03-13 20:50:05 +0000861 if os.path.isdir(os.path.join(base, '.svn')) and which("svn") is not None:
862 pipe = subprocess.Popen([which("svn"), "info", base], stdout = subprocess.PIPE)
863 svn_info = pipe.stdout.read()
864 elif os.path.isdir(os.path.join(base, '.git')) and which("git") is not None:
865 pipe = subprocess.Popen([which("git"), "svn", "info", base], stdout = subprocess.PIPE)
866 svn_info = pipe.stdout.read()
867 if not noHeaders:
868 print svn_info
Johnny Chen26901c82011-03-11 19:47:23 +0000869
870 global ignore
871
Johnny Chen9707bb62010-06-25 21:14:08 +0000872 lldbPath = None
Sean Callanan0acf4c62012-10-24 22:45:39 +0000873 if lldbFrameworkPath:
874 candidatePath = os.path.join(lldbFrameworkPath, 'Resources', 'Python')
875 if os.path.isfile(os.path.join(candidatePath, 'lldb/__init__.py')):
876 lldbPath = candidatePath
877 if not lldbPath:
878 print 'Resources/Python/lldb/__init__.py was not found in ' + lldbFrameworkPath
879 sys.exit(-1)
880 else:
881 # The '-i' option is used to skip looking for lldb.py in the build tree.
882 if ignore:
883 return
Jim Inghamaa93c932012-12-21 22:22:26 +0000884
885 # If our lldb supports the -P option, use it to find the python path:
886 init_in_python_dir = 'lldb/__init__.py'
887 import pexpect
888 lldb_dash_p_result = None
889
890 if lldbHere:
891 lldb_dash_p_result = pexpect.run("%s -P"%(lldbHere))
892 elif lldbExec:
893 lldb_dash_p_result = pexpect.run("%s -P"%(lldbExec))
894
895 if lldb_dash_p_result and not lldb_dash_p_result.startswith(("<", "lldb: invalid option:")):
896 lines = lldb_dash_p_result.splitlines()
897 if len(lines) == 1 and os.path.isfile(os.path.join(lines[0], init_in_python_dir)):
898 lldbPath = lines[0]
Daniel Malea21e32a62013-01-04 23:35:13 +0000899 if "linux" in sys.platform:
Matt Kopeca964b092013-02-20 20:54:10 +0000900 os.environ['LLDB_LIB_DIR'] = os.path.join(lldbPath, '..', '..')
Jim Inghamaa93c932012-12-21 22:22:26 +0000901
902 if not lldbPath:
903 dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
904 dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
905 dbcPath = os.path.join(base, *(xcode3_build_dir + dbc + python_resource_dir))
906 dbcPath2 = os.path.join(base, *(xcode4_build_dir + dbc + python_resource_dir))
907 relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
908 relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
909 baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
910 baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
Sean Callanan0acf4c62012-10-24 22:45:39 +0000911
Jim Inghamaa93c932012-12-21 22:22:26 +0000912 if os.path.isfile(os.path.join(dbgPath, init_in_python_dir)):
913 lldbPath = dbgPath
914 elif os.path.isfile(os.path.join(dbgPath2, init_in_python_dir)):
915 lldbPath = dbgPath2
916 elif os.path.isfile(os.path.join(dbcPath, init_in_python_dir)):
917 lldbPath = dbcPath
918 elif os.path.isfile(os.path.join(dbcPath2, init_in_python_dir)):
919 lldbPath = dbcPath2
920 elif os.path.isfile(os.path.join(relPath, init_in_python_dir)):
921 lldbPath = relPath
922 elif os.path.isfile(os.path.join(relPath2, init_in_python_dir)):
923 lldbPath = relPath2
924 elif os.path.isfile(os.path.join(baiPath, init_in_python_dir)):
925 lldbPath = baiPath
926 elif os.path.isfile(os.path.join(baiPath2, init_in_python_dir)):
927 lldbPath = baiPath2
928
Sean Callanan0acf4c62012-10-24 22:45:39 +0000929 if not lldbPath:
930 print 'This script requires lldb.py to be in either ' + dbgPath + ',',
931 print relPath + ', or ' + baiPath
932 sys.exit(-1)
Johnny Chen9707bb62010-06-25 21:14:08 +0000933
Jim Inghamaa93c932012-12-21 22:22:26 +0000934 # Some of the code that uses this path assumes it hasn't resolved the Versions... link.
935 # If the path we've constructed looks like that, then we'll strip out the Versions/A part.
936 (before, frameWithVersion, after) = lldbPath.rpartition("LLDB.framework/Versions/A")
937 if frameWithVersion != "" :
938 lldbPath = before + "LLDB.framework" + after
939
Enrico Granata0ad92972013-04-11 23:40:59 +0000940 lldbPath = os.path.abspath(lldbPath)
941
Enrico Granata01458ca2012-10-23 00:09:02 +0000942 # If tests need to find LLDB_FRAMEWORK, now they can do it
943 os.environ["LLDB_FRAMEWORK"] = os.path.dirname(os.path.dirname(lldbPath))
944
Johnny Chenaf149a02010-09-16 17:11:30 +0000945 # This is to locate the lldb.py module. Insert it right after sys.path[0].
946 sys.path[1:1] = [lldbPath]
Johnny Chen50bc6382011-01-29 01:16:52 +0000947 if dumpSysPath:
948 print "sys.path:", sys.path
Johnny Chen9707bb62010-06-25 21:14:08 +0000949
Johnny Chen9707bb62010-06-25 21:14:08 +0000950
Johnny Chencd0279d2010-09-20 18:07:50 +0000951def doDelay(delta):
952 """Delaying startup for delta-seconds to facilitate debugger attachment."""
953 def alarm_handler(*args):
954 raise Exception("timeout")
955
956 signal.signal(signal.SIGALRM, alarm_handler)
957 signal.alarm(delta)
958 sys.stdout.write("pid=%d\n" % os.getpid())
959 sys.stdout.write("Enter RET to proceed (or timeout after %d seconds):" %
960 delta)
961 sys.stdout.flush()
962 try:
963 text = sys.stdin.readline()
964 except:
965 text = ""
966 signal.alarm(0)
967 sys.stdout.write("proceeding...\n")
968 pass
969
970
Johnny Chen9707bb62010-06-25 21:14:08 +0000971def visit(prefix, dir, names):
972 """Visitor function for os.path.walk(path, visit, arg)."""
973
974 global suite
Johnny Chen7c52ff12010-09-27 23:29:54 +0000975 global regexp
Johnny Chenc5fa0052011-07-29 22:54:56 +0000976 global filters
Johnny Chenb62436b2010-10-06 20:40:56 +0000977 global fs4all
Johnny Chene9eae812012-01-18 05:15:00 +0000978 global excluded
979
980 if set(dir.split(os.sep)).intersection(excluded):
981 #print "Detected an excluded dir component: %s" % dir
982 return
Johnny Chen9707bb62010-06-25 21:14:08 +0000983
984 for name in names:
985 if os.path.isdir(os.path.join(dir, name)):
986 continue
987
988 if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
Johnny Chen7c52ff12010-09-27 23:29:54 +0000989 # Try to match the regexp pattern, if specified.
990 if regexp:
991 import re
992 if re.search(regexp, name):
993 #print "Filename: '%s' matches pattern: '%s'" % (name, regexp)
994 pass
995 else:
996 #print "Filename: '%s' does not match pattern: '%s'" % (name, regexp)
997 continue
998
Johnny Chen953864a2010-10-12 21:35:54 +0000999 # We found a match for our test. Add it to the suite.
Johnny Chen79723352010-10-12 15:53:22 +00001000
1001 # Update the sys.path first.
Johnny Chena85d7ee2010-06-26 00:19:32 +00001002 if not sys.path.count(dir):
Johnny Chen548aefd2010-10-11 22:25:46 +00001003 sys.path.insert(0, dir)
Johnny Chen9707bb62010-06-25 21:14:08 +00001004 base = os.path.splitext(name)[0]
Johnny Chenb62436b2010-10-06 20:40:56 +00001005
1006 # Thoroughly check the filterspec against the base module and admit
1007 # the (base, filterspec) combination only when it makes sense.
Johnny Chenc5fa0052011-07-29 22:54:56 +00001008 filterspec = None
1009 for filterspec in filters:
Johnny Chenb62436b2010-10-06 20:40:56 +00001010 # Optimistically set the flag to True.
1011 filtered = True
1012 module = __import__(base)
1013 parts = filterspec.split('.')
1014 obj = module
1015 for part in parts:
1016 try:
1017 parent, obj = obj, getattr(obj, part)
1018 except AttributeError:
1019 # The filterspec has failed.
1020 filtered = False
1021 break
Johnny Chenc5fa0052011-07-29 22:54:56 +00001022
Johnny Chendb4be602011-08-12 23:55:07 +00001023 # If filtered, we have a good filterspec. Add it.
Johnny Chenc5fa0052011-07-29 22:54:56 +00001024 if filtered:
Johnny Chendb4be602011-08-12 23:55:07 +00001025 #print "adding filter spec %s to module %s" % (filterspec, module)
1026 suite.addTests(
1027 unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
1028 continue
Johnny Chenc5fa0052011-07-29 22:54:56 +00001029
1030 # Forgo this module if the (base, filterspec) combo is invalid
1031 # and no '-g' option is specified
1032 if filters and fs4all and not filtered:
1033 continue
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001034
Johnny Chendb4be602011-08-12 23:55:07 +00001035 # Add either the filtered test case(s) (which is done before) or the entire test class.
1036 if not filterspec or not filtered:
Johnny Chenb62436b2010-10-06 20:40:56 +00001037 # A simple case of just the module name. Also the failover case
1038 # from the filterspec branch when the (base, filterspec) combo
1039 # doesn't make sense.
1040 suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
Johnny Chen9707bb62010-06-25 21:14:08 +00001041
1042
Johnny Chencd0279d2010-09-20 18:07:50 +00001043def lldbLoggings():
1044 """Check and do lldb loggings if necessary."""
1045
1046 # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
1047 # defined. Use ${LLDB_LOG} to specify the log file.
1048 ci = lldb.DBG.GetCommandInterpreter()
1049 res = lldb.SBCommandReturnObject()
1050 if ("LLDB_LOG" in os.environ):
1051 if ("LLDB_LOG_OPTION" in os.environ):
1052 lldb_log_option = os.environ["LLDB_LOG_OPTION"]
1053 else:
Johnny Chen8fd886c2010-12-08 01:25:21 +00001054 lldb_log_option = "event process expr state api"
Johnny Chencd0279d2010-09-20 18:07:50 +00001055 ci.HandleCommand(
Greg Clayton940b1032011-02-23 00:35:02 +00001056 "log enable -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option,
Johnny Chencd0279d2010-09-20 18:07:50 +00001057 res)
1058 if not res.Succeeded():
1059 raise Exception('log enable failed (check LLDB_LOG env variable.')
1060 # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
1061 # Use ${GDB_REMOTE_LOG} to specify the log file.
1062 if ("GDB_REMOTE_LOG" in os.environ):
1063 if ("GDB_REMOTE_LOG_OPTION" in os.environ):
1064 gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
1065 else:
Johnny Chen7ab8c852010-12-02 18:35:13 +00001066 gdb_remote_log_option = "packets process"
Johnny Chencd0279d2010-09-20 18:07:50 +00001067 ci.HandleCommand(
Johnny Chenc935a892011-06-21 19:25:45 +00001068 "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
Johnny Chencd0279d2010-09-20 18:07:50 +00001069 + gdb_remote_log_option,
1070 res)
1071 if not res.Succeeded():
1072 raise Exception('log enable failed (check GDB_REMOTE_LOG env variable.')
1073
Johnny Chen067022b2011-01-19 19:31:46 +00001074def getMyCommandLine():
Daniel Malea782e4742013-05-30 21:48:58 +00001075 ps = subprocess.Popen([which('ps'), '-o', "command=CMD", str(os.getpid())], stdout=subprocess.PIPE).communicate()[0]
Johnny Chen067022b2011-01-19 19:31:46 +00001076 lines = ps.split('\n')
1077 cmd_line = lines[1]
1078 return cmd_line
Johnny Chencd0279d2010-09-20 18:07:50 +00001079
Johnny Chend96b5682010-11-05 17:30:53 +00001080# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +00001081# #
1082# Execution of the test driver starts here #
1083# #
Johnny Chend96b5682010-11-05 17:30:53 +00001084# ======================================== #
Johnny Chencd0279d2010-09-20 18:07:50 +00001085
Johnny Chen2891bb02011-09-16 01:04:26 +00001086def checkDsymForUUIDIsNotOn():
Johnny Chen6a4e0872011-09-16 17:50:44 +00001087 cmd = ["defaults", "read", "com.apple.DebugSymbols"]
1088 pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1089 cmd_output = pipe.stdout.read()
Johnny Chen178c8d92011-09-16 18:03:19 +00001090 if cmd_output and "DBGFileMappedPaths = " in cmd_output:
Johnny Chen6a451482011-09-16 18:09:45 +00001091 print "%s =>" % ' '.join(cmd)
Johnny Chen6a4e0872011-09-16 17:50:44 +00001092 print cmd_output
Johnny Chen2891bb02011-09-16 01:04:26 +00001093 print "Disable automatic lookup and caching of dSYMs before running the test suite!"
1094 print "Exiting..."
1095 sys.exit(0)
1096
1097# On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
1098# does not exist before proceeding to running the test suite.
1099if sys.platform.startswith("darwin"):
1100 checkDsymForUUIDIsNotOn()
1101
Johnny Chen9707bb62010-06-25 21:14:08 +00001102#
Johnny Chenaf149a02010-09-16 17:11:30 +00001103# Start the actions by first parsing the options while setting up the test
1104# directories, followed by setting up the search paths for lldb utilities;
1105# then, we walk the directory trees and collect the tests into our test suite.
Johnny Chen9707bb62010-06-25 21:14:08 +00001106#
Johnny Chenaf149a02010-09-16 17:11:30 +00001107parseOptionsAndInitTestdirs()
Johnny Chen9707bb62010-06-25 21:14:08 +00001108setupSysPath()
Johnny Chen91960d32010-09-08 20:56:16 +00001109
1110#
1111# If '-d' is specified, do a delay of 10 seconds for the debugger to attach.
1112#
1113if delay:
Johnny Chencd0279d2010-09-20 18:07:50 +00001114 doDelay(10)
Johnny Chen91960d32010-09-08 20:56:16 +00001115
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001116#
Johnny Chen41998192010-10-01 22:59:49 +00001117# If '-l' is specified, do not skip the long running tests.
Johnny Chen028d8eb2011-11-17 19:57:27 +00001118if not skip_long_running_test:
Johnny Chen41998192010-10-01 22:59:49 +00001119 os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
1120
1121#
Johnny Chen79723352010-10-12 15:53:22 +00001122# Walk through the testdirs while collecting tests.
Johnny Chen49f2f7a2010-09-20 17:25:45 +00001123#
Johnny Chen9707bb62010-06-25 21:14:08 +00001124for testdir in testdirs:
1125 os.path.walk(testdir, visit, 'Test')
1126
Johnny Chenb40056b2010-09-21 00:09:27 +00001127#
Johnny Chen9707bb62010-06-25 21:14:08 +00001128# Now that we have loaded all the test cases, run the whole test suite.
Johnny Chenb40056b2010-09-21 00:09:27 +00001129#
Johnny Chencd0279d2010-09-20 18:07:50 +00001130
Johnny Chen1bfbd412010-06-29 19:44:16 +00001131# For the time being, let's bracket the test runner within the
1132# lldb.SBDebugger.Initialize()/Terminate() pair.
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001133import lldb, atexit
Johnny Chen6b6f5ba2010-10-14 16:36:49 +00001134# Update: the act of importing lldb now executes lldb.SBDebugger.Initialize(),
1135# there's no need to call it a second time.
1136#lldb.SBDebugger.Initialize()
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001137atexit.register(lambda: lldb.SBDebugger.Terminate())
Johnny Chen1bfbd412010-06-29 19:44:16 +00001138
Johnny Chen909e5a62010-07-01 22:52:57 +00001139# Create a singleton SBDebugger in the lldb namespace.
1140lldb.DBG = lldb.SBDebugger.Create()
1141
Johnny Chen4f93bf12010-12-10 00:51:23 +00001142# Put the blacklist in the lldb namespace, to be used by lldb.TestBase.
Johnny Chen82e6b1e2010-12-01 22:47:54 +00001143lldb.blacklist = blacklist
1144
Johnny Chenac97a6b2012-04-16 18:55:15 +00001145# The pre_flight and post_flight come from reading a config file.
1146lldb.pre_flight = pre_flight
1147lldb.post_flight = post_flight
1148def getsource_if_available(obj):
1149 """
1150 Return the text of the source code for an object if available. Otherwise,
1151 a print representation is returned.
1152 """
1153 import inspect
1154 try:
1155 return inspect.getsource(obj)
1156 except:
1157 return repr(obj)
1158
Daniel Malea361eb432013-02-15 21:31:37 +00001159if not noHeaders:
1160 print "lldb.pre_flight:", getsource_if_available(lldb.pre_flight)
1161 print "lldb.post_flight:", getsource_if_available(lldb.post_flight)
Johnny Chenac97a6b2012-04-16 18:55:15 +00001162
Johnny Chena3ed7d82012-04-06 00:56:05 +00001163# Put all these test decorators in the lldb namespace.
Johnny Chen4f93bf12010-12-10 00:51:23 +00001164lldb.dont_do_python_api_test = dont_do_python_api_test
1165lldb.just_do_python_api_test = just_do_python_api_test
Johnny Chen82ccf402011-07-30 01:39:58 +00001166lldb.just_do_benchmarks_test = just_do_benchmarks_test
Johnny Chena3ed7d82012-04-06 00:56:05 +00001167lldb.dont_do_dsym_test = dont_do_dsym_test
1168lldb.dont_do_dwarf_test = dont_do_dwarf_test
Johnny Chen4f93bf12010-12-10 00:51:23 +00001169
Johnny Chen028d8eb2011-11-17 19:57:27 +00001170# Do we need to skip build and cleanup?
1171lldb.skip_build_and_cleanup = skip_build_and_cleanup
1172
Johnny Chen5f2ed172011-10-20 18:43:28 +00001173# Put bmExecutable, bmBreakpointSpec, and bmIterationCount into the lldb namespace, too.
Johnny Chene00c9302011-10-10 22:03:44 +00001174lldb.bmExecutable = bmExecutable
1175lldb.bmBreakpointSpec = bmBreakpointSpec
Johnny Chen5f2ed172011-10-20 18:43:28 +00001176lldb.bmIterationCount = bmIterationCount
Johnny Chene00c9302011-10-10 22:03:44 +00001177
Johnny Chen38f823c2011-10-11 01:30:27 +00001178# And don't forget the runHooks!
1179lldb.runHooks = runHooks
1180
Johnny Chencd0279d2010-09-20 18:07:50 +00001181# Turn on lldb loggings if necessary.
1182lldbLoggings()
Johnny Chen909e5a62010-07-01 22:52:57 +00001183
Johnny Chen7987ac92010-08-09 20:40:52 +00001184# Install the control-c handler.
1185unittest2.signals.installHandler()
1186
Johnny Chen125fc2b2010-10-21 16:55:35 +00001187# If sdir_name is not specified through the '-s sdir_name' option, get a
1188# timestamp string and export it as LLDB_SESSION_DIR environment var. This will
1189# be used when/if we want to dump the session info of individual test cases
1190# later on.
Johnny Chence681462010-10-19 00:25:01 +00001191#
1192# See also TestBase.dumpSessionInfo() in lldbtest.py.
Johnny Chena73ad662012-08-16 19:15:21 +00001193import datetime
1194# The windows platforms don't like ':' in the pathname.
1195timestamp_started = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
Johnny Chen125fc2b2010-10-21 16:55:35 +00001196if not sdir_name:
Johnny Chena73ad662012-08-16 19:15:21 +00001197 sdir_name = timestamp_started
Peter Collingbourne132476f2011-06-20 23:55:53 +00001198os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), sdir_name)
Johnny Chen067022b2011-01-19 19:31:46 +00001199
Johnny Chenfe5f1ed2011-10-21 18:33:27 +00001200if not noHeaders:
1201 sys.stderr.write("\nSession logs for test failures/errors/unexpected successes"
1202 " will go into directory '%s'\n" % sdir_name)
1203 sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
Johnny Chence681462010-10-19 00:25:01 +00001204
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001205if not os.path.isdir(sdir_name):
1206 os.mkdir(sdir_name)
Enrico Granata571358f2013-06-19 21:48:09 +00001207where_to_save_session = os.getcwd()
Johnny Chena73ad662012-08-16 19:15:21 +00001208fname = os.path.join(sdir_name, "TestStarted")
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001209with open(fname, "w") as f:
Johnny Chena73ad662012-08-16 19:15:21 +00001210 print >> f, "Test started at: %s\n" % timestamp_started
Johnny Chenb5fe80c2011-05-17 22:58:50 +00001211 print >> f, svn_info
1212 print >> f, "Command invoked: %s\n" % getMyCommandLine()
1213
Johnny Chenb40056b2010-09-21 00:09:27 +00001214#
1215# Invoke the default TextTestRunner to run the test suite, possibly iterating
1216# over different configurations.
1217#
1218
Johnny Chenb40056b2010-09-21 00:09:27 +00001219iterArchs = False
Johnny Chenf032d902010-09-21 00:16:09 +00001220iterCompilers = False
Johnny Chenb40056b2010-09-21 00:09:27 +00001221
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001222if not archs and "archs" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001223 archs = config["archs"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001224
1225if isinstance(archs, list) and len(archs) >= 1:
1226 iterArchs = True
1227
1228if not compilers and "compilers" in config:
Johnny Chenb40056b2010-09-21 00:09:27 +00001229 compilers = config["compilers"]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001230
Johnny Chen92693b52012-03-09 02:11:37 +00001231#
1232# Add some intervention here to sanity check that the compilers requested are sane.
1233# If found not to be an executable program, the invalid one is dropped from the list.
1234for i in range(len(compilers)):
1235 c = compilers[i]
1236 if which(c):
1237 continue
1238 else:
1239 if sys.platform.startswith("darwin"):
1240 pipe = subprocess.Popen(['xcrun', '-find', c], stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1241 cmd_output = pipe.stdout.read()
1242 if cmd_output:
1243 if "not found" in cmd_output:
1244 print "dropping %s from the compilers used" % c
1245 compilers.remove(i)
1246 else:
1247 compilers[i] = cmd_output.split('\n')[0]
1248 print "'xcrun -find %s' returning %s" % (c, compilers[i])
1249
Daniel Malea361eb432013-02-15 21:31:37 +00001250if not parsable:
1251 print "compilers=%s" % str(compilers)
Johnny Chen92693b52012-03-09 02:11:37 +00001252
1253if not compilers or len(compilers) == 0:
1254 print "No eligible compiler found, exiting."
1255 sys.exit(1)
1256
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001257if isinstance(compilers, list) and len(compilers) >= 1:
1258 iterCompilers = True
Johnny Chenb40056b2010-09-21 00:09:27 +00001259
Johnny Chen953864a2010-10-12 21:35:54 +00001260# Make a shallow copy of sys.path, we need to manipulate the search paths later.
1261# This is only necessary if we are relocated and with different configurations.
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001262if rdir:
Johnny Chen953864a2010-10-12 21:35:54 +00001263 old_sys_path = sys.path[:]
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001264# If we iterate on archs or compilers, there is a chance we want to split stderr/stdout.
1265if iterArchs or iterCompilers:
Johnny Chen953864a2010-10-12 21:35:54 +00001266 old_stderr = sys.stderr
1267 old_stdout = sys.stdout
1268 new_stderr = None
1269 new_stdout = None
1270
Johnny Chend96b5682010-11-05 17:30:53 +00001271# Iterating over all possible architecture and compiler combinations.
Johnny Chenb40056b2010-09-21 00:09:27 +00001272for ia in range(len(archs) if iterArchs else 1):
1273 archConfig = ""
1274 if iterArchs:
Johnny Chen18a921f2010-09-30 17:11:58 +00001275 os.environ["ARCH"] = archs[ia]
Johnny Chenb40056b2010-09-21 00:09:27 +00001276 archConfig = "arch=%s" % archs[ia]
1277 for ic in range(len(compilers) if iterCompilers else 1):
1278 if iterCompilers:
Johnny Chen18a921f2010-09-30 17:11:58 +00001279 os.environ["CC"] = compilers[ic]
Johnny Chenb40056b2010-09-21 00:09:27 +00001280 configString = "%s compiler=%s" % (archConfig, compilers[ic])
1281 else:
1282 configString = archConfig
1283
Johnny Chenb40056b2010-09-21 00:09:27 +00001284 if iterArchs or iterCompilers:
Johnny Chen1a4d5e72011-03-04 01:35:22 +00001285 # Translate ' ' to '-' for pathname component.
1286 from string import maketrans
1287 tbl = maketrans(' ', '-')
1288 configPostfix = configString.translate(tbl)
1289
1290 # Check whether we need to split stderr/stdout into configuration
1291 # specific files.
1292 if old_stderr.name != '<stderr>' and config.get('split_stderr'):
1293 if new_stderr:
1294 new_stderr.close()
1295 new_stderr = open("%s.%s" % (old_stderr.name, configPostfix), "w")
1296 sys.stderr = new_stderr
1297 if old_stdout.name != '<stdout>' and config.get('split_stdout'):
1298 if new_stdout:
1299 new_stdout.close()
1300 new_stdout = open("%s.%s" % (old_stdout.name, configPostfix), "w")
1301 sys.stdout = new_stdout
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001302
Johnny Chen953864a2010-10-12 21:35:54 +00001303 # If we specified a relocated directory to run the test suite, do
1304 # the extra housekeeping to copy the testdirs to a configStringified
1305 # directory and to update sys.path before invoking the test runner.
1306 # The purpose is to separate the configuration-specific directories
1307 # from each other.
1308 if rdir:
Johnny Chen3bc7e5e2012-04-24 21:44:10 +00001309 from shutil import copytree, rmtree, ignore_patterns
Johnny Chen953864a2010-10-12 21:35:54 +00001310
Johnny Chen953864a2010-10-12 21:35:54 +00001311 newrdir = "%s.%s" % (rdir, configPostfix)
1312
1313 # Copy the tree to a new directory with postfix name configPostfix.
Johnny Chen3bc7e5e2012-04-24 21:44:10 +00001314 if os.path.exists(newrdir):
1315 rmtree(newrdir)
Johnny Chen953864a2010-10-12 21:35:54 +00001316 copytree(rdir, newrdir, ignore=ignore_patterns('*.pyc', '*.o', '*.d'))
1317
Filipe Cabecinhas0e1d06d2012-08-08 15:23:24 +00001318 # Update the LLDB_TEST environment variable to reflect new top
Johnny Chen953864a2010-10-12 21:35:54 +00001319 # level test directory.
1320 #
1321 # See also lldbtest.TestBase.setUpClass(cls).
1322 if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
1323 os.environ["LLDB_TEST"] = os.path.join(newrdir, 'test')
1324 else:
1325 os.environ["LLDB_TEST"] = newrdir
1326
1327 # And update the Python search paths for modules.
1328 sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
1329
1330 # Output the configuration.
Daniel Malea361eb432013-02-15 21:31:37 +00001331 if not parsable:
1332 sys.stderr.write("\nConfiguration: " + configString + "\n")
Johnny Chen953864a2010-10-12 21:35:54 +00001333
1334 #print "sys.stderr name is", sys.stderr.name
1335 #print "sys.stdout name is", sys.stdout.name
1336
1337 # First, write out the number of collected test cases.
Daniel Malea361eb432013-02-15 21:31:37 +00001338 if not parsable:
1339 sys.stderr.write(separator + "\n")
1340 sys.stderr.write("Collected %d test%s\n\n"
1341 % (suite.countTestCases(),
1342 suite.countTestCases() != 1 and "s" or ""))
Johnny Chen953864a2010-10-12 21:35:54 +00001343
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001344 class LLDBTestResult(unittest2.TextTestResult):
1345 """
Johnny Chen26be4532010-11-09 23:56:14 +00001346 Enforce a singleton pattern to allow introspection of test progress.
1347
1348 Overwrite addError(), addFailure(), and addExpectedFailure() methods
1349 to enable each test instance to track its failure/error status. It
1350 is used in the LLDB test framework to emit detailed trace messages
1351 to a log file for easier human inspection of test failres/errors.
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001352 """
1353 __singleton__ = None
Johnny Chen360dd372010-11-29 17:50:10 +00001354 __ignore_singleton__ = False
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001355
Enrico Granatabc0c5a62013-02-08 23:39:18 +00001356 @staticmethod
1357 def getTerminalSize():
1358 import os
1359 env = os.environ
1360 def ioctl_GWINSZ(fd):
1361 try:
1362 import fcntl, termios, struct, os
1363 cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
1364 '1234'))
1365 except:
1366 return
1367 return cr
1368 cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
1369 if not cr:
1370 try:
1371 fd = os.open(os.ctermid(), os.O_RDONLY)
1372 cr = ioctl_GWINSZ(fd)
1373 os.close(fd)
1374 except:
1375 pass
1376 if not cr:
1377 cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
1378 return int(cr[1]), int(cr[0])
1379
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001380 def __init__(self, *args):
Johnny Chen360dd372010-11-29 17:50:10 +00001381 if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
Johnny Chend2acdb32010-11-16 22:42:58 +00001382 raise Exception("LLDBTestResult instantiated more than once")
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001383 super(LLDBTestResult, self).__init__(*args)
1384 LLDBTestResult.__singleton__ = self
1385 # Now put this singleton into the lldb module namespace.
1386 lldb.test_result = self
Johnny Chen810042e2011-01-05 20:24:11 +00001387 # Computes the format string for displaying the counter.
1388 global suite
1389 counterWidth = len(str(suite.countTestCases()))
1390 self.fmt = "%" + str(counterWidth) + "d: "
Johnny Chenc87fd492011-01-05 22:50:11 +00001391 self.indentation = ' ' * (counterWidth + 2)
Johnny Chen810042e2011-01-05 20:24:11 +00001392 # This counts from 1 .. suite.countTestCases().
1393 self.counter = 0
Enrico Granatabc0c5a62013-02-08 23:39:18 +00001394 (width, height) = LLDBTestResult.getTerminalSize()
Enrico Granata77215892013-02-15 00:32:05 +00001395 self.progressbar = None
Jim Ingham75f260a2013-02-19 20:39:27 +00001396 global progress_bar
Daniel Malea361eb432013-02-15 21:31:37 +00001397 if width > 10 and not parsable and progress_bar:
Enrico Granata77215892013-02-15 00:32:05 +00001398 try:
1399 self.progressbar = progress.ProgressWithEvents(stdout=self.stream,start=0,end=suite.countTestCases(),width=width-10)
1400 except:
1401 self.progressbar = None
Johnny Chen810042e2011-01-05 20:24:11 +00001402
Daniel Malea361eb432013-02-15 21:31:37 +00001403 def _config_string(self, test):
1404 compiler = getattr(test, "getCompiler", None)
1405 arch = getattr(test, "getArchitecture", None)
1406 return "%s-%s" % (compiler() if compiler else "", arch() if arch else "")
1407
Johnny Chenbe452272012-04-19 21:33:55 +00001408 def _exc_info_to_string(self, err, test):
1409 """Overrides superclass TestResult's method in order to append
1410 our test config info string to the exception info string."""
1411 modified_exc_string = '%sConfig=%s-%s' % (super(LLDBTestResult, self)._exc_info_to_string(err, test),
1412 test.getArchitecture(),
1413 test.getCompiler())
1414 return modified_exc_string
1415
Johnny Chenc87fd492011-01-05 22:50:11 +00001416 def getDescription(self, test):
1417 doc_first_line = test.shortDescription()
1418 if self.descriptions and doc_first_line:
1419 return '\n'.join((str(test), self.indentation + doc_first_line))
1420 else:
1421 return str(test)
1422
Enrico Granataac3a8e22012-09-21 19:10:53 +00001423 def getCategoriesForTest(self,test):
Enrico Granata56e2c562013-02-27 02:37:12 +00001424 if hasattr(test,"_testMethodName"):
1425 test_method = getattr(test,"_testMethodName")
1426 test_method = getattr(test,test_method)
1427 else:
1428 test_method = None
1429 if test_method != None and hasattr(test_method,"getCategories"):
1430 test_categories = test_method.getCategories(test)
1431 elif hasattr(test,"getCategories"):
Enrico Granataac3a8e22012-09-21 19:10:53 +00001432 test_categories = test.getCategories()
1433 elif inspect.ismethod(test) and test.__self__ != None and hasattr(test.__self__,"getCategories"):
1434 test_categories = test.__self__.getCategories()
1435 else:
1436 test_categories = []
1437 if test_categories == None:
1438 test_categories = []
1439 return test_categories
1440
1441 def shouldSkipBecauseOfCategories(self,test):
1442 global useCategories
1443 import inspect
1444 if useCategories:
1445 global categoriesList
1446 test_categories = self.getCategoriesForTest(test)
1447 if len(test_categories) == 0 or len(categoriesList & set(test_categories)) == 0:
1448 return True
1449 return False
1450
1451 def hardMarkAsSkipped(self,test):
1452 getattr(test, test._testMethodName).__func__.__unittest_skip__ = True
1453 getattr(test, test._testMethodName).__func__.__unittest_skip_why__ = "test case does not fall in any category of interest for this run"
Enrico Granata571358f2013-06-19 21:48:09 +00001454 test.__class__.__unittest_skip__ = True
1455 test.__class__.__unittest_skip_why__ = "test case does not fall in any category of interest for this run"
Enrico Granataac3a8e22012-09-21 19:10:53 +00001456
Johnny Chen810042e2011-01-05 20:24:11 +00001457 def startTest(self, test):
Enrico Granataac3a8e22012-09-21 19:10:53 +00001458 if self.shouldSkipBecauseOfCategories(test):
1459 self.hardMarkAsSkipped(test)
Johnny Chen810042e2011-01-05 20:24:11 +00001460 self.counter += 1
1461 if self.showAll:
1462 self.stream.write(self.fmt % self.counter)
1463 super(LLDBTestResult, self).startTest(test)
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001464
Daniel Malea361eb432013-02-15 21:31:37 +00001465 def addSuccess(self, test):
1466 global parsable
1467 super(LLDBTestResult, self).addSuccess(test)
1468 if parsable:
1469 self.stream.write("PASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1470
Johnny Chence681462010-10-19 00:25:01 +00001471 def addError(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001472 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001473 global parsable
Johnny Chen63c2cba2010-10-29 22:20:36 +00001474 sdir_has_content = True
Johnny Chence681462010-10-19 00:25:01 +00001475 super(LLDBTestResult, self).addError(test, err)
1476 method = getattr(test, "markError", None)
1477 if method:
1478 method()
Daniel Malea361eb432013-02-15 21:31:37 +00001479 if parsable:
Daniel Maleae1dd3e52013-03-07 18:39:26 +00001480 self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
Johnny Chence681462010-10-19 00:25:01 +00001481
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001482 def addFailure(self, test, err):
Johnny Chen63c2cba2010-10-29 22:20:36 +00001483 global sdir_has_content
Enrico Granataac3a8e22012-09-21 19:10:53 +00001484 global failuresPerCategory
Daniel Malea361eb432013-02-15 21:31:37 +00001485 global parsable
Johnny Chen63c2cba2010-10-29 22:20:36 +00001486 sdir_has_content = True
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001487 super(LLDBTestResult, self).addFailure(test, err)
1488 method = getattr(test, "markFailure", None)
1489 if method:
1490 method()
Daniel Malea361eb432013-02-15 21:31:37 +00001491 if parsable:
1492 self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
Enrico Granataac3a8e22012-09-21 19:10:53 +00001493 if useCategories:
1494 test_categories = self.getCategoriesForTest(test)
1495 for category in test_categories:
1496 if category in failuresPerCategory:
1497 failuresPerCategory[category] = failuresPerCategory[category] + 1
1498 else:
1499 failuresPerCategory[category] = 1
Johnny Chen84a6d6f2010-10-15 01:18:29 +00001500
Enrico Granata21416a12013-02-23 01:05:23 +00001501 def addExpectedFailure(self, test, err, bugnumber):
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001502 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001503 global parsable
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001504 sdir_has_content = True
Enrico Granata21416a12013-02-23 01:05:23 +00001505 super(LLDBTestResult, self).addExpectedFailure(test, err, bugnumber)
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001506 method = getattr(test, "markExpectedFailure", None)
1507 if method:
Enrico Granata21416a12013-02-23 01:05:23 +00001508 method(err, bugnumber)
Daniel Malea361eb432013-02-15 21:31:37 +00001509 if parsable:
1510 self.stream.write("XFAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
Johnny Chendd2bb2c2010-11-03 18:17:03 +00001511
Johnny Chenf5b89092011-08-15 23:09:08 +00001512 def addSkip(self, test, reason):
1513 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001514 global parsable
Johnny Chenf5b89092011-08-15 23:09:08 +00001515 sdir_has_content = True
1516 super(LLDBTestResult, self).addSkip(test, reason)
1517 method = getattr(test, "markSkippedTest", None)
1518 if method:
1519 method()
Daniel Malea361eb432013-02-15 21:31:37 +00001520 if parsable:
1521 self.stream.write("UNSUPPORTED: LLDB (%s) :: %s (%s) \n" % (self._config_string(test), str(test), reason))
Johnny Chenf5b89092011-08-15 23:09:08 +00001522
Enrico Granata21416a12013-02-23 01:05:23 +00001523 def addUnexpectedSuccess(self, test, bugnumber):
Johnny Chenab2f0662011-05-06 20:30:22 +00001524 global sdir_has_content
Daniel Malea361eb432013-02-15 21:31:37 +00001525 global parsable
Johnny Chenab2f0662011-05-06 20:30:22 +00001526 sdir_has_content = True
Enrico Granata21416a12013-02-23 01:05:23 +00001527 super(LLDBTestResult, self).addUnexpectedSuccess(test, bugnumber)
Johnny Chenab2f0662011-05-06 20:30:22 +00001528 method = getattr(test, "markUnexpectedSuccess", None)
1529 if method:
Enrico Granata21416a12013-02-23 01:05:23 +00001530 method(bugnumber)
Daniel Malea361eb432013-02-15 21:31:37 +00001531 if parsable:
1532 self.stream.write("XPASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1533
1534 if parsable:
1535 v = 0
1536 elif progress_bar:
1537 v = 1
1538 else:
1539 v = verbose
Johnny Chenab2f0662011-05-06 20:30:22 +00001540
Johnny Chen26be4532010-11-09 23:56:14 +00001541 # Invoke the test runner.
Johnny Chend2acdb32010-11-16 22:42:58 +00001542 if count == 1:
Johnny Chen7d6d8442010-12-03 19:59:35 +00001543 result = unittest2.TextTestRunner(stream=sys.stderr,
Daniel Malea361eb432013-02-15 21:31:37 +00001544 verbosity=v,
Johnny Chen7d6d8442010-12-03 19:59:35 +00001545 failfast=failfast,
Johnny Chend2acdb32010-11-16 22:42:58 +00001546 resultclass=LLDBTestResult).run(suite)
1547 else:
Johnny Chend6e7ca22010-11-29 17:52:43 +00001548 # We are invoking the same test suite more than once. In this case,
1549 # mark __ignore_singleton__ flag as True so the signleton pattern is
1550 # not enforced.
Johnny Chen360dd372010-11-29 17:50:10 +00001551 LLDBTestResult.__ignore_singleton__ = True
Johnny Chend2acdb32010-11-16 22:42:58 +00001552 for i in range(count):
Daniel Malea361eb432013-02-15 21:31:37 +00001553
Johnny Chen7d6d8442010-12-03 19:59:35 +00001554 result = unittest2.TextTestRunner(stream=sys.stderr,
Daniel Malea361eb432013-02-15 21:31:37 +00001555 verbosity=v,
Johnny Chen7d6d8442010-12-03 19:59:35 +00001556 failfast=failfast,
Johnny Chen360dd372010-11-29 17:50:10 +00001557 resultclass=LLDBTestResult).run(suite)
Filipe Cabecinhasc0566642012-08-08 15:05:04 +00001558
Daniel Malea24765572013-02-20 20:12:11 +00001559 failed = failed or not result.wasSuccessful()
Johnny Chen1bfbd412010-06-29 19:44:16 +00001560
Daniel Malea361eb432013-02-15 21:31:37 +00001561if sdir_has_content and not parsable:
Johnny Chenab2f0662011-05-06 20:30:22 +00001562 sys.stderr.write("Session logs for test failures/errors/unexpected successes"
1563 " can be found in directory '%s'\n" % sdir_name)
Johnny Chen63c2cba2010-10-29 22:20:36 +00001564
Enrico Granataac3a8e22012-09-21 19:10:53 +00001565if useCategories and len(failuresPerCategory) > 0:
1566 sys.stderr.write("Failures per category:\n")
1567 for category in failuresPerCategory:
1568 sys.stderr.write("%s - %d\n" % (category,failuresPerCategory[category]))
1569
Enrico Granata571358f2013-06-19 21:48:09 +00001570os.chdir(where_to_save_session)
Johnny Chena73ad662012-08-16 19:15:21 +00001571fname = os.path.join(sdir_name, "TestFinished")
1572with open(fname, "w") as f:
1573 print >> f, "Test finished at: %s\n" % datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
1574
Johnny Chencd0279d2010-09-20 18:07:50 +00001575# Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1576# This should not be necessary now.
Johnny Chen83f6e512010-08-13 22:58:44 +00001577if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
Johnny Chen83f6e512010-08-13 22:58:44 +00001578 print "Terminating Test suite..."
1579 subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1580
Johnny Chen01f2a6a2010-08-10 20:23:55 +00001581# Exiting.
Daniel Malea24765572013-02-20 20:12:11 +00001582sys.exit(failed)