blob: 3063a91407bddaad01ac94d354e7f66fb2ec3a22 [file] [log] [blame]
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001"""
2A simple testing framework for lldb using python's unit testing framework.
3
4Tests for lldb are written as python scripts which take advantage of the script
5bridging provided by LLDB.framework to interact with lldb core.
6
7A specific naming pattern is followed by the .py script to be recognized as
8a module which implements a test scenario, namely, Test*.py.
9
10To specify the directories where "Test*.py" python test scripts are located,
11you need to pass in a list of directory names. By default, the current
12working directory is searched if nothing is specified on the command line.
13
14Type:
15
16./dotest.py -h
17
18for available options.
19"""
20
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000021from __future__ import absolute_import
Zachary Turnerc432c8f2015-10-28 17:43:26 +000022from __future__ import print_function
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000023
24# System modules
Zachary Turnerc432c8f2015-10-28 17:43:26 +000025import atexit
Zachary Turnerc432c8f2015-10-28 17:43:26 +000026import importlib
27import os
Zachary Turnerc432c8f2015-10-28 17:43:26 +000028import errno
29import platform
Zachary Turnerc432c8f2015-10-28 17:43:26 +000030import signal
31import socket
32import subprocess
33import sys
Zachary Turnerc432c8f2015-10-28 17:43:26 +000034import inspect
Zachary Turnerc432c8f2015-10-28 17:43:26 +000035
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000036# Third-party modules
Zachary Turnerc432c8f2015-10-28 17:43:26 +000037import six
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000038import unittest2
39
40# LLDB Modules
41import lldbsuite
Zachary Turner606e3a52015-12-08 01:15:30 +000042from . import configuration
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000043from . import dotest_args
44from . import lldbtest_config
45from . import test_categories
Zachary Turner905a9882015-12-07 21:23:41 +000046from . import result_formatter
Zachary Turnerb4733e62015-12-08 01:15:44 +000047from . import test_result
Zachary Turner905a9882015-12-07 21:23:41 +000048from .result_formatter import EventBuilder
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000049from ..support import seven
Zachary Turnerc432c8f2015-10-28 17:43:26 +000050
51def is_exe(fpath):
52 """Returns true if fpath is an executable."""
53 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
54
55def which(program):
56 """Returns the full path to a program; None otherwise."""
57 fpath, fname = os.path.split(program)
58 if fpath:
59 if is_exe(program):
60 return program
61 else:
62 for path in os.environ["PATH"].split(os.pathsep):
63 exe_file = os.path.join(path, program)
64 if is_exe(exe_file):
65 return exe_file
66 return None
67
68class _WritelnDecorator(object):
69 """Used to decorate file-like objects with a handy 'writeln' method"""
70 def __init__(self,stream):
71 self.stream = stream
72
73 def __getattr__(self, attr):
74 if attr in ('stream', '__getstate__'):
75 raise AttributeError(attr)
76 return getattr(self.stream,attr)
77
78 def writeln(self, arg=None):
79 if arg:
80 self.write(arg)
81 self.write('\n') # text-mode streams translate to \r\n if needed
82
83#
84# Global variables:
85#
Zachary Turnerc432c8f2015-10-28 17:43:26 +000086def usage(parser):
87 parser.print_help()
Zachary Turner606e3a52015-12-08 01:15:30 +000088 if configuration.verbose > 0:
Zachary Turnerc432c8f2015-10-28 17:43:26 +000089 print("""
90Examples:
91
92This is an example of using the -f option to pinpoint to a specific test class
93and test method to be run:
94
95$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
96----------------------------------------------------------------------
97Collected 1 test
98
99test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
100Test 'frame variable this' when stopped on a class constructor. ... ok
101
102----------------------------------------------------------------------
103Ran 1 test in 1.396s
104
105OK
106
107And this is an example of using the -p option to run a single file (the filename
108matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
109
110$ ./dotest.py -v -p ObjC
111----------------------------------------------------------------------
112Collected 4 tests
113
114test_break_with_dsym (TestObjCMethods.FoundationTestCase)
115Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
116test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
117Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
118test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
119Lookup objective-c data types and evaluate expressions. ... ok
120test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
121Lookup objective-c data types and evaluate expressions. ... ok
122
123----------------------------------------------------------------------
124Ran 4 tests in 16.661s
125
126OK
127
128Running of this script also sets up the LLDB_TEST environment variable so that
129individual test cases can locate their supporting files correctly. The script
130tries to set up Python's search paths for modules by looking at the build tree
131relative to this script. See also the '-i' option in the following example.
132
133Finally, this is an example of using the lldb.py module distributed/installed by
134Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
135option to add some delay between two tests. It uses ARCH=x86_64 to specify that
136as the architecture and CC=clang to specify the compiler used for the test run:
137
138$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
139
140Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
141----------------------------------------------------------------------
142Collected 2 tests
143
144test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
145Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
146test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
147Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
148
149----------------------------------------------------------------------
150Ran 2 tests in 5.659s
151
152OK
153
154The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
155notify the directory containing the session logs for test failures or errors.
156In case there is any test failure/error, a similar message is appended at the
157end of the stderr output for your convenience.
158
159ENABLING LOGS FROM TESTS
160
161Option 1:
162
163Writing logs into different files per test case::
164
165This option is particularly useful when multiple dotest instances are created
166by dosep.py
167
168$ ./dotest.py --channel "lldb all"
169
170$ ./dotest.py --channel "lldb all" --channel "gdb-remote packets"
171
172These log files are written to:
173
174<session-dir>/<test-id>-host.log (logs from lldb host process)
175<session-dir>/<test-id>-server.log (logs from debugserver/lldb-server)
176<session-dir>/<test-id>-<test-result>.log (console logs)
177
178By default, logs from successful runs are deleted. Use the --log-success flag
179to create reference logs for debugging.
180
181$ ./dotest.py --log-success
182
183Option 2: (DEPRECATED)
184
185The following options can only enable logs from the host lldb process.
186Only categories from the "lldb" or "gdb-remote" channels can be enabled
187They also do not automatically enable logs in locally running debug servers.
188Also, logs from all test case are written into each log file
189
190o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
191 with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
192
193o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
194 'process.gdb-remote' subsystem with a default option of 'packets' if
195 GDB_REMOTE_LOG_OPTION is not defined.
196
197""")
198 sys.exit(0)
199
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000200def parseOptionsAndInitTestdirs():
201 """Initialize the list of directories containing our unittest scripts.
202
203 '-h/--help as the first option prints out usage info and exit the program.
204 """
205
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000206 do_help = False
207
208 platform_system = platform.system()
209 platform_machine = platform.machine()
210
211 parser = dotest_args.create_parser()
212 args = dotest_args.parse_args(parser, sys.argv[1:])
213
214 if args.unset_env_varnames:
215 for env_var in args.unset_env_varnames:
216 if env_var in os.environ:
217 # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
218 # is automatically translated into a corresponding call to unsetenv().
219 del os.environ[env_var]
220 #os.unsetenv(env_var)
221
222 if args.set_env_vars:
223 for env_var in args.set_env_vars:
224 parts = env_var.split('=', 1)
225 if len(parts) == 1:
226 os.environ[parts[0]] = ""
227 else:
228 os.environ[parts[0]] = parts[1]
229
230 # only print the args if being verbose (and parsable is off)
231 if args.v and not args.q:
232 print(sys.argv)
233
234 if args.h:
235 do_help = True
236
237 if args.compilers:
Zachary Turner606e3a52015-12-08 01:15:30 +0000238 configuration.compilers = args.compilers
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000239 else:
240 # Use a compiler appropriate appropriate for the Apple SDK if one was specified
241 if platform_system == 'Darwin' and args.apple_sdk:
Zachary Turner606e3a52015-12-08 01:15:30 +0000242 configuration.compilers = [seven.get_command_output('xcrun -sdk "%s" -find clang 2> /dev/null' % (args.apple_sdk))]
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000243 else:
244 # 'clang' on ubuntu 14.04 is 3.4 so we try clang-3.5 first
245 candidateCompilers = ['clang-3.5', 'clang', 'gcc']
246 for candidate in candidateCompilers:
247 if which(candidate):
Zachary Turner606e3a52015-12-08 01:15:30 +0000248 configuration.compilers = [candidate]
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000249 break
250
251 if args.channels:
252 lldbtest_config.channels = args.channels
253
254 if args.log_success:
255 lldbtest_config.log_success = args.log_success
256
257 # Set SDKROOT if we are using an Apple SDK
258 if platform_system == 'Darwin' and args.apple_sdk:
Zachary Turnerbb03a462015-11-03 18:55:22 +0000259 os.environ['SDKROOT'] = seven.get_command_output('xcrun --sdk "%s" --show-sdk-path 2> /dev/null' % (args.apple_sdk))
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000260
261 if args.archs:
Zachary Turner606e3a52015-12-08 01:15:30 +0000262 configuration.archs = args.archs
263 for arch in configuration.archs:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000264 if arch.startswith('arm') and platform_system == 'Darwin' and not args.apple_sdk:
Zachary Turnerbb03a462015-11-03 18:55:22 +0000265 os.environ['SDKROOT'] = seven.get_command_output('xcrun --sdk iphoneos.internal --show-sdk-path 2> /dev/null')
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000266 if not os.path.exists(os.environ['SDKROOT']):
Zachary Turnerbb03a462015-11-03 18:55:22 +0000267 os.environ['SDKROOT'] = seven.get_command_output('xcrun --sdk iphoneos --show-sdk-path 2> /dev/null')
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000268 else:
Zachary Turner606e3a52015-12-08 01:15:30 +0000269 configuration.archs = [platform_machine]
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000270
271 if args.categoriesList:
Zachary Turner606e3a52015-12-08 01:15:30 +0000272 configuration.categoriesList = set(test_categories.validate(args.categoriesList, False))
273 configuration.useCategories = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000274 else:
Zachary Turner606e3a52015-12-08 01:15:30 +0000275 configuration.categoriesList = []
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000276
277 if args.skipCategories:
Zachary Turner606e3a52015-12-08 01:15:30 +0000278 configuration.skipCategories = test_categories.validate(args.skipCategories, False)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000279
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000280 if args.E:
281 cflags_extras = args.E
282 os.environ['CFLAGS_EXTRAS'] = cflags_extras
283
284 # argparse makes sure we have correct options
285 if args.N == 'dwarf':
Zachary Turner606e3a52015-12-08 01:15:30 +0000286 configuration.dont_do_dwarf_test = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000287 elif args.N == 'dwo':
Zachary Turner606e3a52015-12-08 01:15:30 +0000288 configuration.dont_do_dwo_test = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000289 elif args.N == 'dsym':
Zachary Turner606e3a52015-12-08 01:15:30 +0000290 configuration.dont_do_dsym_test = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000291
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000292 if args.d:
293 sys.stdout.write("Suspending the process %d to wait for debugger to attach...\n" % os.getpid())
294 sys.stdout.flush()
295 os.kill(os.getpid(), signal.SIGSTOP)
296
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000297 if args.f:
298 if any([x.startswith('-') for x in args.f]):
299 usage(parser)
Zachary Turner606e3a52015-12-08 01:15:30 +0000300 configuration.filters.extend(args.f)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000301 # Shut off multiprocessing mode when additional filters are specified.
302 # The rational is that the user is probably going after a very specific
303 # test and doesn't need a bunch of parallel test runners all looking for
304 # it in a frenzy. Also, '-v' now spits out all test run output even
305 # on success, so the standard recipe for redoing a failing test (with -v
306 # and a -f to filter to the specific test) now causes all test scanning
307 # (in parallel) to print results for do-nothing runs in a very distracting
308 # manner. If we really need filtered parallel runs in the future, consider
309 # adding a --no-output-on-success that prevents -v from setting
310 # output-on-success.
Zachary Turner606e3a52015-12-08 01:15:30 +0000311 configuration.no_multiprocess_test_runner = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000312
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000313 if args.l:
Zachary Turner606e3a52015-12-08 01:15:30 +0000314 configuration.skip_long_running_test = False
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000315
316 if args.framework:
Zachary Turner606e3a52015-12-08 01:15:30 +0000317 configuration.lldbFrameworkPath = args.framework
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000318
319 if args.executable:
320 lldbtest_config.lldbExec = args.executable
321
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000322 if args.p:
323 if args.p.startswith('-'):
324 usage(parser)
Zachary Turner606e3a52015-12-08 01:15:30 +0000325 configuration.regexp = args.p
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000326
327 if args.q:
Zachary Turner606e3a52015-12-08 01:15:30 +0000328 configuration.parsable = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000329
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000330 if args.s:
331 if args.s.startswith('-'):
332 usage(parser)
Zachary Turner606e3a52015-12-08 01:15:30 +0000333 configuration.sdir_name = args.s
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000334
335 if args.t:
336 os.environ['LLDB_COMMAND_TRACE'] = 'YES'
337
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000338 if args.v:
Zachary Turner606e3a52015-12-08 01:15:30 +0000339 configuration.verbose = 2
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000340
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000341 # argparse makes sure we have a number
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000342 if args.sharp:
Zachary Turner606e3a52015-12-08 01:15:30 +0000343 configuration.count = args.sharp
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000344
345 if sys.platform.startswith('win32'):
346 os.environ['LLDB_DISABLE_CRASH_DIALOG'] = str(args.disable_crash_dialog)
Zachary Turner80310c22015-12-10 18:51:02 +0000347 os.environ['LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE'] = str(True)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000348
349 if do_help == True:
350 usage(parser)
351
352 if args.no_multiprocess:
Zachary Turner606e3a52015-12-08 01:15:30 +0000353 configuration.no_multiprocess_test_runner = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000354
355 if args.inferior:
Zachary Turner606e3a52015-12-08 01:15:30 +0000356 configuration.is_inferior_test_runner = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000357
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000358 if args.num_threads:
Zachary Turner606e3a52015-12-08 01:15:30 +0000359 configuration.num_threads = args.num_threads
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000360
361 if args.test_subdir:
Zachary Turner606e3a52015-12-08 01:15:30 +0000362 configuration.multiprocess_test_subdir = args.test_subdir
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000363
364 if args.test_runner_name:
Zachary Turner606e3a52015-12-08 01:15:30 +0000365 configuration.test_runner_name = args.test_runner_name
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000366
367 # Capture test results-related args.
Todd Fialacee6a6a2015-11-09 18:51:04 +0000368 if args.curses and not args.inferior:
369 # Act as if the following args were set.
370 args.results_formatter = "lldbsuite.test.curses_results.Curses"
371 args.results_file = "stdout"
372
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000373 if args.results_file:
Zachary Turner606e3a52015-12-08 01:15:30 +0000374 configuration.results_filename = args.results_file
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000375
376 if args.results_port:
Zachary Turner606e3a52015-12-08 01:15:30 +0000377 configuration.results_port = args.results_port
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000378
379 if args.results_file and args.results_port:
380 sys.stderr.write(
381 "only one of --results-file and --results-port should "
382 "be specified\n")
383 usage(args)
384
385 if args.results_formatter:
Zachary Turner606e3a52015-12-08 01:15:30 +0000386 configuration.results_formatter_name = args.results_formatter
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000387 if args.results_formatter_options:
Zachary Turner606e3a52015-12-08 01:15:30 +0000388 configuration.results_formatter_options = args.results_formatter_options
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000389
Todd Fialab68dbfa22015-12-11 22:29:34 +0000390 # Default to using the BasicResultsFormatter if no formatter is specified
391 # and we're not a test inferior.
392 if not args.inferior and configuration.results_formatter_name is None:
393 configuration.results_formatter_name = (
394 "lldbsuite.test.basic_results_formatter.BasicResultsFormatter")
395
Todd Fiala93153922015-12-12 19:26:56 +0000396 # rerun-related arguments
397 configuration.rerun_all_issues = args.rerun_all_issues
398
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000399 if args.lldb_platform_name:
Zachary Turner606e3a52015-12-08 01:15:30 +0000400 configuration.lldb_platform_name = args.lldb_platform_name
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000401 if args.lldb_platform_url:
Zachary Turner606e3a52015-12-08 01:15:30 +0000402 configuration.lldb_platform_url = args.lldb_platform_url
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000403 if args.lldb_platform_working_dir:
Zachary Turner606e3a52015-12-08 01:15:30 +0000404 configuration.lldb_platform_working_dir = args.lldb_platform_working_dir
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000405
406 if args.event_add_entries and len(args.event_add_entries) > 0:
407 entries = {}
408 # Parse out key=val pairs, separated by comma
409 for keyval in args.event_add_entries.split(","):
410 key_val_entry = keyval.split("=")
411 if len(key_val_entry) == 2:
412 (key, val) = key_val_entry
413 val_parts = val.split(':')
414 if len(val_parts) > 1:
415 (val, val_type) = val_parts
416 if val_type == 'int':
417 val = int(val)
418 entries[key] = val
419 # Tell the event builder to create all events with these
420 # key/val pairs in them.
421 if len(entries) > 0:
Zachary Turner905a9882015-12-07 21:23:41 +0000422 result_formatter.EventBuilder.add_entries_to_all_events(entries)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000423
424 # Gather all the dirs passed on the command line.
425 if len(args.args) > 0:
Zachary Turner606e3a52015-12-08 01:15:30 +0000426 configuration.testdirs = list(map(os.path.abspath, args.args))
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000427 # Shut off multiprocessing mode when test directories are specified.
Zachary Turner606e3a52015-12-08 01:15:30 +0000428 configuration.no_multiprocess_test_runner = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000429
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000430 #print("testdirs:", testdirs)
431
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000432def getXcodeOutputPaths(lldbRootDirectory):
433 result = []
434
435 # These are for xcode build directories.
436 xcode3_build_dir = ['build']
437 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
438
439 configurations = [['Debug'], ['DebugClang'], ['Release'], ['BuildAndIntegration']]
440 xcode_build_dirs = [xcode3_build_dir, xcode4_build_dir]
441 for configuration in configurations:
442 for xcode_build_dir in xcode_build_dirs:
443 outputPath = os.path.join(lldbRootDirectory, *(xcode_build_dir+configuration) )
444 result.append(outputPath)
445
446 return result
447
448
449def createSocketToLocalPort(port):
450 def socket_closer(s):
451 """Close down an opened socket properly."""
452 s.shutdown(socket.SHUT_RDWR)
453 s.close()
454
455 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
456 sock.connect(("localhost", port))
457 return (sock, lambda: socket_closer(sock))
458
459
460def setupTestResults():
461 """Sets up test results-related objects based on arg settings."""
Todd Fiala51831472015-12-09 06:45:43 +0000462 # Setup the results formatter configuration.
463 formatter_config = result_formatter.FormatterConfig()
464 formatter_config.filename = configuration.results_filename
465 formatter_config.formatter_name = configuration.results_formatter_name
466 formatter_config.formatter_options = (
467 configuration.results_formatter_options)
468 formatter_config.port = configuration.results_port
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000469
Todd Fialade029392015-12-08 00:53:56 +0000470 # Create the results formatter.
Todd Fiala51831472015-12-09 06:45:43 +0000471 formatter_spec = result_formatter.create_results_formatter(
472 formatter_config)
Todd Fialade029392015-12-08 00:53:56 +0000473 if formatter_spec is not None and formatter_spec.formatter is not None:
Zachary Turner606e3a52015-12-08 01:15:30 +0000474 configuration.results_formatter_object = formatter_spec.formatter
Todd Fiala194913f2015-12-02 21:12:17 +0000475
Todd Fialade029392015-12-08 00:53:56 +0000476 # Send an intialize message to the formatter.
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000477 initialize_event = EventBuilder.bare_event("initialize")
478 if isMultiprocessTestRunner():
Todd Fiala51831472015-12-09 06:45:43 +0000479 if (configuration.test_runner_name is not None and
480 configuration.test_runner_name == "serial"):
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000481 # Only one worker queue here.
482 worker_count = 1
483 else:
484 # Workers will be the number of threads specified.
Zachary Turner606e3a52015-12-08 01:15:30 +0000485 worker_count = configuration.num_threads
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000486 else:
487 worker_count = 1
488 initialize_event["worker_count"] = worker_count
489
Todd Fialade029392015-12-08 00:53:56 +0000490 formatter_spec.formatter.handle_event(initialize_event)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000491
Todd Fialade029392015-12-08 00:53:56 +0000492 # Make sure we clean up the formatter on shutdown.
493 if formatter_spec.cleanup_func is not None:
494 atexit.register(formatter_spec.cleanup_func)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000495
496
497def getOutputPaths(lldbRootDirectory):
498 """
499 Returns typical build output paths for the lldb executable
500
501 lldbDirectory - path to the root of the lldb svn/git repo
502 """
503 result = []
504
505 if sys.platform == 'darwin':
506 result.extend(getXcodeOutputPaths(lldbRootDirectory))
507
508 # cmake builds? look for build or build/host folder next to llvm directory
509 # lldb is located in llvm/tools/lldb so we need to go up three levels
510 llvmParentDir = os.path.abspath(os.path.join(lldbRootDirectory, os.pardir, os.pardir, os.pardir))
511 result.append(os.path.join(llvmParentDir, 'build', 'bin'))
512 result.append(os.path.join(llvmParentDir, 'build', 'host', 'bin'))
513
514 # some cmake developers keep their build directory beside their lldb directory
515 lldbParentDir = os.path.abspath(os.path.join(lldbRootDirectory, os.pardir))
516 result.append(os.path.join(lldbParentDir, 'build', 'bin'))
517 result.append(os.path.join(lldbParentDir, 'build', 'host', 'bin'))
518
519 return result
520
521def setupSysPath():
522 """
523 Add LLDB.framework/Resources/Python to the search paths for modules.
524 As a side effect, we also discover the 'lldb' executable and export it here.
525 """
526
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000527 # Get the directory containing the current script.
528 if "DOTEST_PROFILE" in os.environ and "DOTEST_SCRIPT_DIR" in os.environ:
529 scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
530 else:
531 scriptPath = os.path.dirname(os.path.realpath(__file__))
532 if not scriptPath.endswith('test'):
533 print("This script expects to reside in lldb's test directory.")
534 sys.exit(-1)
535
Zachary Turner6a188e62015-12-11 19:21:34 +0000536 os.environ["LLDB_TEST"] = scriptPath
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000537
538 # Set up the LLDB_SRC environment variable, so that the tests can locate
539 # the LLDB source code.
540 os.environ["LLDB_SRC"] = lldbsuite.lldb_root
541
542 pluginPath = os.path.join(scriptPath, 'plugins')
543 toolsLLDBMIPath = os.path.join(scriptPath, 'tools', 'lldb-mi')
544 toolsLLDBServerPath = os.path.join(scriptPath, 'tools', 'lldb-server')
545
546 # Insert script dir, plugin dir, lldb-mi dir and lldb-server dir to the sys.path.
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000547 sys.path.insert(0, pluginPath)
548 sys.path.insert(0, toolsLLDBMIPath) # Adding test/tools/lldb-mi to the path makes it easy
549 # to "import lldbmi_testcase" from the MI tests
550 sys.path.insert(0, toolsLLDBServerPath) # Adding test/tools/lldb-server to the path makes it easy
551 # to "import lldbgdbserverutils" from the lldb-server tests
552
553 # This is the root of the lldb git/svn checkout
554 # When this changes over to a package instead of a standalone script, this
555 # will be `lldbsuite.lldb_root`
556 lldbRootDirectory = lldbsuite.lldb_root
557
558 # Some of the tests can invoke the 'lldb' command directly.
559 # We'll try to locate the appropriate executable right here.
560
561 # The lldb executable can be set from the command line
562 # if it's not set, we try to find it now
563 # first, we try the environment
564 if not lldbtest_config.lldbExec:
565 # First, you can define an environment variable LLDB_EXEC specifying the
566 # full pathname of the lldb executable.
567 if "LLDB_EXEC" in os.environ:
568 lldbtest_config.lldbExec = os.environ["LLDB_EXEC"]
569
570 if not lldbtest_config.lldbExec:
571 outputPaths = getOutputPaths(lldbRootDirectory)
572 for outputPath in outputPaths:
573 candidatePath = os.path.join(outputPath, 'lldb')
574 if is_exe(candidatePath):
575 lldbtest_config.lldbExec = candidatePath
576 break
577
578 if not lldbtest_config.lldbExec:
579 # Last, check the path
580 lldbtest_config.lldbExec = which('lldb')
581
582 if lldbtest_config.lldbExec and not is_exe(lldbtest_config.lldbExec):
583 print("'{}' is not a path to a valid executable".format(lldbtest_config.lldbExec))
584 lldbtest_config.lldbExec = None
585
586 if not lldbtest_config.lldbExec:
587 print("The 'lldb' executable cannot be located. Some of the tests may not be run as a result.")
588 sys.exit(-1)
589
590 lldbLibDir = os.path.dirname(lldbtest_config.lldbExec) # confusingly, this is the "bin" directory
591 os.environ["LLDB_LIB_DIR"] = lldbLibDir
592 lldbImpLibDir = os.path.join(lldbLibDir, '..', 'lib') if sys.platform.startswith('win32') else lldbLibDir
593 os.environ["LLDB_IMPLIB_DIR"] = lldbImpLibDir
Zachary Turner35a76102015-12-09 20:48:42 +0000594 print("LLDB library dir:", os.environ["LLDB_LIB_DIR"])
595 print("LLDB import library dir:", os.environ["LLDB_IMPLIB_DIR"])
596 os.system('%s -v' % lldbtest_config.lldbExec)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000597
598 # Assume lldb-mi is in same place as lldb
599 # If not found, disable the lldb-mi tests
600 lldbMiExec = None
601 if lldbtest_config.lldbExec and is_exe(lldbtest_config.lldbExec + "-mi"):
602 lldbMiExec = lldbtest_config.lldbExec + "-mi"
603 if not lldbMiExec:
Zachary Turnerb4733e62015-12-08 01:15:44 +0000604 if not configuration.shouldSkipBecauseOfCategories(["lldb-mi"]):
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000605 print("The 'lldb-mi' executable cannot be located. The lldb-mi tests can not be run as a result.")
Zachary Turner606e3a52015-12-08 01:15:30 +0000606 configuration.skipCategories.append("lldb-mi")
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000607 else:
608 os.environ["LLDBMI_EXEC"] = lldbMiExec
609
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000610 lldbPythonDir = None # The directory that contains 'lldb/__init__.py'
Zachary Turner606e3a52015-12-08 01:15:30 +0000611 if configuration.lldbFrameworkPath:
612 candidatePath = os.path.join(configuration.lldbFrameworkPath, 'Resources', 'Python')
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000613 if os.path.isfile(os.path.join(candidatePath, 'lldb/__init__.py')):
614 lldbPythonDir = candidatePath
615 if not lldbPythonDir:
Zachary Turner606e3a52015-12-08 01:15:30 +0000616 print('Resources/Python/lldb/__init__.py was not found in ' + configuration.lldbFrameworkPath)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000617 sys.exit(-1)
618 else:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000619 # If our lldb supports the -P option, use it to find the python path:
620 init_in_python_dir = os.path.join('lldb', '__init__.py')
621
Zachary Turnerbbc5b462015-11-04 01:03:47 +0000622 lldb_dash_p_result = subprocess.check_output([lldbtest_config.lldbExec, "-P"], stderr=subprocess.STDOUT, universal_newlines=True)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000623
624 if lldb_dash_p_result and not lldb_dash_p_result.startswith(("<", "lldb: invalid option:")) \
625 and not lldb_dash_p_result.startswith("Traceback"):
626 lines = lldb_dash_p_result.splitlines()
627
628 # Workaround for readline vs libedit issue on FreeBSD. If stdout
629 # is not a terminal Python executes
630 # rl_variable_bind ("enable-meta-key", "off");
631 # This produces a warning with FreeBSD's libedit because the
632 # enable-meta-key variable is unknown. Not an issue on Apple
633 # because cpython commit f0ab6f9f0603 added a #ifndef __APPLE__
634 # around the call. See http://bugs.python.org/issue19884 for more
635 # information. For now we just discard the warning output.
636 if len(lines) >= 1 and lines[0].startswith("bind: Invalid command"):
637 lines.pop(0)
638
639 # Taking the last line because lldb outputs
640 # 'Cannot read termcap database;\nusing dumb terminal settings.\n'
641 # before the path
642 if len(lines) >= 1 and os.path.isfile(os.path.join(lines[-1], init_in_python_dir)):
643 lldbPythonDir = lines[-1]
644 if "freebsd" in sys.platform or "linux" in sys.platform:
645 os.environ['LLDB_LIB_DIR'] = os.path.join(lldbPythonDir, '..', '..')
646
647 if not lldbPythonDir:
648 if platform.system() == "Darwin":
649 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
650 outputPaths = getXcodeOutputPaths()
651 for outputPath in outputPaths:
652 candidatePath = os.path.join(outputPath, python_resource_dir)
653 if os.path.isfile(os.path.join(candidatePath, init_in_python_dir)):
654 lldbPythonDir = candidatePath
655 break
656
657 if not lldbPythonDir:
658 print('This script requires lldb.py to be in either ' + dbgPath + ',', end=' ')
659 print(relPath + ', or ' + baiPath + '. Some tests might fail.')
660 else:
661 print("Unable to load lldb extension module. Possible reasons for this include:")
662 print(" 1) LLDB was built with LLDB_DISABLE_PYTHON=1")
663 print(" 2) PYTHONPATH and PYTHONHOME are not set correctly. PYTHONHOME should refer to")
664 print(" the version of Python that LLDB built and linked against, and PYTHONPATH")
665 print(" should contain the Lib directory for the same python distro, as well as the")
666 print(" location of LLDB\'s site-packages folder.")
667 print(" 3) A different version of Python than that which was built against is exported in")
668 print(" the system\'s PATH environment variable, causing conflicts.")
669 print(" 4) The executable '%s' could not be found. Please check " % lldbExecutable)
670 print(" that it exists and is executable.")
671
672 if lldbPythonDir:
673 lldbPythonDir = os.path.normpath(lldbPythonDir)
674 # Some of the code that uses this path assumes it hasn't resolved the Versions... link.
675 # If the path we've constructed looks like that, then we'll strip out the Versions/A part.
676 (before, frameWithVersion, after) = lldbPythonDir.rpartition("LLDB.framework/Versions/A")
677 if frameWithVersion != "" :
678 lldbPythonDir = before + "LLDB.framework" + after
679
680 lldbPythonDir = os.path.abspath(lldbPythonDir)
681
682 # If tests need to find LLDB_FRAMEWORK, now they can do it
683 os.environ["LLDB_FRAMEWORK"] = os.path.dirname(os.path.dirname(lldbPythonDir))
684
685 # This is to locate the lldb.py module. Insert it right after sys.path[0].
686 sys.path[1:1] = [lldbPythonDir]
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000687
688def visit(prefix, dir, names):
689 """Visitor function for os.path.walk(path, visit, arg)."""
690
Zachary Turner50671582015-12-08 20:36:22 +0000691 dir_components = set(dir.split(os.sep))
692 excluded_components = set(['.svn', '.git'])
693 if dir_components.intersection(excluded_components):
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000694 #print("Detected an excluded dir component: %s" % dir)
695 return
696
697 for name in names:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000698 if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
699
Zachary Turner606e3a52015-12-08 01:15:30 +0000700 if name in configuration.all_tests:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000701 raise Exception("Found multiple tests with the name %s" % name)
Zachary Turner606e3a52015-12-08 01:15:30 +0000702 configuration.all_tests.add(name)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000703
704 # Try to match the regexp pattern, if specified.
Zachary Turner606e3a52015-12-08 01:15:30 +0000705 if configuration.regexp:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000706 import re
Zachary Turner606e3a52015-12-08 01:15:30 +0000707 if re.search(configuration.regexp, name):
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000708 #print("Filename: '%s' matches pattern: '%s'" % (name, regexp))
709 pass
710 else:
711 #print("Filename: '%s' does not match pattern: '%s'" % (name, regexp))
712 continue
713
714 # We found a match for our test. Add it to the suite.
715
716 # Update the sys.path first.
717 if not sys.path.count(dir):
718 sys.path.insert(0, dir)
719 base = os.path.splitext(name)[0]
720
721 # Thoroughly check the filterspec against the base module and admit
722 # the (base, filterspec) combination only when it makes sense.
723 filterspec = None
Zachary Turner606e3a52015-12-08 01:15:30 +0000724 for filterspec in configuration.filters:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000725 # Optimistically set the flag to True.
726 filtered = True
727 module = __import__(base)
728 parts = filterspec.split('.')
729 obj = module
730 for part in parts:
731 try:
732 parent, obj = obj, getattr(obj, part)
733 except AttributeError:
734 # The filterspec has failed.
735 filtered = False
736 break
737
738 # If filtered, we have a good filterspec. Add it.
739 if filtered:
740 #print("adding filter spec %s to module %s" % (filterspec, module))
Zachary Turner606e3a52015-12-08 01:15:30 +0000741 configuration.suite.addTests(
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000742 unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
743 continue
744
745 # Forgo this module if the (base, filterspec) combo is invalid
Zachary Turner75446022015-12-08 18:48:53 +0000746 if configuration.filters and not filtered:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000747 continue
748
749 # Add either the filtered test case(s) (which is done before) or the entire test class.
750 if not filterspec or not filtered:
751 # A simple case of just the module name. Also the failover case
752 # from the filterspec branch when the (base, filterspec) combo
753 # doesn't make sense.
Zachary Turner606e3a52015-12-08 01:15:30 +0000754 configuration.suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000755
756
757def disabledynamics():
758 import lldb
759 ci = lldb.DBG.GetCommandInterpreter()
760 res = lldb.SBCommandReturnObject()
761 ci.HandleCommand("setting set target.prefer-dynamic-value no-dynamic-values", res, False)
762 if not res.Succeeded():
763 raise Exception('disabling dynamic type support failed')
764
765def lldbLoggings():
766 import lldb
767 """Check and do lldb loggings if necessary."""
768
769 # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
770 # defined. Use ${LLDB_LOG} to specify the log file.
771 ci = lldb.DBG.GetCommandInterpreter()
772 res = lldb.SBCommandReturnObject()
773 if ("LLDB_LOG" in os.environ):
774 open(os.environ["LLDB_LOG"], 'w').close()
775 if ("LLDB_LOG_OPTION" in os.environ):
776 lldb_log_option = os.environ["LLDB_LOG_OPTION"]
777 else:
778 lldb_log_option = "event process expr state api"
779 ci.HandleCommand(
780 "log enable -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option,
781 res)
782 if not res.Succeeded():
783 raise Exception('log enable failed (check LLDB_LOG env variable)')
784
785 if ("LLDB_LINUX_LOG" in os.environ):
786 open(os.environ["LLDB_LINUX_LOG"], 'w').close()
787 if ("LLDB_LINUX_LOG_OPTION" in os.environ):
788 lldb_log_option = os.environ["LLDB_LINUX_LOG_OPTION"]
789 else:
790 lldb_log_option = "event process expr state api"
791 ci.HandleCommand(
792 "log enable -n -f " + os.environ["LLDB_LINUX_LOG"] + " linux " + lldb_log_option,
793 res)
794 if not res.Succeeded():
795 raise Exception('log enable failed (check LLDB_LINUX_LOG env variable)')
796
797 # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
798 # Use ${GDB_REMOTE_LOG} to specify the log file.
799 if ("GDB_REMOTE_LOG" in os.environ):
800 if ("GDB_REMOTE_LOG_OPTION" in os.environ):
801 gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
802 else:
803 gdb_remote_log_option = "packets process"
804 ci.HandleCommand(
805 "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
806 + gdb_remote_log_option,
807 res)
808 if not res.Succeeded():
809 raise Exception('log enable failed (check GDB_REMOTE_LOG env variable)')
810
811def getMyCommandLine():
812 return ' '.join(sys.argv)
813
814# ======================================== #
815# #
816# Execution of the test driver starts here #
817# #
818# ======================================== #
819
820def checkDsymForUUIDIsNotOn():
821 cmd = ["defaults", "read", "com.apple.DebugSymbols"]
822 pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
823 cmd_output = pipe.stdout.read()
824 if cmd_output and "DBGFileMappedPaths = " in cmd_output:
825 print("%s =>" % ' '.join(cmd))
826 print(cmd_output)
827 print("Disable automatic lookup and caching of dSYMs before running the test suite!")
828 print("Exiting...")
829 sys.exit(0)
830
831def exitTestSuite(exitCode = None):
832 import lldb
833 lldb.SBDebugger.Terminate()
834 if exitCode:
835 sys.exit(exitCode)
836
837
838def isMultiprocessTestRunner():
839 # We're not multiprocess when we're either explicitly
840 # the inferior (as specified by the multiprocess test
841 # runner) OR we've been told to skip using the multiprocess
842 # test runner
Zachary Turner606e3a52015-12-08 01:15:30 +0000843 return not (configuration.is_inferior_test_runner or configuration.no_multiprocess_test_runner)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000844
Enrico Granata5f92a132015-11-05 00:46:25 +0000845def getVersionForSDK(sdk):
846 sdk = str.lower(sdk)
847 full_path = seven.get_command_output('xcrun -sdk %s --show-sdk-path' % sdk)
848 basename = os.path.basename(full_path)
849 basename = os.path.splitext(basename)[0]
850 basename = str.lower(basename)
851 ver = basename.replace(sdk, '')
852 return ver
853
854def getPathForSDK(sdk):
855 sdk = str.lower(sdk)
856 full_path = seven.get_command_output('xcrun -sdk %s --show-sdk-path' % sdk)
857 if os.path.exists(full_path): return full_path
858 return None
859
860def setDefaultTripleForPlatform():
Zachary Turner606e3a52015-12-08 01:15:30 +0000861 if configuration.lldb_platform_name == 'ios-simulator':
Enrico Granata5f92a132015-11-05 00:46:25 +0000862 triple_str = 'x86_64-apple-ios%s' % (getVersionForSDK('iphonesimulator'))
863 os.environ['TRIPLE'] = triple_str
864 return {'TRIPLE':triple_str}
865 return {}
866
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000867def run_suite():
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000868 # On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
869 # does not exist before proceeding to running the test suite.
870 if sys.platform.startswith("darwin"):
871 checkDsymForUUIDIsNotOn()
872
873 #
874 # Start the actions by first parsing the options while setting up the test
875 # directories, followed by setting up the search paths for lldb utilities;
876 # then, we walk the directory trees and collect the tests into our test suite.
877 #
878 parseOptionsAndInitTestdirs()
879
880 # Setup test results (test results formatter and output handling).
881 setupTestResults()
882
883 # If we are running as the multiprocess test runner, kick off the
884 # multiprocess test runner here.
885 if isMultiprocessTestRunner():
Zachary Turnerc1b7cd72015-11-05 19:22:28 +0000886 from . import dosep
Zachary Turner80310c22015-12-10 18:51:02 +0000887 dosep.main(configuration.num_threads, configuration.multiprocess_test_subdir,
Zachary Turner606e3a52015-12-08 01:15:30 +0000888 configuration.test_runner_name, configuration.results_formatter_object)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000889 raise Exception("should never get here")
Zachary Turner606e3a52015-12-08 01:15:30 +0000890 elif configuration.is_inferior_test_runner:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000891 # Shut off Ctrl-C processing in inferiors. The parallel
892 # test runner handles this more holistically.
893 signal.signal(signal.SIGINT, signal.SIG_IGN)
894
895 setupSysPath()
Pavel Labath9cbf7dd2015-12-08 13:32:07 +0000896 configuration.setupCrashInfoHook()
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000897
898 #
899 # If '-l' is specified, do not skip the long running tests.
Zachary Turner606e3a52015-12-08 01:15:30 +0000900 if not configuration.skip_long_running_test:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000901 os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
902
903 # For the time being, let's bracket the test runner within the
904 # lldb.SBDebugger.Initialize()/Terminate() pair.
905 import lldb
906
907 # Create a singleton SBDebugger in the lldb namespace.
908 lldb.DBG = lldb.SBDebugger.Create()
909
Zachary Turner606e3a52015-12-08 01:15:30 +0000910 if configuration.lldb_platform_name:
911 print("Setting up remote platform '%s'" % (configuration.lldb_platform_name))
912 lldb.remote_platform = lldb.SBPlatform(configuration.lldb_platform_name)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000913 if not lldb.remote_platform.IsValid():
Zachary Turner606e3a52015-12-08 01:15:30 +0000914 print("error: unable to create the LLDB platform named '%s'." % (configuration.lldb_platform_name))
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000915 exitTestSuite(1)
Zachary Turner606e3a52015-12-08 01:15:30 +0000916 if configuration.lldb_platform_url:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000917 # We must connect to a remote platform if a LLDB platform URL was specified
Zachary Turner606e3a52015-12-08 01:15:30 +0000918 print("Connecting to remote platform '%s' at '%s'..." % (configuration.lldb_platform_name, configuration.lldb_platform_url))
919 platform_connect_options = lldb.SBPlatformConnectOptions(configuration.lldb_platform_url)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000920 err = lldb.remote_platform.ConnectRemote(platform_connect_options)
921 if err.Success():
922 print("Connected.")
923 else:
Zachary Turner606e3a52015-12-08 01:15:30 +0000924 print("error: failed to connect to remote platform using URL '%s': %s" % (configuration.lldb_platform_url, err))
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000925 exitTestSuite(1)
926 else:
Zachary Turner606e3a52015-12-08 01:15:30 +0000927 configuration.lldb_platform_url = None
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000928
Enrico Granata5f92a132015-11-05 00:46:25 +0000929 platform_changes = setDefaultTripleForPlatform()
930 first = True
931 for key in platform_changes:
932 if first:
933 print("Environment variables setup for platform support:")
934 first = False
935 print("%s = %s" % (key,platform_changes[key]))
936
Zachary Turner606e3a52015-12-08 01:15:30 +0000937 if configuration.lldb_platform_working_dir:
938 print("Setting remote platform working directory to '%s'..." % (configuration.lldb_platform_working_dir))
939 lldb.remote_platform.SetWorkingDirectory(configuration.lldb_platform_working_dir)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000940 lldb.DBG.SetSelectedPlatform(lldb.remote_platform)
941 else:
942 lldb.remote_platform = None
Zachary Turner606e3a52015-12-08 01:15:30 +0000943 configuration.lldb_platform_working_dir = None
944 configuration.lldb_platform_url = None
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000945
946 target_platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
947
948 # By default, both dsym, dwarf and dwo tests are performed.
949 # Use @dsym_test, @dwarf_test or @dwo_test decorators, defined in lldbtest.py, to mark a test as
950 # a dsym, dwarf or dwo test. Use '-N dsym', '-N dwarf' or '-N dwo' to exclude dsym, dwarf or
951 # dwo tests from running.
Zachary Turner606e3a52015-12-08 01:15:30 +0000952 configuration.dont_do_dsym_test = configuration.dont_do_dsym_test \
953 or any(platform in target_platform for platform in ["linux", "freebsd", "windows"])
954 configuration.dont_do_dwo_test = configuration.dont_do_dwo_test \
955 or any(platform in target_platform for platform in ["darwin", "macosx", "ios"])
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000956
957 # Don't do debugserver tests on everything except OS X.
Zachary Turner606e3a52015-12-08 01:15:30 +0000958 configuration.dont_do_debugserver_test = "linux" in target_platform or "freebsd" in target_platform or "windows" in target_platform
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000959
960 # Don't do lldb-server (llgs) tests on anything except Linux.
Zachary Turner606e3a52015-12-08 01:15:30 +0000961 configuration.dont_do_llgs_test = not ("linux" in target_platform)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000962
963 #
964 # Walk through the testdirs while collecting tests.
965 #
Zachary Turner606e3a52015-12-08 01:15:30 +0000966 for testdir in configuration.testdirs:
Zachary Turnere6ba0532015-11-05 01:33:54 +0000967 for (dirpath, dirnames, filenames) in os.walk(testdir):
968 visit('Test', dirpath, filenames)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000969
970 #
971 # Now that we have loaded all the test cases, run the whole test suite.
972 #
973
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000974 # Turn on lldb loggings if necessary.
975 lldbLoggings()
976
977 # Disable default dynamic types for testing purposes
978 disabledynamics()
979
980 # Install the control-c handler.
981 unittest2.signals.installHandler()
982
983 # If sdir_name is not specified through the '-s sdir_name' option, get a
984 # timestamp string and export it as LLDB_SESSION_DIR environment var. This will
985 # be used when/if we want to dump the session info of individual test cases
986 # later on.
987 #
988 # See also TestBase.dumpSessionInfo() in lldbtest.py.
989 import datetime
990 # The windows platforms don't like ':' in the pathname.
991 timestamp_started = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
Zachary Turner606e3a52015-12-08 01:15:30 +0000992 if not configuration.sdir_name:
993 configuration.sdir_name = timestamp_started
994 os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), configuration.sdir_name)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000995
Zachary Turner35a76102015-12-09 20:48:42 +0000996 sys.stderr.write("\nSession logs for test failures/errors/unexpected successes"
997 " will go into directory '%s'\n" % configuration.sdir_name)
998 sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000999
Zachary Turner606e3a52015-12-08 01:15:30 +00001000 if not os.path.isdir(configuration.sdir_name):
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001001 try:
Zachary Turner606e3a52015-12-08 01:15:30 +00001002 os.mkdir(configuration.sdir_name)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001003 except OSError as exception:
1004 if exception.errno != errno.EEXIST:
1005 raise
1006 where_to_save_session = os.getcwd()
Zachary Turner606e3a52015-12-08 01:15:30 +00001007 fname = os.path.join(configuration.sdir_name, "TestStarted-%d" % os.getpid())
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001008 with open(fname, "w") as f:
1009 print("Test started at: %s\n" % timestamp_started, file=f)
Zachary Turner606e3a52015-12-08 01:15:30 +00001010 print(configuration.svn_info, file=f)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001011 print("Command invoked: %s\n" % getMyCommandLine(), file=f)
1012
1013 #
1014 # Invoke the default TextTestRunner to run the test suite, possibly iterating
1015 # over different configurations.
1016 #
1017
1018 iterArchs = False
1019 iterCompilers = False
1020
Zachary Turner606e3a52015-12-08 01:15:30 +00001021 if isinstance(configuration.archs, list) and len(configuration.archs) >= 1:
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001022 iterArchs = True
1023
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001024 #
1025 # Add some intervention here to sanity check that the compilers requested are sane.
1026 # If found not to be an executable program, the invalid one is dropped from the list.
Zachary Turner606e3a52015-12-08 01:15:30 +00001027 for i in range(len(configuration.compilers)):
1028 c = configuration.compilers[i]
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001029 if which(c):
1030 continue
1031 else:
1032 if sys.platform.startswith("darwin"):
1033 pipe = subprocess.Popen(['xcrun', '-find', c], stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1034 cmd_output = pipe.stdout.read()
1035 if cmd_output:
1036 if "not found" in cmd_output:
1037 print("dropping %s from the compilers used" % c)
Zachary Turner606e3a52015-12-08 01:15:30 +00001038 configuration.compilers.remove(i)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001039 else:
Zachary Turner606e3a52015-12-08 01:15:30 +00001040 configuration.compilers[i] = cmd_output.split('\n')[0]
1041 print("'xcrun -find %s' returning %s" % (c, configuration.compilers[i]))
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001042
Zachary Turner606e3a52015-12-08 01:15:30 +00001043 if not configuration.parsable:
1044 print("compilers=%s" % str(configuration.compilers))
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001045
Zachary Turner606e3a52015-12-08 01:15:30 +00001046 if not configuration.compilers or len(configuration.compilers) == 0:
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001047 print("No eligible compiler found, exiting.")
1048 exitTestSuite(1)
1049
Zachary Turner606e3a52015-12-08 01:15:30 +00001050 if isinstance(configuration.compilers, list) and len(configuration.compilers) >= 1:
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001051 iterCompilers = True
1052
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001053 # If we iterate on archs or compilers, there is a chance we want to split stderr/stdout.
1054 if iterArchs or iterCompilers:
1055 old_stderr = sys.stderr
1056 old_stdout = sys.stdout
1057 new_stderr = None
1058 new_stdout = None
1059
1060 # Iterating over all possible architecture and compiler combinations.
Zachary Turner606e3a52015-12-08 01:15:30 +00001061 for ia in range(len(configuration.archs) if iterArchs else 1):
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001062 archConfig = ""
1063 if iterArchs:
Zachary Turner606e3a52015-12-08 01:15:30 +00001064 os.environ["ARCH"] = configuration.archs[ia]
1065 archConfig = "arch=%s" % configuration.archs[ia]
1066 for ic in range(len(configuration.compilers) if iterCompilers else 1):
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001067 if iterCompilers:
Zachary Turner606e3a52015-12-08 01:15:30 +00001068 os.environ["CC"] = configuration.compilers[ic]
1069 configString = "%s compiler=%s" % (archConfig, configuration.compilers[ic])
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001070 else:
1071 configString = archConfig
1072
1073 if iterArchs or iterCompilers:
1074 # Translate ' ' to '-' for pathname component.
Zachary Turnere73a0602015-11-06 21:37:33 +00001075 if six.PY2:
Chaoren Linc0a55532015-11-06 22:30:30 +00001076 import string
Zachary Turnere73a0602015-11-06 21:37:33 +00001077 tbl = string.maketrans(' ', '-')
1078 else:
1079 tbl = str.maketrans(' ', '-')
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001080 configPostfix = configString.translate(tbl)
1081
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001082 # Output the configuration.
Zachary Turner606e3a52015-12-08 01:15:30 +00001083 if not configuration.parsable:
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001084 sys.stderr.write("\nConfiguration: " + configString + "\n")
1085
1086 #print("sys.stderr name is", sys.stderr.name)
1087 #print("sys.stdout name is", sys.stdout.name)
1088
1089 # First, write out the number of collected test cases.
Zachary Turner606e3a52015-12-08 01:15:30 +00001090 if not configuration.parsable:
Pavel Labathbddf1802015-12-08 12:09:56 +00001091 sys.stderr.write(configuration.separator + "\n")
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001092 sys.stderr.write("Collected %d test%s\n\n"
Zachary Turner606e3a52015-12-08 01:15:30 +00001093 % (configuration.suite.countTestCases(),
1094 configuration.suite.countTestCases() != 1 and "s" or ""))
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001095
Zachary Turner606e3a52015-12-08 01:15:30 +00001096 if configuration.parsable:
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001097 v = 0
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001098 else:
Zachary Turner606e3a52015-12-08 01:15:30 +00001099 v = configuration.verbose
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001100
1101 # Invoke the test runner.
Zachary Turner606e3a52015-12-08 01:15:30 +00001102 if configuration.count == 1:
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001103 result = unittest2.TextTestRunner(stream=sys.stderr,
1104 verbosity=v,
Zachary Turnerb4733e62015-12-08 01:15:44 +00001105 resultclass=test_result.LLDBTestResult).run(configuration.suite)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001106 else:
1107 # We are invoking the same test suite more than once. In this case,
1108 # mark __ignore_singleton__ flag as True so the signleton pattern is
1109 # not enforced.
Zachary Turnerb4733e62015-12-08 01:15:44 +00001110 test_result.LLDBTestResult.__ignore_singleton__ = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001111 for i in range(count):
1112
1113 result = unittest2.TextTestRunner(stream=sys.stderr,
1114 verbosity=v,
Zachary Turnerb4733e62015-12-08 01:15:44 +00001115 resultclass=test_result.LLDBTestResult).run(configuration.suite)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001116
Zachary Turner606e3a52015-12-08 01:15:30 +00001117 configuration.failed = configuration.failed or not result.wasSuccessful()
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001118
Zachary Turner606e3a52015-12-08 01:15:30 +00001119 if configuration.sdir_has_content and not configuration.parsable:
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001120 sys.stderr.write("Session logs for test failures/errors/unexpected successes"
Zachary Turner606e3a52015-12-08 01:15:30 +00001121 " can be found in directory '%s'\n" % configuration.sdir_name)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001122
Zachary Turner606e3a52015-12-08 01:15:30 +00001123 if configuration.useCategories and len(configuration.failuresPerCategory) > 0:
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001124 sys.stderr.write("Failures per category:\n")
Zachary Turner606e3a52015-12-08 01:15:30 +00001125 for category in configuration.failuresPerCategory:
1126 sys.stderr.write("%s - %d\n" % (category, configuration.failuresPerCategory[category]))
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001127
1128 os.chdir(where_to_save_session)
Zachary Turner606e3a52015-12-08 01:15:30 +00001129 fname = os.path.join(configuration.sdir_name, "TestFinished-%d" % os.getpid())
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001130 with open(fname, "w") as f:
1131 print("Test finished at: %s\n" % datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S"), file=f)
1132
1133 # Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1134 # This should not be necessary now.
1135 if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
1136 print("Terminating Test suite...")
1137 subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1138
1139 # Exiting.
Zachary Turner606e3a52015-12-08 01:15:30 +00001140 exitTestSuite(configuration.failed)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001141
1142if __name__ == "__main__":
Zachary Turner7d564542015-11-02 19:19:49 +00001143 print(__file__ + " is for use as a module only. It should not be run as a standalone script.")
1144 sys.exit(-1)