blob: 22b02900a221c969630c364caa33b0d1ae144763 [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 os
Zachary Turnerc432c8f2015-10-28 17:43:26 +000027import errno
28import platform
Francis Ricci69517072016-09-23 21:32:47 +000029import re
Zachary Turnerc432c8f2015-10-28 17:43:26 +000030import signal
31import socket
32import subprocess
33import sys
Zachary Turnerc432c8f2015-10-28 17:43:26 +000034
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000035# Third-party modules
Zachary Turnerc432c8f2015-10-28 17:43:26 +000036import six
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000037import unittest2
38
39# LLDB Modules
40import lldbsuite
Zachary Turner606e3a52015-12-08 01:15:30 +000041from . import configuration
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000042from . import dotest_args
43from . import lldbtest_config
44from . import test_categories
Todd Fiala49d3c152016-04-20 16:27:27 +000045from lldbsuite.test_event import formatter
Zachary Turnerb4733e62015-12-08 01:15:44 +000046from . import test_result
Todd Fiala49d3c152016-04-20 16:27:27 +000047from lldbsuite.test_event.event_builder import EventBuilder
Zachary Turnerc1b7cd72015-11-05 19:22:28 +000048from ..support import seven
Zachary Turnerc432c8f2015-10-28 17:43:26 +000049
Kate Stoneb9c1b512016-09-06 20:57:50 +000050
Zachary Turnerc432c8f2015-10-28 17:43:26 +000051def 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
Kate Stoneb9c1b512016-09-06 20:57:50 +000055
Zachary Turnerc432c8f2015-10-28 17:43:26 +000056def which(program):
57 """Returns the full path to a program; None otherwise."""
58 fpath, fname = os.path.split(program)
59 if fpath:
60 if is_exe(program):
61 return program
62 else:
63 for path in os.environ["PATH"].split(os.pathsep):
64 exe_file = os.path.join(path, program)
65 if is_exe(exe_file):
66 return exe_file
67 return None
68
Kate Stoneb9c1b512016-09-06 20:57:50 +000069
Zachary Turnerc432c8f2015-10-28 17:43:26 +000070class _WritelnDecorator(object):
71 """Used to decorate file-like objects with a handy 'writeln' method"""
Kate Stoneb9c1b512016-09-06 20:57:50 +000072
73 def __init__(self, stream):
Zachary Turnerc432c8f2015-10-28 17:43:26 +000074 self.stream = stream
75
76 def __getattr__(self, attr):
77 if attr in ('stream', '__getstate__'):
78 raise AttributeError(attr)
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 return getattr(self.stream, attr)
Zachary Turnerc432c8f2015-10-28 17:43:26 +000080
81 def writeln(self, arg=None):
82 if arg:
83 self.write(arg)
Kate Stoneb9c1b512016-09-06 20:57:50 +000084 self.write('\n') # text-mode streams translate to \r\n if needed
Zachary Turnerc432c8f2015-10-28 17:43:26 +000085
86#
87# Global variables:
88#
Kate Stoneb9c1b512016-09-06 20:57:50 +000089
90
Zachary Turnerc432c8f2015-10-28 17:43:26 +000091def usage(parser):
92 parser.print_help()
Zachary Turner606e3a52015-12-08 01:15:30 +000093 if configuration.verbose > 0:
Zachary Turnerc432c8f2015-10-28 17:43:26 +000094 print("""
95Examples:
96
97This is an example of using the -f option to pinpoint to a specific test class
98and test method to be run:
99
100$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
101----------------------------------------------------------------------
102Collected 1 test
103
104test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
105Test 'frame variable this' when stopped on a class constructor. ... ok
106
107----------------------------------------------------------------------
108Ran 1 test in 1.396s
109
110OK
111
112And this is an example of using the -p option to run a single file (the filename
113matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
114
115$ ./dotest.py -v -p ObjC
116----------------------------------------------------------------------
117Collected 4 tests
118
119test_break_with_dsym (TestObjCMethods.FoundationTestCase)
120Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
121test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
122Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
123test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
124Lookup objective-c data types and evaluate expressions. ... ok
125test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
126Lookup objective-c data types and evaluate expressions. ... ok
127
128----------------------------------------------------------------------
129Ran 4 tests in 16.661s
130
131OK
132
133Running of this script also sets up the LLDB_TEST environment variable so that
134individual test cases can locate their supporting files correctly. The script
135tries to set up Python's search paths for modules by looking at the build tree
136relative to this script. See also the '-i' option in the following example.
137
138Finally, this is an example of using the lldb.py module distributed/installed by
139Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
140option to add some delay between two tests. It uses ARCH=x86_64 to specify that
141as the architecture and CC=clang to specify the compiler used for the test run:
142
143$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
144
145Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
146----------------------------------------------------------------------
147Collected 2 tests
148
149test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
150Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
151test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
152Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
153
154----------------------------------------------------------------------
155Ran 2 tests in 5.659s
156
157OK
158
159The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
160notify the directory containing the session logs for test failures or errors.
161In case there is any test failure/error, a similar message is appended at the
162end of the stderr output for your convenience.
163
164ENABLING LOGS FROM TESTS
165
166Option 1:
167
168Writing logs into different files per test case::
169
170This option is particularly useful when multiple dotest instances are created
171by dosep.py
172
173$ ./dotest.py --channel "lldb all"
174
175$ ./dotest.py --channel "lldb all" --channel "gdb-remote packets"
176
177These log files are written to:
178
179<session-dir>/<test-id>-host.log (logs from lldb host process)
180<session-dir>/<test-id>-server.log (logs from debugserver/lldb-server)
181<session-dir>/<test-id>-<test-result>.log (console logs)
182
183By default, logs from successful runs are deleted. Use the --log-success flag
184to create reference logs for debugging.
185
186$ ./dotest.py --log-success
187
188Option 2: (DEPRECATED)
189
190The following options can only enable logs from the host lldb process.
191Only categories from the "lldb" or "gdb-remote" channels can be enabled
192They also do not automatically enable logs in locally running debug servers.
193Also, logs from all test case are written into each log file
194
195o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
196 with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
197
198o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
199 'process.gdb-remote' subsystem with a default option of 'packets' if
200 GDB_REMOTE_LOG_OPTION is not defined.
201
202""")
203 sys.exit(0)
204
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205
Francis Ricci69517072016-09-23 21:32:47 +0000206def parseExclusion(exclusion_file):
207 """Parse an exclusion file, of the following format, where
208 'skip files', 'skip methods', 'xfail files', and 'xfail methods'
209 are the possible list heading values:
210
211 skip files
212 <file name>
213 <file name>
214
215 xfail methods
216 <method name>
217 """
218 excl_type = None
Francis Ricci69517072016-09-23 21:32:47 +0000219
220 with open(exclusion_file) as f:
221 for line in f:
Francis Riccif833f172016-10-04 18:48:00 +0000222 line = line.strip()
Francis Ricci69517072016-09-23 21:32:47 +0000223 if not excl_type:
Francis Riccif833f172016-10-04 18:48:00 +0000224 excl_type = line
Francis Ricci69517072016-09-23 21:32:47 +0000225 continue
226
Francis Ricci69517072016-09-23 21:32:47 +0000227 if not line:
228 excl_type = None
Francis Riccif833f172016-10-04 18:48:00 +0000229 elif excl_type == 'skip':
230 if not configuration.skip_tests:
231 configuration.skip_tests = []
232 configuration.skip_tests.append(line)
233 elif excl_type == 'xfail':
234 if not configuration.xfail_tests:
235 configuration.xfail_tests = []
236 configuration.xfail_tests.append(line)
Francis Ricci69517072016-09-23 21:32:47 +0000237
238
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000239def parseOptionsAndInitTestdirs():
240 """Initialize the list of directories containing our unittest scripts.
241
242 '-h/--help as the first option prints out usage info and exit the program.
243 """
244
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000245 do_help = False
246
247 platform_system = platform.system()
248 platform_machine = platform.machine()
249
250 parser = dotest_args.create_parser()
251 args = dotest_args.parse_args(parser, sys.argv[1:])
252
253 if args.unset_env_varnames:
254 for env_var in args.unset_env_varnames:
255 if env_var in os.environ:
256 # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
Kate Stoneb9c1b512016-09-06 20:57:50 +0000257 # is automatically translated into a corresponding call to
258 # unsetenv().
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000259 del os.environ[env_var]
Kate Stoneb9c1b512016-09-06 20:57:50 +0000260 # os.unsetenv(env_var)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000261
262 if args.set_env_vars:
263 for env_var in args.set_env_vars:
264 parts = env_var.split('=', 1)
265 if len(parts) == 1:
266 os.environ[parts[0]] = ""
267 else:
268 os.environ[parts[0]] = parts[1]
269
270 # only print the args if being verbose (and parsable is off)
271 if args.v and not args.q:
272 print(sys.argv)
273
274 if args.h:
275 do_help = True
276
Pavel Labath6de25ec2017-03-15 08:51:59 +0000277 if args.compiler:
278 configuration.compiler = args.compiler
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000279 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000280 # Use a compiler appropriate appropriate for the Apple SDK if one was
281 # specified
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000282 if platform_system == 'Darwin' and args.apple_sdk:
Pavel Labath6de25ec2017-03-15 08:51:59 +0000283 configuration.compiler = seven.get_command_output(
284 'xcrun -sdk "%s" -find clang 2> /dev/null' %
285 (args.apple_sdk))
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000286 else:
287 # 'clang' on ubuntu 14.04 is 3.4 so we try clang-3.5 first
288 candidateCompilers = ['clang-3.5', 'clang', 'gcc']
289 for candidate in candidateCompilers:
290 if which(candidate):
Pavel Labath6de25ec2017-03-15 08:51:59 +0000291 configuration.compiler = candidate
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000292 break
293
294 if args.channels:
295 lldbtest_config.channels = args.channels
296
297 if args.log_success:
298 lldbtest_config.log_success = args.log_success
299
300 # Set SDKROOT if we are using an Apple SDK
301 if platform_system == 'Darwin' and args.apple_sdk:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000302 os.environ['SDKROOT'] = seven.get_command_output(
303 'xcrun --sdk "%s" --show-sdk-path 2> /dev/null' %
304 (args.apple_sdk))
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000305
Pavel Labath6de25ec2017-03-15 08:51:59 +0000306 if args.arch:
307 configuration.arch = args.arch
308 if configuration.arch.startswith(
309 'arm') and platform_system == 'Darwin' and not args.apple_sdk:
310 os.environ['SDKROOT'] = seven.get_command_output(
311 'xcrun --sdk iphoneos.internal --show-sdk-path 2> /dev/null')
312 if not os.path.exists(os.environ['SDKROOT']):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000313 os.environ['SDKROOT'] = seven.get_command_output(
Pavel Labath6de25ec2017-03-15 08:51:59 +0000314 'xcrun --sdk iphoneos --show-sdk-path 2> /dev/null')
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000315 else:
Pavel Labath6de25ec2017-03-15 08:51:59 +0000316 configuration.arch = platform_machine
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000317
318 if args.categoriesList:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000319 configuration.categoriesList = set(
320 test_categories.validate(
321 args.categoriesList, False))
Zachary Turner606e3a52015-12-08 01:15:30 +0000322 configuration.useCategories = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000323 else:
Zachary Turner606e3a52015-12-08 01:15:30 +0000324 configuration.categoriesList = []
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000325
326 if args.skipCategories:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000327 configuration.skipCategories = test_categories.validate(
328 args.skipCategories, False)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000329
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000330 if args.E:
331 cflags_extras = args.E
332 os.environ['CFLAGS_EXTRAS'] = cflags_extras
333
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000334 if args.d:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000335 sys.stdout.write(
336 "Suspending the process %d to wait for debugger to attach...\n" %
337 os.getpid())
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000338 sys.stdout.flush()
339 os.kill(os.getpid(), signal.SIGSTOP)
340
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000341 if args.f:
342 if any([x.startswith('-') for x in args.f]):
343 usage(parser)
Zachary Turner606e3a52015-12-08 01:15:30 +0000344 configuration.filters.extend(args.f)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000345 # Shut off multiprocessing mode when additional filters are specified.
346 # The rational is that the user is probably going after a very specific
347 # test and doesn't need a bunch of parallel test runners all looking for
348 # it in a frenzy. Also, '-v' now spits out all test run output even
349 # on success, so the standard recipe for redoing a failing test (with -v
350 # and a -f to filter to the specific test) now causes all test scanning
351 # (in parallel) to print results for do-nothing runs in a very distracting
352 # manner. If we really need filtered parallel runs in the future, consider
353 # adding a --no-output-on-success that prevents -v from setting
354 # output-on-success.
Zachary Turner606e3a52015-12-08 01:15:30 +0000355 configuration.no_multiprocess_test_runner = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000356
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000357 if args.l:
Zachary Turner606e3a52015-12-08 01:15:30 +0000358 configuration.skip_long_running_test = False
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000359
360 if args.framework:
Zachary Turner606e3a52015-12-08 01:15:30 +0000361 configuration.lldbFrameworkPath = args.framework
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000362
363 if args.executable:
Francis Riccicef04a22016-04-25 20:36:22 +0000364 lldbtest_config.lldbExec = os.path.realpath(args.executable)
Chris Bieneman265ca532017-03-14 20:04:46 +0000365
366 if args.server:
367 os.environ['LLDB_DEBUGSERVER_PATH'] = args.server
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000368
Francis Ricci69517072016-09-23 21:32:47 +0000369 if args.excluded:
Francis Riccif833f172016-10-04 18:48:00 +0000370 for excl_file in args.excluded:
371 parseExclusion(excl_file)
Francis Ricci69517072016-09-23 21:32:47 +0000372
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000373 if args.p:
374 if args.p.startswith('-'):
375 usage(parser)
Zachary Turner606e3a52015-12-08 01:15:30 +0000376 configuration.regexp = args.p
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000377
378 if args.q:
Zachary Turner606e3a52015-12-08 01:15:30 +0000379 configuration.parsable = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000380
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000381 if args.s:
382 if args.s.startswith('-'):
383 usage(parser)
Zachary Turner606e3a52015-12-08 01:15:30 +0000384 configuration.sdir_name = args.s
Zachary Turner8d4d1512016-05-17 18:02:34 +0000385 configuration.session_file_format = args.session_file_format
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000386
387 if args.t:
388 os.environ['LLDB_COMMAND_TRACE'] = 'YES'
389
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000390 if args.v:
Zachary Turner606e3a52015-12-08 01:15:30 +0000391 configuration.verbose = 2
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000392
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000393 # argparse makes sure we have a number
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000394 if args.sharp:
Zachary Turner606e3a52015-12-08 01:15:30 +0000395 configuration.count = args.sharp
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000396
397 if sys.platform.startswith('win32'):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000398 os.environ['LLDB_DISABLE_CRASH_DIALOG'] = str(
399 args.disable_crash_dialog)
Zachary Turner80310c22015-12-10 18:51:02 +0000400 os.environ['LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE'] = str(True)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000401
Kate Stoneb9c1b512016-09-06 20:57:50 +0000402 if do_help:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000403 usage(parser)
404
405 if args.no_multiprocess:
Zachary Turner606e3a52015-12-08 01:15:30 +0000406 configuration.no_multiprocess_test_runner = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000407
408 if args.inferior:
Zachary Turner606e3a52015-12-08 01:15:30 +0000409 configuration.is_inferior_test_runner = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000410
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000411 if args.num_threads:
Zachary Turner606e3a52015-12-08 01:15:30 +0000412 configuration.num_threads = args.num_threads
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000413
414 if args.test_subdir:
Zachary Turner606e3a52015-12-08 01:15:30 +0000415 configuration.multiprocess_test_subdir = args.test_subdir
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000416
417 if args.test_runner_name:
Zachary Turner606e3a52015-12-08 01:15:30 +0000418 configuration.test_runner_name = args.test_runner_name
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000419
420 # Capture test results-related args.
Todd Fialacee6a6a2015-11-09 18:51:04 +0000421 if args.curses and not args.inferior:
422 # Act as if the following args were set.
Todd Fiala49d3c152016-04-20 16:27:27 +0000423 args.results_formatter = "lldbsuite.test_event.formatter.curses.Curses"
Todd Fialacee6a6a2015-11-09 18:51:04 +0000424 args.results_file = "stdout"
425
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000426 if args.results_file:
Zachary Turner606e3a52015-12-08 01:15:30 +0000427 configuration.results_filename = args.results_file
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000428
429 if args.results_port:
Zachary Turner606e3a52015-12-08 01:15:30 +0000430 configuration.results_port = args.results_port
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000431
432 if args.results_file and args.results_port:
433 sys.stderr.write(
434 "only one of --results-file and --results-port should "
435 "be specified\n")
436 usage(args)
437
438 if args.results_formatter:
Zachary Turner606e3a52015-12-08 01:15:30 +0000439 configuration.results_formatter_name = args.results_formatter
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000440 if args.results_formatter_options:
Zachary Turner606e3a52015-12-08 01:15:30 +0000441 configuration.results_formatter_options = args.results_formatter_options
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000442
Todd Fialab68dbfa22015-12-11 22:29:34 +0000443 # Default to using the BasicResultsFormatter if no formatter is specified
444 # and we're not a test inferior.
445 if not args.inferior and configuration.results_formatter_name is None:
446 configuration.results_formatter_name = (
Todd Fiala49d3c152016-04-20 16:27:27 +0000447 "lldbsuite.test_event.formatter.results_formatter.ResultsFormatter")
Todd Fialab68dbfa22015-12-11 22:29:34 +0000448
Todd Fiala93153922015-12-12 19:26:56 +0000449 # rerun-related arguments
450 configuration.rerun_all_issues = args.rerun_all_issues
Todd Fiala685a7572015-12-14 21:28:46 +0000451 configuration.rerun_max_file_threshold = args.rerun_max_file_threshold
Todd Fiala93153922015-12-12 19:26:56 +0000452
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000453 if args.lldb_platform_name:
Zachary Turner606e3a52015-12-08 01:15:30 +0000454 configuration.lldb_platform_name = args.lldb_platform_name
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000455 if args.lldb_platform_url:
Zachary Turner606e3a52015-12-08 01:15:30 +0000456 configuration.lldb_platform_url = args.lldb_platform_url
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000457 if args.lldb_platform_working_dir:
Zachary Turner606e3a52015-12-08 01:15:30 +0000458 configuration.lldb_platform_working_dir = args.lldb_platform_working_dir
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000459
460 if args.event_add_entries and len(args.event_add_entries) > 0:
461 entries = {}
462 # Parse out key=val pairs, separated by comma
463 for keyval in args.event_add_entries.split(","):
464 key_val_entry = keyval.split("=")
465 if len(key_val_entry) == 2:
466 (key, val) = key_val_entry
467 val_parts = val.split(':')
468 if len(val_parts) > 1:
469 (val, val_type) = val_parts
470 if val_type == 'int':
471 val = int(val)
472 entries[key] = val
473 # Tell the event builder to create all events with these
474 # key/val pairs in them.
475 if len(entries) > 0:
Todd Fiala49d3c152016-04-20 16:27:27 +0000476 EventBuilder.add_entries_to_all_events(entries)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000477
478 # Gather all the dirs passed on the command line.
479 if len(args.args) > 0:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000480 configuration.testdirs = list(
481 map(lambda x: os.path.realpath(os.path.abspath(x)), args.args))
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000482 # Shut off multiprocessing mode when test directories are specified.
Zachary Turner606e3a52015-12-08 01:15:30 +0000483 configuration.no_multiprocess_test_runner = True
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000484
Chris Bieneman7ba55812016-10-21 22:13:55 +0000485 lldbtest_config.codesign_identity = args.codesign_identity
486
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000487 #print("testdirs:", testdirs)
488
Kate Stoneb9c1b512016-09-06 20:57:50 +0000489
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000490def getXcodeOutputPaths(lldbRootDirectory):
491 result = []
492
493 # These are for xcode build directories.
494 xcode3_build_dir = ['build']
495 xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
496
Kate Stoneb9c1b512016-09-06 20:57:50 +0000497 configurations = [
498 ['Debug'],
499 ['DebugClang'],
500 ['Release'],
501 ['BuildAndIntegration']]
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000502 xcode_build_dirs = [xcode3_build_dir, xcode4_build_dir]
503 for configuration in configurations:
504 for xcode_build_dir in xcode_build_dirs:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000505 outputPath = os.path.join(
506 lldbRootDirectory, *(xcode_build_dir + configuration))
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000507 result.append(outputPath)
508
509 return result
510
511
512def createSocketToLocalPort(port):
513 def socket_closer(s):
514 """Close down an opened socket properly."""
515 s.shutdown(socket.SHUT_RDWR)
516 s.close()
517
518 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
519 sock.connect(("localhost", port))
520 return (sock, lambda: socket_closer(sock))
521
522
523def setupTestResults():
524 """Sets up test results-related objects based on arg settings."""
Todd Fiala51831472015-12-09 06:45:43 +0000525 # Setup the results formatter configuration.
Todd Fiala49d3c152016-04-20 16:27:27 +0000526 formatter_config = formatter.FormatterConfig()
Todd Fiala51831472015-12-09 06:45:43 +0000527 formatter_config.filename = configuration.results_filename
528 formatter_config.formatter_name = configuration.results_formatter_name
529 formatter_config.formatter_options = (
530 configuration.results_formatter_options)
531 formatter_config.port = configuration.results_port
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000532
Todd Fialade029392015-12-08 00:53:56 +0000533 # Create the results formatter.
Todd Fiala49d3c152016-04-20 16:27:27 +0000534 formatter_spec = formatter.create_results_formatter(
Todd Fiala51831472015-12-09 06:45:43 +0000535 formatter_config)
Todd Fialade029392015-12-08 00:53:56 +0000536 if formatter_spec is not None and formatter_spec.formatter is not None:
Zachary Turner606e3a52015-12-08 01:15:30 +0000537 configuration.results_formatter_object = formatter_spec.formatter
Todd Fiala194913f2015-12-02 21:12:17 +0000538
Todd Fiala49d3c152016-04-20 16:27:27 +0000539 # Send an initialize message to the formatter.
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000540 initialize_event = EventBuilder.bare_event("initialize")
541 if isMultiprocessTestRunner():
Todd Fiala51831472015-12-09 06:45:43 +0000542 if (configuration.test_runner_name is not None and
543 configuration.test_runner_name == "serial"):
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000544 # Only one worker queue here.
545 worker_count = 1
546 else:
547 # Workers will be the number of threads specified.
Zachary Turner606e3a52015-12-08 01:15:30 +0000548 worker_count = configuration.num_threads
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000549 else:
550 worker_count = 1
551 initialize_event["worker_count"] = worker_count
552
Todd Fialade029392015-12-08 00:53:56 +0000553 formatter_spec.formatter.handle_event(initialize_event)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000554
Todd Fialade029392015-12-08 00:53:56 +0000555 # Make sure we clean up the formatter on shutdown.
556 if formatter_spec.cleanup_func is not None:
557 atexit.register(formatter_spec.cleanup_func)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000558
559
560def getOutputPaths(lldbRootDirectory):
561 """
562 Returns typical build output paths for the lldb executable
563
564 lldbDirectory - path to the root of the lldb svn/git repo
565 """
566 result = []
567
568 if sys.platform == 'darwin':
569 result.extend(getXcodeOutputPaths(lldbRootDirectory))
570
571 # cmake builds? look for build or build/host folder next to llvm directory
572 # lldb is located in llvm/tools/lldb so we need to go up three levels
Kate Stoneb9c1b512016-09-06 20:57:50 +0000573 llvmParentDir = os.path.abspath(
574 os.path.join(
575 lldbRootDirectory,
576 os.pardir,
577 os.pardir,
578 os.pardir))
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000579 result.append(os.path.join(llvmParentDir, 'build', 'bin'))
580 result.append(os.path.join(llvmParentDir, 'build', 'host', 'bin'))
581
Kate Stoneb9c1b512016-09-06 20:57:50 +0000582 # some cmake developers keep their build directory beside their lldb
583 # directory
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000584 lldbParentDir = os.path.abspath(os.path.join(lldbRootDirectory, os.pardir))
585 result.append(os.path.join(lldbParentDir, 'build', 'bin'))
586 result.append(os.path.join(lldbParentDir, 'build', 'host', 'bin'))
587
588 return result
589
Kate Stoneb9c1b512016-09-06 20:57:50 +0000590
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000591def setupSysPath():
592 """
593 Add LLDB.framework/Resources/Python to the search paths for modules.
594 As a side effect, we also discover the 'lldb' executable and export it here.
595 """
596
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000597 # Get the directory containing the current script.
598 if "DOTEST_PROFILE" in os.environ and "DOTEST_SCRIPT_DIR" in os.environ:
599 scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
600 else:
601 scriptPath = os.path.dirname(os.path.realpath(__file__))
602 if not scriptPath.endswith('test'):
603 print("This script expects to reside in lldb's test directory.")
604 sys.exit(-1)
605
Zachary Turner6a188e62015-12-11 19:21:34 +0000606 os.environ["LLDB_TEST"] = scriptPath
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000607
608 # Set up the LLDB_SRC environment variable, so that the tests can locate
609 # the LLDB source code.
610 os.environ["LLDB_SRC"] = lldbsuite.lldb_root
611
612 pluginPath = os.path.join(scriptPath, 'plugins')
613 toolsLLDBMIPath = os.path.join(scriptPath, 'tools', 'lldb-mi')
614 toolsLLDBServerPath = os.path.join(scriptPath, 'tools', 'lldb-server')
615
Kate Stoneb9c1b512016-09-06 20:57:50 +0000616 # Insert script dir, plugin dir, lldb-mi dir and lldb-server dir to the
617 # sys.path.
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000618 sys.path.insert(0, pluginPath)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000619 # Adding test/tools/lldb-mi to the path makes it easy
620 sys.path.insert(0, toolsLLDBMIPath)
621 # to "import lldbmi_testcase" from the MI tests
622 # Adding test/tools/lldb-server to the path makes it easy
623 sys.path.insert(0, toolsLLDBServerPath)
624 # to "import lldbgdbserverutils" from the lldb-server tests
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000625
626 # This is the root of the lldb git/svn checkout
627 # When this changes over to a package instead of a standalone script, this
628 # will be `lldbsuite.lldb_root`
629 lldbRootDirectory = lldbsuite.lldb_root
630
631 # Some of the tests can invoke the 'lldb' command directly.
632 # We'll try to locate the appropriate executable right here.
633
634 # The lldb executable can be set from the command line
635 # if it's not set, we try to find it now
636 # first, we try the environment
637 if not lldbtest_config.lldbExec:
638 # First, you can define an environment variable LLDB_EXEC specifying the
639 # full pathname of the lldb executable.
640 if "LLDB_EXEC" in os.environ:
641 lldbtest_config.lldbExec = os.environ["LLDB_EXEC"]
642
643 if not lldbtest_config.lldbExec:
644 outputPaths = getOutputPaths(lldbRootDirectory)
645 for outputPath in outputPaths:
646 candidatePath = os.path.join(outputPath, 'lldb')
647 if is_exe(candidatePath):
648 lldbtest_config.lldbExec = candidatePath
649 break
650
651 if not lldbtest_config.lldbExec:
652 # Last, check the path
653 lldbtest_config.lldbExec = which('lldb')
654
655 if lldbtest_config.lldbExec and not is_exe(lldbtest_config.lldbExec):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000656 print(
657 "'{}' is not a path to a valid executable".format(
658 lldbtest_config.lldbExec))
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000659 lldbtest_config.lldbExec = None
660
661 if not lldbtest_config.lldbExec:
662 print("The 'lldb' executable cannot be located. Some of the tests may not be run as a result.")
663 sys.exit(-1)
664
Kate Stoneb9c1b512016-09-06 20:57:50 +0000665 # confusingly, this is the "bin" directory
666 lldbLibDir = os.path.dirname(lldbtest_config.lldbExec)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000667 os.environ["LLDB_LIB_DIR"] = lldbLibDir
Kate Stoneb9c1b512016-09-06 20:57:50 +0000668 lldbImpLibDir = os.path.join(
669 lldbLibDir,
670 '..',
671 'lib') if sys.platform.startswith('win32') else lldbLibDir
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000672 os.environ["LLDB_IMPLIB_DIR"] = lldbImpLibDir
Zachary Turner35a76102015-12-09 20:48:42 +0000673 print("LLDB library dir:", os.environ["LLDB_LIB_DIR"])
674 print("LLDB import library dir:", os.environ["LLDB_IMPLIB_DIR"])
675 os.system('%s -v' % lldbtest_config.lldbExec)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000676
677 # Assume lldb-mi is in same place as lldb
678 # If not found, disable the lldb-mi tests
Chris Bieneman35e54572016-10-12 20:15:46 +0000679 # TODO: Append .exe on Windows
680 # - this will be in a separate commit in case the mi tests fail horribly
681 lldbDir = os.path.dirname(lldbtest_config.lldbExec)
682 lldbMiExec = os.path.join(lldbDir, "lldb-mi")
683 if is_exe(lldbMiExec):
684 os.environ["LLDBMI_EXEC"] = lldbMiExec
685 else:
Zachary Turnerb4733e62015-12-08 01:15:44 +0000686 if not configuration.shouldSkipBecauseOfCategories(["lldb-mi"]):
Kate Stoneb9c1b512016-09-06 20:57:50 +0000687 print(
688 "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 +0000689 configuration.skipCategories.append("lldb-mi")
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000690
Kate Stoneb9c1b512016-09-06 20:57:50 +0000691 lldbPythonDir = None # The directory that contains 'lldb/__init__.py'
Chris Bieneman5d51a762016-10-31 22:06:52 +0000692 if not configuration.lldbFrameworkPath and os.path.exists(os.path.join(lldbLibDir, "LLDB.framework")):
693 configuration.lldbFrameworkPath = os.path.join(lldbLibDir, "LLDB.framework")
Zachary Turner606e3a52015-12-08 01:15:30 +0000694 if configuration.lldbFrameworkPath:
Chris Bienemanbd6d6992016-10-31 04:48:10 +0000695 lldbtest_config.lldbFrameworkPath = configuration.lldbFrameworkPath
Kate Stoneb9c1b512016-09-06 20:57:50 +0000696 candidatePath = os.path.join(
697 configuration.lldbFrameworkPath, 'Resources', 'Python')
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000698 if os.path.isfile(os.path.join(candidatePath, 'lldb/__init__.py')):
699 lldbPythonDir = candidatePath
700 if not lldbPythonDir:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000701 print(
702 'Resources/Python/lldb/__init__.py was not found in ' +
703 configuration.lldbFrameworkPath)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000704 sys.exit(-1)
705 else:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000706 # If our lldb supports the -P option, use it to find the python path:
707 init_in_python_dir = os.path.join('lldb', '__init__.py')
708
Kate Stoneb9c1b512016-09-06 20:57:50 +0000709 lldb_dash_p_result = subprocess.check_output(
710 [lldbtest_config.lldbExec, "-P"], stderr=subprocess.STDOUT, universal_newlines=True)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000711
Kate Stoneb9c1b512016-09-06 20:57:50 +0000712 if lldb_dash_p_result and not lldb_dash_p_result.startswith(
713 ("<", "lldb: invalid option:")) and not lldb_dash_p_result.startswith("Traceback"):
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000714 lines = lldb_dash_p_result.splitlines()
715
716 # Workaround for readline vs libedit issue on FreeBSD. If stdout
717 # is not a terminal Python executes
718 # rl_variable_bind ("enable-meta-key", "off");
719 # This produces a warning with FreeBSD's libedit because the
720 # enable-meta-key variable is unknown. Not an issue on Apple
721 # because cpython commit f0ab6f9f0603 added a #ifndef __APPLE__
722 # around the call. See http://bugs.python.org/issue19884 for more
723 # information. For now we just discard the warning output.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000724 if len(lines) >= 1 and lines[0].startswith(
725 "bind: Invalid command"):
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000726 lines.pop(0)
727
728 # Taking the last line because lldb outputs
729 # 'Cannot read termcap database;\nusing dumb terminal settings.\n'
730 # before the path
Kate Stoneb9c1b512016-09-06 20:57:50 +0000731 if len(lines) >= 1 and os.path.isfile(
732 os.path.join(lines[-1], init_in_python_dir)):
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000733 lldbPythonDir = lines[-1]
734 if "freebsd" in sys.platform or "linux" in sys.platform:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000735 os.environ['LLDB_LIB_DIR'] = os.path.join(
736 lldbPythonDir, '..', '..')
737
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000738 if not lldbPythonDir:
739 if platform.system() == "Darwin":
740 python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
Saleem Abdulrasool81eadde2016-05-16 03:13:05 +0000741 outputPaths = getXcodeOutputPaths(lldbRootDirectory)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000742 for outputPath in outputPaths:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000743 candidatePath = os.path.join(
744 outputPath, *python_resource_dir)
745 if os.path.isfile(
746 os.path.join(
747 candidatePath,
748 init_in_python_dir)):
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000749 lldbPythonDir = candidatePath
750 break
751
752 if not lldbPythonDir:
Saleem Abdulrasool0eadc532016-05-16 03:13:12 +0000753 print("lldb.py is not found, some tests may fail.")
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000754 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000755 print(
756 "Unable to load lldb extension module. Possible reasons for this include:")
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000757 print(" 1) LLDB was built with LLDB_DISABLE_PYTHON=1")
Kate Stoneb9c1b512016-09-06 20:57:50 +0000758 print(
759 " 2) PYTHONPATH and PYTHONHOME are not set correctly. PYTHONHOME should refer to")
760 print(
761 " the version of Python that LLDB built and linked against, and PYTHONPATH")
762 print(
763 " should contain the Lib directory for the same python distro, as well as the")
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000764 print(" location of LLDB\'s site-packages folder.")
Kate Stoneb9c1b512016-09-06 20:57:50 +0000765 print(
766 " 3) A different version of Python than that which was built against is exported in")
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000767 print(" the system\'s PATH environment variable, causing conflicts.")
Kate Stoneb9c1b512016-09-06 20:57:50 +0000768 print(
769 " 4) The executable '%s' could not be found. Please check " %
770 lldbtest_config.lldbExec)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000771 print(" that it exists and is executable.")
772
773 if lldbPythonDir:
774 lldbPythonDir = os.path.normpath(lldbPythonDir)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 # Some of the code that uses this path assumes it hasn't resolved the Versions... link.
776 # If the path we've constructed looks like that, then we'll strip out
777 # the Versions/A part.
778 (before, frameWithVersion, after) = lldbPythonDir.rpartition(
779 "LLDB.framework/Versions/A")
780 if frameWithVersion != "":
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000781 lldbPythonDir = before + "LLDB.framework" + after
782
783 lldbPythonDir = os.path.abspath(lldbPythonDir)
784
785 # If tests need to find LLDB_FRAMEWORK, now they can do it
Kate Stoneb9c1b512016-09-06 20:57:50 +0000786 os.environ["LLDB_FRAMEWORK"] = os.path.dirname(
787 os.path.dirname(lldbPythonDir))
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000788
Kate Stoneb9c1b512016-09-06 20:57:50 +0000789 # This is to locate the lldb.py module. Insert it right after
790 # sys.path[0].
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000791 sys.path[1:1] = [lldbPythonDir]
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000792
Todd Fiala7c5f7ca2016-05-13 21:36:26 +0000793
794def visit_file(dir, name):
795 # Try to match the regexp pattern, if specified.
796 if configuration.regexp:
Todd Fiala7c5f7ca2016-05-13 21:36:26 +0000797 if not re.search(configuration.regexp, name):
798 # We didn't match the regex, we're done.
799 return
800
Francis Riccif833f172016-10-04 18:48:00 +0000801 if configuration.skip_tests:
802 for file_regexp in configuration.skip_tests:
Francis Ricci69517072016-09-23 21:32:47 +0000803 if re.search(file_regexp, name):
804 return
805
Todd Fiala7c5f7ca2016-05-13 21:36:26 +0000806 # We found a match for our test. Add it to the suite.
807
808 # Update the sys.path first.
809 if not sys.path.count(dir):
810 sys.path.insert(0, dir)
811 base = os.path.splitext(name)[0]
812
813 # Thoroughly check the filterspec against the base module and admit
814 # the (base, filterspec) combination only when it makes sense.
815 filterspec = None
816 for filterspec in configuration.filters:
817 # Optimistically set the flag to True.
818 filtered = True
819 module = __import__(base)
820 parts = filterspec.split('.')
821 obj = module
822 for part in parts:
823 try:
824 parent, obj = obj, getattr(obj, part)
825 except AttributeError:
826 # The filterspec has failed.
827 filtered = False
828 break
829
830 # If filtered, we have a good filterspec. Add it.
831 if filtered:
832 # print("adding filter spec %s to module %s" % (filterspec, module))
833 configuration.suite.addTests(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000834 unittest2.defaultTestLoader.loadTestsFromName(
835 filterspec, module))
Todd Fiala7c5f7ca2016-05-13 21:36:26 +0000836 continue
837
838 # Forgo this module if the (base, filterspec) combo is invalid
839 if configuration.filters and not filtered:
840 return
841
842 if not filterspec or not filtered:
843 # Add the entire file's worth of tests since we're not filtered.
844 # Also the fail-over case when the filterspec branch
845 # (base, filterspec) combo doesn't make sense.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000846 configuration.suite.addTests(
847 unittest2.defaultTestLoader.loadTestsFromName(base))
Todd Fiala7c5f7ca2016-05-13 21:36:26 +0000848
849
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000850def visit(prefix, dir, names):
851 """Visitor function for os.path.walk(path, visit, arg)."""
852
Zachary Turner50671582015-12-08 20:36:22 +0000853 dir_components = set(dir.split(os.sep))
854 excluded_components = set(['.svn', '.git'])
855 if dir_components.intersection(excluded_components):
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000856 return
857
Todd Fiala7c5f7ca2016-05-13 21:36:26 +0000858 # Gather all the Python test file names that follow the Test*.py pattern.
859 python_test_files = [
860 name
861 for name in names
862 if name.endswith('.py') and name.startswith(prefix)]
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000863
Todd Fiala7c5f7ca2016-05-13 21:36:26 +0000864 # Visit all the python test files.
865 for name in python_test_files:
866 try:
867 # Ensure we error out if we have multiple tests with the same
868 # base name.
869 # Future improvement: find all the places where we work with base
870 # names and convert to full paths. We have directory structure
871 # to disambiguate these, so we shouldn't need this constraint.
Zachary Turner606e3a52015-12-08 01:15:30 +0000872 if name in configuration.all_tests:
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000873 raise Exception("Found multiple tests with the name %s" % name)
Zachary Turner606e3a52015-12-08 01:15:30 +0000874 configuration.all_tests.add(name)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000875
Todd Fiala7c5f7ca2016-05-13 21:36:26 +0000876 # Run the relevant tests in the python file.
877 visit_file(dir, name)
878 except Exception as ex:
879 # Convert this exception to a test event error for the file.
880 test_filename = os.path.abspath(os.path.join(dir, name))
881 if configuration.results_formatter_object is not None:
882 # Grab the backtrace for the exception.
883 import traceback
884 backtrace = traceback.format_exc()
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000885
Todd Fiala7c5f7ca2016-05-13 21:36:26 +0000886 # Generate the test event.
887 configuration.results_formatter_object.handle_event(
888 EventBuilder.event_for_job_test_add_error(
889 test_filename, ex, backtrace))
890 raise
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000891
892
893def disabledynamics():
894 import lldb
895 ci = lldb.DBG.GetCommandInterpreter()
896 res = lldb.SBCommandReturnObject()
Kate Stoneb9c1b512016-09-06 20:57:50 +0000897 ci.HandleCommand(
898 "setting set target.prefer-dynamic-value no-dynamic-values",
899 res,
900 False)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000901 if not res.Succeeded():
902 raise Exception('disabling dynamic type support failed')
903
Kate Stoneb9c1b512016-09-06 20:57:50 +0000904
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000905def lldbLoggings():
906 import lldb
907 """Check and do lldb loggings if necessary."""
908
909 # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
910 # defined. Use ${LLDB_LOG} to specify the log file.
911 ci = lldb.DBG.GetCommandInterpreter()
912 res = lldb.SBCommandReturnObject()
913 if ("LLDB_LOG" in os.environ):
914 open(os.environ["LLDB_LOG"], 'w').close()
915 if ("LLDB_LOG_OPTION" in os.environ):
916 lldb_log_option = os.environ["LLDB_LOG_OPTION"]
917 else:
918 lldb_log_option = "event process expr state api"
919 ci.HandleCommand(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000920 "log enable -n -f " +
921 os.environ["LLDB_LOG"] +
922 " lldb " +
923 lldb_log_option,
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000924 res)
925 if not res.Succeeded():
926 raise Exception('log enable failed (check LLDB_LOG env variable)')
927
928 if ("LLDB_LINUX_LOG" in os.environ):
929 open(os.environ["LLDB_LINUX_LOG"], 'w').close()
930 if ("LLDB_LINUX_LOG_OPTION" in os.environ):
931 lldb_log_option = os.environ["LLDB_LINUX_LOG_OPTION"]
932 else:
933 lldb_log_option = "event process expr state api"
934 ci.HandleCommand(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000935 "log enable -n -f " +
936 os.environ["LLDB_LINUX_LOG"] +
937 " linux " +
938 lldb_log_option,
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000939 res)
940 if not res.Succeeded():
Kate Stoneb9c1b512016-09-06 20:57:50 +0000941 raise Exception(
942 'log enable failed (check LLDB_LINUX_LOG env variable)')
943
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000944 # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
945 # Use ${GDB_REMOTE_LOG} to specify the log file.
946 if ("GDB_REMOTE_LOG" in os.environ):
947 if ("GDB_REMOTE_LOG_OPTION" in os.environ):
948 gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
949 else:
950 gdb_remote_log_option = "packets process"
951 ci.HandleCommand(
952 "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
953 + gdb_remote_log_option,
954 res)
955 if not res.Succeeded():
Kate Stoneb9c1b512016-09-06 20:57:50 +0000956 raise Exception(
957 'log enable failed (check GDB_REMOTE_LOG env variable)')
958
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000959
960def getMyCommandLine():
961 return ' '.join(sys.argv)
962
963# ======================================== #
964# #
965# Execution of the test driver starts here #
966# #
967# ======================================== #
968
Kate Stoneb9c1b512016-09-06 20:57:50 +0000969
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000970def checkDsymForUUIDIsNotOn():
971 cmd = ["defaults", "read", "com.apple.DebugSymbols"]
Kate Stoneb9c1b512016-09-06 20:57:50 +0000972 pipe = subprocess.Popen(
973 cmd,
974 stdout=subprocess.PIPE,
975 stderr=subprocess.STDOUT)
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000976 cmd_output = pipe.stdout.read()
977 if cmd_output and "DBGFileMappedPaths = " in cmd_output:
978 print("%s =>" % ' '.join(cmd))
979 print(cmd_output)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000980 print(
981 "Disable automatic lookup and caching of dSYMs before running the test suite!")
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000982 print("Exiting...")
983 sys.exit(0)
984
Kate Stoneb9c1b512016-09-06 20:57:50 +0000985
986def exitTestSuite(exitCode=None):
Zachary Turnerc432c8f2015-10-28 17:43:26 +0000987 import lldb
988 lldb.SBDebugger.Terminate()
989 if exitCode:
990 sys.exit(exitCode)
991
992
993def isMultiprocessTestRunner():
994 # We're not multiprocess when we're either explicitly
995 # the inferior (as specified by the multiprocess test
996 # runner) OR we've been told to skip using the multiprocess
997 # test runner
Kate Stoneb9c1b512016-09-06 20:57:50 +0000998 return not (
999 configuration.is_inferior_test_runner or configuration.no_multiprocess_test_runner)
1000
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001001
Enrico Granata5f92a132015-11-05 00:46:25 +00001002def getVersionForSDK(sdk):
1003 sdk = str.lower(sdk)
1004 full_path = seven.get_command_output('xcrun -sdk %s --show-sdk-path' % sdk)
1005 basename = os.path.basename(full_path)
1006 basename = os.path.splitext(basename)[0]
1007 basename = str.lower(basename)
1008 ver = basename.replace(sdk, '')
1009 return ver
1010
Kate Stoneb9c1b512016-09-06 20:57:50 +00001011
Enrico Granata5f92a132015-11-05 00:46:25 +00001012def getPathForSDK(sdk):
1013 sdk = str.lower(sdk)
1014 full_path = seven.get_command_output('xcrun -sdk %s --show-sdk-path' % sdk)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015 if os.path.exists(full_path):
1016 return full_path
Enrico Granata5f92a132015-11-05 00:46:25 +00001017 return None
1018
Kate Stoneb9c1b512016-09-06 20:57:50 +00001019
Enrico Granata5f92a132015-11-05 00:46:25 +00001020def setDefaultTripleForPlatform():
Zachary Turner606e3a52015-12-08 01:15:30 +00001021 if configuration.lldb_platform_name == 'ios-simulator':
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022 triple_str = 'x86_64-apple-ios%s' % (
1023 getVersionForSDK('iphonesimulator'))
Enrico Granata5f92a132015-11-05 00:46:25 +00001024 os.environ['TRIPLE'] = triple_str
Kate Stoneb9c1b512016-09-06 20:57:50 +00001025 return {'TRIPLE': triple_str}
Enrico Granata5f92a132015-11-05 00:46:25 +00001026 return {}
1027
Kate Stoneb9c1b512016-09-06 20:57:50 +00001028
Pavel Labath6de25ec2017-03-15 08:51:59 +00001029def checkCompiler():
1030 # Add some intervention here to sanity check that the compiler requested is sane.
1031 # If found not to be an executable program, we abort.
1032 c = configuration.compiler
1033 if which(c):
1034 return
1035
1036 if not sys.platform.startswith("darwin"):
1037 raise Exception(c + " is not a valid compiler")
1038
1039 pipe = subprocess.Popen(
1040 ['xcrun', '-find', c], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
1041 cmd_output = pipe.stdout.read()
1042 if not cmd_output or "not found" in cmd_output:
1043 raise Exception(c + " is not a valid compiler")
1044
1045 configuration.compiler = cmd_output.split('\n')[0]
1046 print("'xcrun -find %s' returning %s" % (c, configuration.compiler))
1047
1048
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001049def run_suite():
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001050 # On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
1051 # does not exist before proceeding to running the test suite.
1052 if sys.platform.startswith("darwin"):
1053 checkDsymForUUIDIsNotOn()
1054
1055 #
1056 # Start the actions by first parsing the options while setting up the test
1057 # directories, followed by setting up the search paths for lldb utilities;
1058 # then, we walk the directory trees and collect the tests into our test suite.
1059 #
1060 parseOptionsAndInitTestdirs()
1061
1062 # Setup test results (test results formatter and output handling).
1063 setupTestResults()
1064
1065 # If we are running as the multiprocess test runner, kick off the
1066 # multiprocess test runner here.
1067 if isMultiprocessTestRunner():
Zachary Turnerc1b7cd72015-11-05 19:22:28 +00001068 from . import dosep
Kate Stoneb9c1b512016-09-06 20:57:50 +00001069 dosep.main(
1070 configuration.num_threads,
1071 configuration.multiprocess_test_subdir,
1072 configuration.test_runner_name,
1073 configuration.results_formatter_object)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001074 raise Exception("should never get here")
Zachary Turner606e3a52015-12-08 01:15:30 +00001075 elif configuration.is_inferior_test_runner:
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001076 # Shut off Ctrl-C processing in inferiors. The parallel
1077 # test runner handles this more holistically.
1078 signal.signal(signal.SIGINT, signal.SIG_IGN)
1079
1080 setupSysPath()
Pavel Labath9cbf7dd2015-12-08 13:32:07 +00001081 configuration.setupCrashInfoHook()
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001082
1083 #
1084 # If '-l' is specified, do not skip the long running tests.
Zachary Turner606e3a52015-12-08 01:15:30 +00001085 if not configuration.skip_long_running_test:
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001086 os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
1087
1088 # For the time being, let's bracket the test runner within the
1089 # lldb.SBDebugger.Initialize()/Terminate() pair.
1090 import lldb
1091
1092 # Create a singleton SBDebugger in the lldb namespace.
1093 lldb.DBG = lldb.SBDebugger.Create()
1094
Zachary Turner606e3a52015-12-08 01:15:30 +00001095 if configuration.lldb_platform_name:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001096 print("Setting up remote platform '%s'" %
1097 (configuration.lldb_platform_name))
1098 lldb.remote_platform = lldb.SBPlatform(
1099 configuration.lldb_platform_name)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001100 if not lldb.remote_platform.IsValid():
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101 print(
1102 "error: unable to create the LLDB platform named '%s'." %
1103 (configuration.lldb_platform_name))
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001104 exitTestSuite(1)
Zachary Turner606e3a52015-12-08 01:15:30 +00001105 if configuration.lldb_platform_url:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001106 # We must connect to a remote platform if a LLDB platform URL was
1107 # specified
1108 print(
1109 "Connecting to remote platform '%s' at '%s'..." %
1110 (configuration.lldb_platform_name, configuration.lldb_platform_url))
1111 platform_connect_options = lldb.SBPlatformConnectOptions(
1112 configuration.lldb_platform_url)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001113 err = lldb.remote_platform.ConnectRemote(platform_connect_options)
1114 if err.Success():
1115 print("Connected.")
1116 else:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001117 print("error: failed to connect to remote platform using URL '%s': %s" % (
1118 configuration.lldb_platform_url, err))
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001119 exitTestSuite(1)
1120 else:
Zachary Turner606e3a52015-12-08 01:15:30 +00001121 configuration.lldb_platform_url = None
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001122
Enrico Granata5f92a132015-11-05 00:46:25 +00001123 platform_changes = setDefaultTripleForPlatform()
1124 first = True
1125 for key in platform_changes:
1126 if first:
1127 print("Environment variables setup for platform support:")
1128 first = False
Kate Stoneb9c1b512016-09-06 20:57:50 +00001129 print("%s = %s" % (key, platform_changes[key]))
Enrico Granata5f92a132015-11-05 00:46:25 +00001130
Zachary Turner606e3a52015-12-08 01:15:30 +00001131 if configuration.lldb_platform_working_dir:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001132 print("Setting remote platform working directory to '%s'..." %
1133 (configuration.lldb_platform_working_dir))
1134 lldb.remote_platform.SetWorkingDirectory(
1135 configuration.lldb_platform_working_dir)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001136 lldb.DBG.SetSelectedPlatform(lldb.remote_platform)
1137 else:
1138 lldb.remote_platform = None
Zachary Turner606e3a52015-12-08 01:15:30 +00001139 configuration.lldb_platform_working_dir = None
1140 configuration.lldb_platform_url = None
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001141
1142 target_platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
1143
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001144 # Don't do debugserver tests on everything except OS X.
Zachary Turner606e3a52015-12-08 01:15:30 +00001145 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 +00001146
1147 # Don't do lldb-server (llgs) tests on anything except Linux.
Zachary Turner606e3a52015-12-08 01:15:30 +00001148 configuration.dont_do_llgs_test = not ("linux" in target_platform)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001149
1150 #
1151 # Walk through the testdirs while collecting tests.
1152 #
Zachary Turner606e3a52015-12-08 01:15:30 +00001153 for testdir in configuration.testdirs:
Zachary Turnere6ba0532015-11-05 01:33:54 +00001154 for (dirpath, dirnames, filenames) in os.walk(testdir):
1155 visit('Test', dirpath, filenames)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001156
1157 #
1158 # Now that we have loaded all the test cases, run the whole test suite.
1159 #
1160
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001161 # Turn on lldb loggings if necessary.
1162 lldbLoggings()
1163
1164 # Disable default dynamic types for testing purposes
1165 disabledynamics()
1166
1167 # Install the control-c handler.
1168 unittest2.signals.installHandler()
1169
1170 # If sdir_name is not specified through the '-s sdir_name' option, get a
1171 # timestamp string and export it as LLDB_SESSION_DIR environment var. This will
1172 # be used when/if we want to dump the session info of individual test cases
1173 # later on.
1174 #
1175 # See also TestBase.dumpSessionInfo() in lldbtest.py.
1176 import datetime
1177 # The windows platforms don't like ':' in the pathname.
1178 timestamp_started = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
Zachary Turner606e3a52015-12-08 01:15:30 +00001179 if not configuration.sdir_name:
1180 configuration.sdir_name = timestamp_started
Kate Stoneb9c1b512016-09-06 20:57:50 +00001181 os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(
1182 os.getcwd(), configuration.sdir_name)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001183
Kate Stoneb9c1b512016-09-06 20:57:50 +00001184 sys.stderr.write(
1185 "\nSession logs for test failures/errors/unexpected successes"
1186 " will go into directory '%s'\n" %
1187 configuration.sdir_name)
Zachary Turner35a76102015-12-09 20:48:42 +00001188 sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001189
Zachary Turner606e3a52015-12-08 01:15:30 +00001190 if not os.path.isdir(configuration.sdir_name):
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001191 try:
Zachary Turner606e3a52015-12-08 01:15:30 +00001192 os.mkdir(configuration.sdir_name)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001193 except OSError as exception:
1194 if exception.errno != errno.EEXIST:
1195 raise
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001196
1197 #
Pavel Labath6de25ec2017-03-15 08:51:59 +00001198 # Invoke the default TextTestRunner to run the test suite
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001199 #
Pavel Labath6de25ec2017-03-15 08:51:59 +00001200 checkCompiler()
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001201
Zachary Turner606e3a52015-12-08 01:15:30 +00001202 if not configuration.parsable:
Pavel Labath6de25ec2017-03-15 08:51:59 +00001203 print("compiler=%s" % configuration.compiler)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001204
1205 # Iterating over all possible architecture and compiler combinations.
Pavel Labath6de25ec2017-03-15 08:51:59 +00001206 os.environ["ARCH"] = configuration.arch
1207 os.environ["CC"] = configuration.compiler
1208 configString = "arch=%s compiler=%s" % (configuration.arch,
1209 configuration.compiler)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001210
Pavel Labath6de25ec2017-03-15 08:51:59 +00001211 # Translate ' ' to '-' for pathname component.
1212 if six.PY2:
1213 import string
1214 tbl = string.maketrans(' ', '-')
1215 else:
1216 tbl = str.maketrans(' ', '-')
1217 configPostfix = configString.translate(tbl)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001218
Pavel Labath6de25ec2017-03-15 08:51:59 +00001219 # Output the configuration.
1220 if not configuration.parsable:
1221 sys.stderr.write("\nConfiguration: " + configString + "\n")
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001222
Pavel Labath6de25ec2017-03-15 08:51:59 +00001223 # First, write out the number of collected test cases.
1224 if not configuration.parsable:
1225 sys.stderr.write(configuration.separator + "\n")
1226 sys.stderr.write(
1227 "Collected %d test%s\n\n" %
1228 (configuration.suite.countTestCases(),
1229 configuration.suite.countTestCases() != 1 and "s" or ""))
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001230
Pavel Labath6de25ec2017-03-15 08:51:59 +00001231 if configuration.parsable:
1232 v = 0
1233 else:
1234 v = configuration.verbose
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001235
Pavel Labath6de25ec2017-03-15 08:51:59 +00001236 # Invoke the test runner.
1237 if configuration.count == 1:
1238 result = unittest2.TextTestRunner(
1239 stream=sys.stderr,
1240 verbosity=v,
1241 resultclass=test_result.LLDBTestResult).run(
1242 configuration.suite)
1243 else:
1244 # We are invoking the same test suite more than once. In this case,
1245 # mark __ignore_singleton__ flag as True so the signleton pattern is
1246 # not enforced.
1247 test_result.LLDBTestResult.__ignore_singleton__ = True
1248 for i in range(configuration.count):
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001249
Pavel Labath6de25ec2017-03-15 08:51:59 +00001250 result = unittest2.TextTestRunner(
1251 stream=sys.stderr,
1252 verbosity=v,
1253 resultclass=test_result.LLDBTestResult).run(
1254 configuration.suite)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001255
Pavel Labath6de25ec2017-03-15 08:51:59 +00001256 configuration.failed = not result.wasSuccessful()
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001257
Zachary Turner606e3a52015-12-08 01:15:30 +00001258 if configuration.sdir_has_content and not configuration.parsable:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001259 sys.stderr.write(
1260 "Session logs for test failures/errors/unexpected successes"
1261 " can be found in directory '%s'\n" %
1262 configuration.sdir_name)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001263
Kate Stoneb9c1b512016-09-06 20:57:50 +00001264 if configuration.useCategories and len(
1265 configuration.failuresPerCategory) > 0:
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001266 sys.stderr.write("Failures per category:\n")
Zachary Turner606e3a52015-12-08 01:15:30 +00001267 for category in configuration.failuresPerCategory:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001268 sys.stderr.write(
1269 "%s - %d\n" %
1270 (category, configuration.failuresPerCategory[category]))
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001271
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001272 # Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1273 # This should not be necessary now.
1274 if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
1275 print("Terminating Test suite...")
1276 subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1277
1278 # Exiting.
Zachary Turner606e3a52015-12-08 01:15:30 +00001279 exitTestSuite(configuration.failed)
Zachary Turnerc432c8f2015-10-28 17:43:26 +00001280
1281if __name__ == "__main__":
Kate Stoneb9c1b512016-09-06 20:57:50 +00001282 print(
1283 __file__ +
1284 " is for use as a module only. It should not be run as a standalone script.")
Zachary Turner7d564542015-11-02 19:19:49 +00001285 sys.exit(-1)