1"""
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
21from __future__ import absolute_import
22from __future__ import print_function
23
24# System modules
25import atexit
26import os
27import errno
28import logging
29import platform
30import re
31import signal
32import socket
33import subprocess
34import sys
35
36# Third-party modules
37import six
38import unittest2
39
40# LLDB Modules
41import lldbsuite
42from . import configuration
43from . import dotest_args
44from . import lldbtest_config
45from . import test_categories
46from lldbsuite.test_event import formatter
47from . import test_result
48from lldbsuite.test_event.event_builder import EventBuilder
49from ..support import seven
50
51
52def is_exe(fpath):
53    """Returns true if fpath is an executable."""
54    if fpath == None:
55      return False
56    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
57
58
59def which(program):
60    """Returns the full path to a program; None otherwise."""
61    fpath, fname = os.path.split(program)
62    if fpath:
63        if is_exe(program):
64            return program
65    else:
66        for path in os.environ["PATH"].split(os.pathsep):
67            exe_file = os.path.join(path, program)
68            if is_exe(exe_file):
69                return exe_file
70    return None
71
72
73class _WritelnDecorator(object):
74    """Used to decorate file-like objects with a handy 'writeln' method"""
75
76    def __init__(self, stream):
77        self.stream = stream
78
79    def __getattr__(self, attr):
80        if attr in ('stream', '__getstate__'):
81            raise AttributeError(attr)
82        return getattr(self.stream, attr)
83
84    def writeln(self, arg=None):
85        if arg:
86            self.write(arg)
87        self.write('\n')  # text-mode streams translate to \r\n if needed
88
89#
90# Global variables:
91#
92
93
94def usage(parser):
95    parser.print_help()
96    if configuration.verbose > 0:
97        print("""
98Examples:
99
100This is an example of using the -f option to pinpoint to a specific test class
101and test method to be run:
102
103$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
104----------------------------------------------------------------------
105Collected 1 test
106
107test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
108Test 'frame variable this' when stopped on a class constructor. ... ok
109
110----------------------------------------------------------------------
111Ran 1 test in 1.396s
112
113OK
114
115And this is an example of using the -p option to run a single file (the filename
116matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
117
118$ ./dotest.py -v -p ObjC
119----------------------------------------------------------------------
120Collected 4 tests
121
122test_break_with_dsym (TestObjCMethods.FoundationTestCase)
123Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
124test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
125Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
126test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
127Lookup objective-c data types and evaluate expressions. ... ok
128test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
129Lookup objective-c data types and evaluate expressions. ... ok
130
131----------------------------------------------------------------------
132Ran 4 tests in 16.661s
133
134OK
135
136Running of this script also sets up the LLDB_TEST environment variable so that
137individual test cases can locate their supporting files correctly.  The script
138tries to set up Python's search paths for modules by looking at the build tree
139relative to this script.  See also the '-i' option in the following example.
140
141Finally, this is an example of using the lldb.py module distributed/installed by
142Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
143option to add some delay between two tests.  It uses ARCH=x86_64 to specify that
144as the architecture and CC=clang to specify the compiler used for the test run:
145
146$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
147
148Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
149----------------------------------------------------------------------
150Collected 2 tests
151
152test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
153Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
154test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
155Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
156
157----------------------------------------------------------------------
158Ran 2 tests in 5.659s
159
160OK
161
162The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
163notify the directory containing the session logs for test failures or errors.
164In case there is any test failure/error, a similar message is appended at the
165end of the stderr output for your convenience.
166
167ENABLING LOGS FROM TESTS
168
169Option 1:
170
171Writing logs into different files per test case::
172
173This option is particularly useful when multiple dotest instances are created
174by dosep.py
175
176$ ./dotest.py --channel "lldb all"
177
178$ ./dotest.py --channel "lldb all" --channel "gdb-remote packets"
179
180These log files are written to:
181
182<session-dir>/<test-id>-host.log (logs from lldb host process)
183<session-dir>/<test-id>-server.log (logs from debugserver/lldb-server)
184<session-dir>/<test-id>-<test-result>.log (console logs)
185
186By default, logs from successful runs are deleted.  Use the --log-success flag
187to create reference logs for debugging.
188
189$ ./dotest.py --log-success
190
191Option 2: (DEPRECATED)
192
193The following options can only enable logs from the host lldb process.
194Only categories from the "lldb" or "gdb-remote" channels can be enabled
195They also do not automatically enable logs in locally running debug servers.
196Also, logs from all test case are written into each log file
197
198o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
199  with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
200
201o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
202  'process.gdb-remote' subsystem with a default option of 'packets' if
203  GDB_REMOTE_LOG_OPTION is not defined.
204
205""")
206    sys.exit(0)
207
208
209def parseExclusion(exclusion_file):
210    """Parse an exclusion file, of the following format, where
211       'skip files', 'skip methods', 'xfail files', and 'xfail methods'
212       are the possible list heading values:
213
214       skip files
215       <file name>
216       <file name>
217
218       xfail methods
219       <method name>
220    """
221    excl_type = None
222
223    with open(exclusion_file) as f:
224        for line in f:
225            line = line.strip()
226            if not excl_type:
227                excl_type = line
228                continue
229
230            if not line:
231                excl_type = None
232            elif excl_type == 'skip':
233                if not configuration.skip_tests:
234                    configuration.skip_tests = []
235                configuration.skip_tests.append(line)
236            elif excl_type == 'xfail':
237                if not configuration.xfail_tests:
238                    configuration.xfail_tests = []
239                configuration.xfail_tests.append(line)
240
241
242def parseOptionsAndInitTestdirs():
243    """Initialize the list of directories containing our unittest scripts.
244
245    '-h/--help as the first option prints out usage info and exit the program.
246    """
247
248    do_help = False
249
250    platform_system = platform.system()
251    platform_machine = platform.machine()
252
253    parser = dotest_args.create_parser()
254    args = dotest_args.parse_args(parser, sys.argv[1:])
255
256    if args.unset_env_varnames:
257        for env_var in args.unset_env_varnames:
258            if env_var in os.environ:
259                # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
260                # is automatically translated into a corresponding call to
261                # unsetenv().
262                del os.environ[env_var]
263                # os.unsetenv(env_var)
264
265    if args.set_env_vars:
266        for env_var in args.set_env_vars:
267            parts = env_var.split('=', 1)
268            if len(parts) == 1:
269                os.environ[parts[0]] = ""
270            else:
271                os.environ[parts[0]] = parts[1]
272
273    # only print the args if being verbose (and parsable is off)
274    if args.v and not args.q:
275        print(sys.argv)
276
277    if args.h:
278        do_help = True
279
280    if args.compiler:
281        configuration.compiler = os.path.realpath(args.compiler)
282        if not is_exe(configuration.compiler):
283            configuration.compiler = which(args.compiler)
284        if not is_exe(configuration.compiler):
285            logging.error(
286                    '%s is not a valid compiler executable; aborting...',
287                    args.compiler)
288            sys.exit(-1)
289    else:
290        # Use a compiler appropriate appropriate for the Apple SDK if one was
291        # specified
292        if platform_system == 'Darwin' and args.apple_sdk:
293            configuration.compiler = seven.get_command_output(
294                'xcrun -sdk "%s" -find clang 2> /dev/null' %
295                (args.apple_sdk))
296        else:
297            # 'clang' on ubuntu 14.04 is 3.4 so we try clang-3.5 first
298            candidateCompilers = ['clang-3.5', 'clang', 'gcc']
299            for candidate in candidateCompilers:
300                if which(candidate):
301                    configuration.compiler = candidate
302                    break
303
304    if args.channels:
305        lldbtest_config.channels = args.channels
306
307    if args.log_success:
308        lldbtest_config.log_success = args.log_success
309
310    # Set SDKROOT if we are using an Apple SDK
311    if platform_system == 'Darwin' and args.apple_sdk:
312        os.environ['SDKROOT'] = seven.get_command_output(
313            'xcrun --sdk "%s" --show-sdk-path 2> /dev/null' %
314            (args.apple_sdk))
315
316    if args.arch:
317        configuration.arch = args.arch
318        if configuration.arch.startswith(
319                'arm') and platform_system == 'Darwin' and not args.apple_sdk:
320            os.environ['SDKROOT'] = seven.get_command_output(
321                'xcrun --sdk iphoneos.internal --show-sdk-path 2> /dev/null')
322            if not os.path.exists(os.environ['SDKROOT']):
323                os.environ['SDKROOT'] = seven.get_command_output(
324                    'xcrun --sdk iphoneos --show-sdk-path 2> /dev/null')
325    else:
326        configuration.arch = platform_machine
327
328    if args.categoriesList:
329        configuration.categoriesList = set(
330            test_categories.validate(
331                args.categoriesList, False))
332        configuration.useCategories = True
333    else:
334        configuration.categoriesList = []
335
336    if args.skipCategories:
337        configuration.skipCategories = test_categories.validate(
338            args.skipCategories, False)
339
340    if args.E:
341        cflags_extras = args.E
342        os.environ['CFLAGS_EXTRAS'] = cflags_extras
343
344    if args.d:
345        sys.stdout.write(
346            "Suspending the process %d to wait for debugger to attach...\n" %
347            os.getpid())
348        sys.stdout.flush()
349        os.kill(os.getpid(), signal.SIGSTOP)
350
351    if args.f:
352        if any([x.startswith('-') for x in args.f]):
353            usage(parser)
354        configuration.filters.extend(args.f)
355        # Shut off multiprocessing mode when additional filters are specified.
356        # The rational is that the user is probably going after a very specific
357        # test and doesn't need a bunch of parallel test runners all looking for
358        # it in a frenzy.  Also, '-v' now spits out all test run output even
359        # on success, so the standard recipe for redoing a failing test (with -v
360        # and a -f to filter to the specific test) now causes all test scanning
361        # (in parallel) to print results for do-nothing runs in a very distracting
362        # manner.  If we really need filtered parallel runs in the future, consider
363        # adding a --no-output-on-success that prevents -v from setting
364        # output-on-success.
365        configuration.no_multiprocess_test_runner = True
366
367    if args.l:
368        configuration.skip_long_running_test = False
369
370    if args.framework:
371        configuration.lldbFrameworkPath = args.framework
372
373    if args.executable:
374        # lldb executable is passed explicitly
375        lldbtest_config.lldbExec = os.path.realpath(args.executable)
376        if not is_exe(lldbtest_config.lldbExec):
377            lldbtest_config.lldbExec = which(args.executable)
378        if not is_exe(lldbtest_config.lldbExec):
379            logging.error(
380                    '%s is not a valid executable to test; aborting...',
381                    args.executable)
382            sys.exit(-1)
383
384    if args.server:
385        os.environ['LLDB_DEBUGSERVER_PATH'] = args.server
386
387    if args.excluded:
388        for excl_file in args.excluded:
389            parseExclusion(excl_file)
390
391    if args.p:
392        if args.p.startswith('-'):
393            usage(parser)
394        configuration.regexp = args.p
395
396    if args.q:
397        configuration.parsable = True
398
399    if args.s:
400        if args.s.startswith('-'):
401            usage(parser)
402        configuration.sdir_name = args.s
403    configuration.session_file_format = args.session_file_format
404
405    if args.t:
406        os.environ['LLDB_COMMAND_TRACE'] = 'YES'
407
408    if args.v:
409        configuration.verbose = 2
410
411    # argparse makes sure we have a number
412    if args.sharp:
413        configuration.count = args.sharp
414
415    if sys.platform.startswith('win32'):
416        os.environ['LLDB_DISABLE_CRASH_DIALOG'] = str(
417            args.disable_crash_dialog)
418        os.environ['LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE'] = str(True)
419
420    if do_help:
421        usage(parser)
422
423    if args.no_multiprocess:
424        configuration.no_multiprocess_test_runner = True
425
426    if args.inferior:
427        configuration.is_inferior_test_runner = True
428
429    if args.num_threads:
430        configuration.num_threads = args.num_threads
431
432    if args.test_subdir:
433        configuration.multiprocess_test_subdir = args.test_subdir
434
435    if args.test_runner_name:
436        configuration.test_runner_name = args.test_runner_name
437
438    # Capture test results-related args.
439    if args.curses and not args.inferior:
440        # Act as if the following args were set.
441        args.results_formatter = "lldbsuite.test_event.formatter.curses.Curses"
442        args.results_file = "stdout"
443
444    if args.results_file:
445        configuration.results_filename = args.results_file
446
447    if args.results_port:
448        configuration.results_port = args.results_port
449
450    if args.results_file and args.results_port:
451        sys.stderr.write(
452            "only one of --results-file and --results-port should "
453            "be specified\n")
454        usage(args)
455
456    if args.results_formatter:
457        configuration.results_formatter_name = args.results_formatter
458    if args.results_formatter_options:
459        configuration.results_formatter_options = args.results_formatter_options
460
461    # Default to using the BasicResultsFormatter if no formatter is specified
462    # and we're not a test inferior.
463    if not args.inferior and configuration.results_formatter_name is None:
464        configuration.results_formatter_name = (
465            "lldbsuite.test_event.formatter.results_formatter.ResultsFormatter")
466
467    # rerun-related arguments
468    configuration.rerun_all_issues = args.rerun_all_issues
469    configuration.rerun_max_file_threshold = args.rerun_max_file_threshold
470
471    if args.lldb_platform_name:
472        configuration.lldb_platform_name = args.lldb_platform_name
473    if args.lldb_platform_url:
474        configuration.lldb_platform_url = args.lldb_platform_url
475    if args.lldb_platform_working_dir:
476        configuration.lldb_platform_working_dir = args.lldb_platform_working_dir
477    if args.test_build_dir:
478        configuration.test_build_dir = args.test_build_dir
479
480    if args.event_add_entries and len(args.event_add_entries) > 0:
481        entries = {}
482        # Parse out key=val pairs, separated by comma
483        for keyval in args.event_add_entries.split(","):
484            key_val_entry = keyval.split("=")
485            if len(key_val_entry) == 2:
486                (key, val) = key_val_entry
487                val_parts = val.split(':')
488                if len(val_parts) > 1:
489                    (val, val_type) = val_parts
490                    if val_type == 'int':
491                        val = int(val)
492                entries[key] = val
493        # Tell the event builder to create all events with these
494        # key/val pairs in them.
495        if len(entries) > 0:
496            EventBuilder.add_entries_to_all_events(entries)
497
498    # Gather all the dirs passed on the command line.
499    if len(args.args) > 0:
500        configuration.testdirs = list(
501            map(lambda x: os.path.realpath(os.path.abspath(x)), args.args))
502        # Shut off multiprocessing mode when test directories are specified.
503        configuration.no_multiprocess_test_runner = True
504
505    lldbtest_config.codesign_identity = args.codesign_identity
506
507    #print("testdirs:", testdirs)
508
509
510def getXcodeOutputPaths(lldbRootDirectory):
511    result = []
512
513    # These are for xcode build directories.
514    xcode3_build_dir = ['build']
515    xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
516
517    configurations = [
518        ['Debug'],
519        ['DebugClang'],
520        ['Release'],
521        ['BuildAndIntegration']]
522    xcode_build_dirs = [xcode3_build_dir, xcode4_build_dir]
523    for configuration in configurations:
524        for xcode_build_dir in xcode_build_dirs:
525            outputPath = os.path.join(
526                lldbRootDirectory, *(xcode_build_dir + configuration))
527            result.append(outputPath)
528
529    return result
530
531
532def createSocketToLocalPort(port):
533    def socket_closer(s):
534        """Close down an opened socket properly."""
535        s.shutdown(socket.SHUT_RDWR)
536        s.close()
537
538    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
539    sock.connect(("localhost", port))
540    return (sock, lambda: socket_closer(sock))
541
542
543def setupTestResults():
544    """Sets up test results-related objects based on arg settings."""
545    # Setup the results formatter configuration.
546    formatter_config = formatter.FormatterConfig()
547    formatter_config.filename = configuration.results_filename
548    formatter_config.formatter_name = configuration.results_formatter_name
549    formatter_config.formatter_options = (
550        configuration.results_formatter_options)
551    formatter_config.port = configuration.results_port
552
553    # Create the results formatter.
554    formatter_spec = formatter.create_results_formatter(
555        formatter_config)
556    if formatter_spec is not None and formatter_spec.formatter is not None:
557        configuration.results_formatter_object = formatter_spec.formatter
558
559        # Send an initialize message to the formatter.
560        initialize_event = EventBuilder.bare_event("initialize")
561        if isMultiprocessTestRunner():
562            if (configuration.test_runner_name is not None and
563                    configuration.test_runner_name == "serial"):
564                # Only one worker queue here.
565                worker_count = 1
566            else:
567                # Workers will be the number of threads specified.
568                worker_count = configuration.num_threads
569        else:
570            worker_count = 1
571        initialize_event["worker_count"] = worker_count
572
573        formatter_spec.formatter.handle_event(initialize_event)
574
575        # Make sure we clean up the formatter on shutdown.
576        if formatter_spec.cleanup_func is not None:
577            atexit.register(formatter_spec.cleanup_func)
578
579
580def getOutputPaths(lldbRootDirectory):
581    """
582    Returns typical build output paths for the lldb executable
583
584    lldbDirectory - path to the root of the lldb svn/git repo
585    """
586    result = []
587
588    if sys.platform == 'darwin':
589        result.extend(getXcodeOutputPaths(lldbRootDirectory))
590
591    # cmake builds?  look for build or build/host folder next to llvm directory
592    # lldb is located in llvm/tools/lldb so we need to go up three levels
593    llvmParentDir = os.path.abspath(
594        os.path.join(
595            lldbRootDirectory,
596            os.pardir,
597            os.pardir,
598            os.pardir))
599    result.append(os.path.join(llvmParentDir, 'build', 'bin'))
600    result.append(os.path.join(llvmParentDir, 'build', 'host', 'bin'))
601
602    # some cmake developers keep their build directory beside their lldb
603    # directory
604    lldbParentDir = os.path.abspath(os.path.join(lldbRootDirectory, os.pardir))
605    result.append(os.path.join(lldbParentDir, 'build', 'bin'))
606    result.append(os.path.join(lldbParentDir, 'build', 'host', 'bin'))
607
608    return result
609
610
611def setupSysPath():
612    """
613    Add LLDB.framework/Resources/Python to the search paths for modules.
614    As a side effect, we also discover the 'lldb' executable and export it here.
615    """
616
617    # Get the directory containing the current script.
618    if "DOTEST_PROFILE" in os.environ and "DOTEST_SCRIPT_DIR" in os.environ:
619        scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
620    else:
621        scriptPath = os.path.dirname(os.path.realpath(__file__))
622    if not scriptPath.endswith('test'):
623        print("This script expects to reside in lldb's test directory.")
624        sys.exit(-1)
625
626    os.environ["LLDB_TEST"] = scriptPath
627
628    # Set up the root build directory.
629    builddir = configuration.test_build_dir
630    if not configuration.test_build_dir:
631        raise Exception("test_build_dir is not set")
632    os.environ["LLDB_BUILD"] = os.path.abspath(configuration.test_build_dir)
633
634    # Set up the LLDB_SRC environment variable, so that the tests can locate
635    # the LLDB source code.
636    os.environ["LLDB_SRC"] = lldbsuite.lldb_root
637
638    pluginPath = os.path.join(scriptPath, 'plugins')
639    toolsLLDBMIPath = os.path.join(scriptPath, 'tools', 'lldb-mi')
640    toolsLLDBServerPath = os.path.join(scriptPath, 'tools', 'lldb-server')
641
642    # Insert script dir, plugin dir, lldb-mi dir and lldb-server dir to the
643    # sys.path.
644    sys.path.insert(0, pluginPath)
645    # Adding test/tools/lldb-mi to the path makes it easy
646    sys.path.insert(0, toolsLLDBMIPath)
647    # to "import lldbmi_testcase" from the MI tests
648    # Adding test/tools/lldb-server to the path makes it easy
649    sys.path.insert(0, toolsLLDBServerPath)
650    # to "import lldbgdbserverutils" from the lldb-server tests
651
652    # This is the root of the lldb git/svn checkout
653    # When this changes over to a package instead of a standalone script, this
654    # will be `lldbsuite.lldb_root`
655    lldbRootDirectory = lldbsuite.lldb_root
656
657    # Some of the tests can invoke the 'lldb' command directly.
658    # We'll try to locate the appropriate executable right here.
659
660    # The lldb executable can be set from the command line
661    # if it's not set, we try to find it now
662    # first, we try the environment
663    if not lldbtest_config.lldbExec:
664        # First, you can define an environment variable LLDB_EXEC specifying the
665        # full pathname of the lldb executable.
666        if "LLDB_EXEC" in os.environ:
667            lldbtest_config.lldbExec = os.environ["LLDB_EXEC"]
668
669    if not lldbtest_config.lldbExec:
670        outputPaths = getOutputPaths(lldbRootDirectory)
671        for outputPath in outputPaths:
672            candidatePath = os.path.join(outputPath, 'lldb')
673            if is_exe(candidatePath):
674                lldbtest_config.lldbExec = candidatePath
675                break
676
677    if not lldbtest_config.lldbExec:
678        # Last, check the path
679        lldbtest_config.lldbExec = which('lldb')
680
681    if lldbtest_config.lldbExec and not is_exe(lldbtest_config.lldbExec):
682        print(
683            "'{}' is not a path to a valid executable".format(
684                lldbtest_config.lldbExec))
685        lldbtest_config.lldbExec = None
686
687    if not lldbtest_config.lldbExec:
688        print("The 'lldb' executable cannot be located.  Some of the tests may not be run as a result.")
689        sys.exit(-1)
690
691    # confusingly, this is the "bin" directory
692    lldbLibDir = os.path.dirname(lldbtest_config.lldbExec)
693    os.environ["LLDB_LIB_DIR"] = lldbLibDir
694    lldbImpLibDir = os.path.join(
695        lldbLibDir,
696        '..',
697        'lib') if sys.platform.startswith('win32') else lldbLibDir
698    os.environ["LLDB_IMPLIB_DIR"] = lldbImpLibDir
699    print("LLDB library dir:", os.environ["LLDB_LIB_DIR"])
700    print("LLDB import library dir:", os.environ["LLDB_IMPLIB_DIR"])
701    os.system('%s -v' % lldbtest_config.lldbExec)
702
703    # Assume lldb-mi is in same place as lldb
704    # If not found, disable the lldb-mi tests
705    # TODO: Append .exe on Windows
706    #   - this will be in a separate commit in case the mi tests fail horribly
707    lldbDir = os.path.dirname(lldbtest_config.lldbExec)
708    lldbMiExec = os.path.join(lldbDir, "lldb-mi")
709    if is_exe(lldbMiExec):
710        os.environ["LLDBMI_EXEC"] = lldbMiExec
711    else:
712        if not configuration.shouldSkipBecauseOfCategories(["lldb-mi"]):
713            print(
714                "The 'lldb-mi' executable cannot be located.  The lldb-mi tests can not be run as a result.")
715            configuration.skipCategories.append("lldb-mi")
716
717    lldbPythonDir = None  # The directory that contains 'lldb/__init__.py'
718    if not configuration.lldbFrameworkPath and os.path.exists(os.path.join(lldbLibDir, "LLDB.framework")):
719        configuration.lldbFrameworkPath = os.path.join(lldbLibDir, "LLDB.framework")
720    if configuration.lldbFrameworkPath:
721        lldbtest_config.lldbFrameworkPath = configuration.lldbFrameworkPath
722        candidatePath = os.path.join(
723            configuration.lldbFrameworkPath, 'Resources', 'Python')
724        if os.path.isfile(os.path.join(candidatePath, 'lldb/__init__.py')):
725            lldbPythonDir = candidatePath
726        if not lldbPythonDir:
727            print(
728                'Resources/Python/lldb/__init__.py was not found in ' +
729                configuration.lldbFrameworkPath)
730            sys.exit(-1)
731    else:
732        # If our lldb supports the -P option, use it to find the python path:
733        init_in_python_dir = os.path.join('lldb', '__init__.py')
734
735        lldb_dash_p_result = subprocess.check_output(
736            [lldbtest_config.lldbExec, "-P"], stderr=subprocess.STDOUT, universal_newlines=True)
737
738        if lldb_dash_p_result and not lldb_dash_p_result.startswith(
739                ("<", "lldb: invalid option:")) and not lldb_dash_p_result.startswith("Traceback"):
740            lines = lldb_dash_p_result.splitlines()
741
742            # Workaround for readline vs libedit issue on FreeBSD.  If stdout
743            # is not a terminal Python executes
744            #     rl_variable_bind ("enable-meta-key", "off");
745            # This produces a warning with FreeBSD's libedit because the
746            # enable-meta-key variable is unknown.  Not an issue on Apple
747            # because cpython commit f0ab6f9f0603 added a #ifndef __APPLE__
748            # around the call.  See http://bugs.python.org/issue19884 for more
749            # information.  For now we just discard the warning output.
750            if len(lines) >= 1 and lines[0].startswith(
751                    "bind: Invalid command"):
752                lines.pop(0)
753
754            # Taking the last line because lldb outputs
755            # 'Cannot read termcap database;\nusing dumb terminal settings.\n'
756            # before the path
757            if len(lines) >= 1 and os.path.isfile(
758                    os.path.join(lines[-1], init_in_python_dir)):
759                lldbPythonDir = lines[-1]
760                if "freebsd" in sys.platform or "linux" in sys.platform:
761                    os.environ['LLDB_LIB_DIR'] = os.path.join(
762                        lldbPythonDir, '..', '..')
763
764        if not lldbPythonDir:
765            if platform.system() == "Darwin":
766                python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
767                outputPaths = getXcodeOutputPaths(lldbRootDirectory)
768                for outputPath in outputPaths:
769                    candidatePath = os.path.join(
770                        outputPath, *python_resource_dir)
771                    if os.path.isfile(
772                        os.path.join(
773                            candidatePath,
774                            init_in_python_dir)):
775                        lldbPythonDir = candidatePath
776                        break
777
778                if not lldbPythonDir:
779                    print("lldb.py is not found, some tests may fail.")
780            else:
781                print(
782                    "Unable to load lldb extension module.  Possible reasons for this include:")
783                print("  1) LLDB was built with LLDB_DISABLE_PYTHON=1")
784                print(
785                    "  2) PYTHONPATH and PYTHONHOME are not set correctly.  PYTHONHOME should refer to")
786                print(
787                    "     the version of Python that LLDB built and linked against, and PYTHONPATH")
788                print(
789                    "     should contain the Lib directory for the same python distro, as well as the")
790                print("     location of LLDB\'s site-packages folder.")
791                print(
792                    "  3) A different version of Python than that which was built against is exported in")
793                print("     the system\'s PATH environment variable, causing conflicts.")
794                print(
795                    "  4) The executable '%s' could not be found.  Please check " %
796                    lldbtest_config.lldbExec)
797                print("     that it exists and is executable.")
798
799    if lldbPythonDir:
800        lldbPythonDir = os.path.normpath(lldbPythonDir)
801        # Some of the code that uses this path assumes it hasn't resolved the Versions... link.
802        # If the path we've constructed looks like that, then we'll strip out
803        # the Versions/A part.
804        (before, frameWithVersion, after) = lldbPythonDir.rpartition(
805            "LLDB.framework/Versions/A")
806        if frameWithVersion != "":
807            lldbPythonDir = before + "LLDB.framework" + after
808
809        lldbPythonDir = os.path.abspath(lldbPythonDir)
810
811        # If tests need to find LLDB_FRAMEWORK, now they can do it
812        os.environ["LLDB_FRAMEWORK"] = os.path.dirname(
813            os.path.dirname(lldbPythonDir))
814
815        # This is to locate the lldb.py module.  Insert it right after
816        # sys.path[0].
817        sys.path[1:1] = [lldbPythonDir]
818
819
820def visit_file(dir, name):
821    # Try to match the regexp pattern, if specified.
822    if configuration.regexp:
823        if not re.search(configuration.regexp, name):
824            # We didn't match the regex, we're done.
825            return
826
827    if configuration.skip_tests:
828        for file_regexp in configuration.skip_tests:
829            if re.search(file_regexp, name):
830                return
831
832    # We found a match for our test.  Add it to the suite.
833
834    # Update the sys.path first.
835    if not sys.path.count(dir):
836        sys.path.insert(0, dir)
837    base = os.path.splitext(name)[0]
838
839    # Thoroughly check the filterspec against the base module and admit
840    # the (base, filterspec) combination only when it makes sense.
841    filterspec = None
842    for filterspec in configuration.filters:
843        # Optimistically set the flag to True.
844        filtered = True
845        module = __import__(base)
846        parts = filterspec.split('.')
847        obj = module
848        for part in parts:
849            try:
850                parent, obj = obj, getattr(obj, part)
851            except AttributeError:
852                # The filterspec has failed.
853                filtered = False
854                break
855
856        # If filtered, we have a good filterspec.  Add it.
857        if filtered:
858            # print("adding filter spec %s to module %s" % (filterspec, module))
859            configuration.suite.addTests(
860                unittest2.defaultTestLoader.loadTestsFromName(
861                    filterspec, module))
862            continue
863
864    # Forgo this module if the (base, filterspec) combo is invalid
865    if configuration.filters and not filtered:
866        return
867
868    if not filterspec or not filtered:
869        # Add the entire file's worth of tests since we're not filtered.
870        # Also the fail-over case when the filterspec branch
871        # (base, filterspec) combo doesn't make sense.
872        configuration.suite.addTests(
873            unittest2.defaultTestLoader.loadTestsFromName(base))
874
875
876def visit(prefix, dir, names):
877    """Visitor function for os.path.walk(path, visit, arg)."""
878
879    dir_components = set(dir.split(os.sep))
880    excluded_components = set(['.svn', '.git'])
881    if dir_components.intersection(excluded_components):
882        return
883
884    # Gather all the Python test file names that follow the Test*.py pattern.
885    python_test_files = [
886        name
887        for name in names
888        if name.endswith('.py') and name.startswith(prefix)]
889
890    # Visit all the python test files.
891    for name in python_test_files:
892        try:
893            # Ensure we error out if we have multiple tests with the same
894            # base name.
895            # Future improvement: find all the places where we work with base
896            # names and convert to full paths.  We have directory structure
897            # to disambiguate these, so we shouldn't need this constraint.
898            if name in configuration.all_tests:
899                raise Exception("Found multiple tests with the name %s" % name)
900            configuration.all_tests.add(name)
901
902            # Run the relevant tests in the python file.
903            visit_file(dir, name)
904        except Exception as ex:
905            # Convert this exception to a test event error for the file.
906            test_filename = os.path.abspath(os.path.join(dir, name))
907            if configuration.results_formatter_object is not None:
908                # Grab the backtrace for the exception.
909                import traceback
910                backtrace = traceback.format_exc()
911
912                # Generate the test event.
913                configuration.results_formatter_object.handle_event(
914                    EventBuilder.event_for_job_test_add_error(
915                        test_filename, ex, backtrace))
916            raise
917
918
919def disabledynamics():
920    import lldb
921    ci = lldb.DBG.GetCommandInterpreter()
922    res = lldb.SBCommandReturnObject()
923    ci.HandleCommand(
924        "setting set target.prefer-dynamic-value no-dynamic-values",
925        res,
926        False)
927    if not res.Succeeded():
928        raise Exception('disabling dynamic type support failed')
929
930
931def lldbLoggings():
932    import lldb
933    """Check and do lldb loggings if necessary."""
934
935    # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
936    # defined.  Use ${LLDB_LOG} to specify the log file.
937    ci = lldb.DBG.GetCommandInterpreter()
938    res = lldb.SBCommandReturnObject()
939    if ("LLDB_LOG" in os.environ):
940        open(os.environ["LLDB_LOG"], 'w').close()
941        if ("LLDB_LOG_OPTION" in os.environ):
942            lldb_log_option = os.environ["LLDB_LOG_OPTION"]
943        else:
944            lldb_log_option = "event process expr state api"
945        ci.HandleCommand(
946            "log enable -n -f " +
947            os.environ["LLDB_LOG"] +
948            " lldb " +
949            lldb_log_option,
950            res)
951        if not res.Succeeded():
952            raise Exception('log enable failed (check LLDB_LOG env variable)')
953
954    if ("LLDB_LINUX_LOG" in os.environ):
955        open(os.environ["LLDB_LINUX_LOG"], 'w').close()
956        if ("LLDB_LINUX_LOG_OPTION" in os.environ):
957            lldb_log_option = os.environ["LLDB_LINUX_LOG_OPTION"]
958        else:
959            lldb_log_option = "event process expr state api"
960        ci.HandleCommand(
961            "log enable -n -f " +
962            os.environ["LLDB_LINUX_LOG"] +
963            " linux " +
964            lldb_log_option,
965            res)
966        if not res.Succeeded():
967            raise Exception(
968                'log enable failed (check LLDB_LINUX_LOG env variable)')
969
970    # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
971    # Use ${GDB_REMOTE_LOG} to specify the log file.
972    if ("GDB_REMOTE_LOG" in os.environ):
973        if ("GDB_REMOTE_LOG_OPTION" in os.environ):
974            gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
975        else:
976            gdb_remote_log_option = "packets process"
977        ci.HandleCommand(
978            "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
979            + gdb_remote_log_option,
980            res)
981        if not res.Succeeded():
982            raise Exception(
983                'log enable failed (check GDB_REMOTE_LOG env variable)')
984
985
986def getMyCommandLine():
987    return ' '.join(sys.argv)
988
989# ======================================== #
990#                                          #
991# Execution of the test driver starts here #
992#                                          #
993# ======================================== #
994
995
996def checkDsymForUUIDIsNotOn():
997    cmd = ["defaults", "read", "com.apple.DebugSymbols"]
998    pipe = subprocess.Popen(
999        cmd,
1000        stdout=subprocess.PIPE,
1001        stderr=subprocess.STDOUT)
1002    cmd_output = pipe.stdout.read()
1003    if cmd_output and "DBGFileMappedPaths = " in cmd_output:
1004        print("%s =>" % ' '.join(cmd))
1005        print(cmd_output)
1006        print(
1007            "Disable automatic lookup and caching of dSYMs before running the test suite!")
1008        print("Exiting...")
1009        sys.exit(0)
1010
1011
1012def exitTestSuite(exitCode=None):
1013    import lldb
1014    lldb.SBDebugger.Terminate()
1015    if exitCode:
1016        sys.exit(exitCode)
1017
1018
1019def isMultiprocessTestRunner():
1020    # We're not multiprocess when we're either explicitly
1021    # the inferior (as specified by the multiprocess test
1022    # runner) OR we've been told to skip using the multiprocess
1023    # test runner
1024    return not (
1025        configuration.is_inferior_test_runner or configuration.no_multiprocess_test_runner)
1026
1027
1028def getVersionForSDK(sdk):
1029    sdk = str.lower(sdk)
1030    full_path = seven.get_command_output('xcrun -sdk %s --show-sdk-path' % sdk)
1031    basename = os.path.basename(full_path)
1032    basename = os.path.splitext(basename)[0]
1033    basename = str.lower(basename)
1034    ver = basename.replace(sdk, '')
1035    return ver
1036
1037
1038def getPathForSDK(sdk):
1039    sdk = str.lower(sdk)
1040    full_path = seven.get_command_output('xcrun -sdk %s --show-sdk-path' % sdk)
1041    if os.path.exists(full_path):
1042        return full_path
1043    return None
1044
1045
1046def setDefaultTripleForPlatform():
1047    if configuration.lldb_platform_name == 'ios-simulator':
1048        triple_str = 'x86_64-apple-ios%s' % (
1049            getVersionForSDK('iphonesimulator'))
1050        os.environ['TRIPLE'] = triple_str
1051        return {'TRIPLE': triple_str}
1052    return {}
1053
1054
1055def checkCompiler():
1056    # Add some intervention here to sanity check that the compiler requested is sane.
1057    # If found not to be an executable program, we abort.
1058    c = configuration.compiler
1059    if which(c):
1060        return
1061
1062    if not sys.platform.startswith("darwin"):
1063        raise Exception(c + " is not a valid compiler")
1064
1065    pipe = subprocess.Popen(
1066        ['xcrun', '-find', c], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
1067    cmd_output = pipe.stdout.read()
1068    if not cmd_output or "not found" in cmd_output:
1069        raise Exception(c + " is not a valid compiler")
1070
1071    configuration.compiler = cmd_output.split('\n')[0]
1072    print("'xcrun -find %s' returning %s" % (c, configuration.compiler))
1073
1074def canRunLibcxxTests():
1075    from lldbsuite.test import lldbplatformutil
1076
1077    platform = lldbplatformutil.getPlatform()
1078
1079    if lldbplatformutil.target_is_android() or lldbplatformutil.platformIsDarwin():
1080        return True, "libc++ always present"
1081
1082    if platform == "linux":
1083        if not os.path.isdir("/usr/include/c++/v1"):
1084            return False, "Unable to find libc++ installation"
1085        return True, "Headers found, let's hope they work"
1086
1087    return False, "Don't know how to build with libc++ on %s" % platform
1088
1089def checkLibcxxSupport():
1090    result, reason = canRunLibcxxTests()
1091    if result:
1092        return # libc++ supported
1093    if "libc++" in configuration.categoriesList:
1094        return # libc++ category explicitly requested, let it run.
1095    print("Libc++ tests will not be run because: " + reason)
1096    configuration.skipCategories.append("libc++")
1097
1098def run_suite():
1099    # On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
1100    # does not exist before proceeding to running the test suite.
1101    if sys.platform.startswith("darwin"):
1102        checkDsymForUUIDIsNotOn()
1103
1104    #
1105    # Start the actions by first parsing the options while setting up the test
1106    # directories, followed by setting up the search paths for lldb utilities;
1107    # then, we walk the directory trees and collect the tests into our test suite.
1108    #
1109    parseOptionsAndInitTestdirs()
1110
1111    # Setup test results (test results formatter and output handling).
1112    setupTestResults()
1113
1114    # If we are running as the multiprocess test runner, kick off the
1115    # multiprocess test runner here.
1116    if isMultiprocessTestRunner():
1117        from . import dosep
1118        dosep.main(
1119            configuration.num_threads,
1120            configuration.multiprocess_test_subdir,
1121            configuration.test_runner_name,
1122            configuration.results_formatter_object)
1123        raise Exception("should never get here")
1124    elif configuration.is_inferior_test_runner:
1125        # Shut off Ctrl-C processing in inferiors.  The parallel
1126        # test runner handles this more holistically.
1127        signal.signal(signal.SIGINT, signal.SIG_IGN)
1128
1129    setupSysPath()
1130
1131    #
1132    # If '-l' is specified, do not skip the long running tests.
1133    if not configuration.skip_long_running_test:
1134        os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
1135
1136    # For the time being, let's bracket the test runner within the
1137    # lldb.SBDebugger.Initialize()/Terminate() pair.
1138    import lldb
1139
1140    # Create a singleton SBDebugger in the lldb namespace.
1141    lldb.DBG = lldb.SBDebugger.Create()
1142
1143    if configuration.lldb_platform_name:
1144        print("Setting up remote platform '%s'" %
1145              (configuration.lldb_platform_name))
1146        lldb.remote_platform = lldb.SBPlatform(
1147            configuration.lldb_platform_name)
1148        if not lldb.remote_platform.IsValid():
1149            print(
1150                "error: unable to create the LLDB platform named '%s'." %
1151                (configuration.lldb_platform_name))
1152            exitTestSuite(1)
1153        if configuration.lldb_platform_url:
1154            # We must connect to a remote platform if a LLDB platform URL was
1155            # specified
1156            print(
1157                "Connecting to remote platform '%s' at '%s'..." %
1158                (configuration.lldb_platform_name, configuration.lldb_platform_url))
1159            platform_connect_options = lldb.SBPlatformConnectOptions(
1160                configuration.lldb_platform_url)
1161            err = lldb.remote_platform.ConnectRemote(platform_connect_options)
1162            if err.Success():
1163                print("Connected.")
1164            else:
1165                print("error: failed to connect to remote platform using URL '%s': %s" % (
1166                    configuration.lldb_platform_url, err))
1167                exitTestSuite(1)
1168        else:
1169            configuration.lldb_platform_url = None
1170
1171    platform_changes = setDefaultTripleForPlatform()
1172    first = True
1173    for key in platform_changes:
1174        if first:
1175            print("Environment variables setup for platform support:")
1176            first = False
1177        print("%s = %s" % (key, platform_changes[key]))
1178
1179    if configuration.lldb_platform_working_dir:
1180        print("Setting remote platform working directory to '%s'..." %
1181              (configuration.lldb_platform_working_dir))
1182        error = lldb.remote_platform.MakeDirectory(
1183            configuration.lldb_platform_working_dir, 448)  # 448 = 0o700
1184        if error.Fail():
1185            raise Exception("making remote directory '%s': %s" % (
1186                remote_test_dir, error))
1187
1188        if not lldb.remote_platform.SetWorkingDirectory(
1189                configuration.lldb_platform_working_dir):
1190            raise Exception("failed to set working directory '%s'" % remote_test_dir)
1191        lldb.DBG.SetSelectedPlatform(lldb.remote_platform)
1192    else:
1193        lldb.remote_platform = None
1194        configuration.lldb_platform_working_dir = None
1195        configuration.lldb_platform_url = None
1196
1197    # Set up the working directory.
1198    # Note that it's not dotest's job to clean this directory.
1199    import lldbsuite.test.lldbutil as lldbutil
1200    build_dir = configuration.test_build_dir
1201    lldbutil.mkdir_p(build_dir)
1202
1203    target_platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
1204
1205    checkLibcxxSupport()
1206
1207    # Don't do debugserver tests on everything except OS X.
1208    configuration.dont_do_debugserver_test = "linux" in target_platform or "freebsd" in target_platform or "windows" in target_platform
1209
1210    # Don't do lldb-server (llgs) tests on anything except Linux.
1211    configuration.dont_do_llgs_test = not ("linux" in target_platform)
1212
1213    #
1214    # Walk through the testdirs while collecting tests.
1215    #
1216    for testdir in configuration.testdirs:
1217        for (dirpath, dirnames, filenames) in os.walk(testdir):
1218            visit('Test', dirpath, filenames)
1219
1220    #
1221    # Now that we have loaded all the test cases, run the whole test suite.
1222    #
1223
1224    # Turn on lldb loggings if necessary.
1225    lldbLoggings()
1226
1227    # Disable default dynamic types for testing purposes
1228    disabledynamics()
1229
1230    # Install the control-c handler.
1231    unittest2.signals.installHandler()
1232
1233    # If sdir_name is not specified through the '-s sdir_name' option, get a
1234    # timestamp string and export it as LLDB_SESSION_DIR environment var.  This will
1235    # be used when/if we want to dump the session info of individual test cases
1236    # later on.
1237    #
1238    # See also TestBase.dumpSessionInfo() in lldbtest.py.
1239    import datetime
1240    # The windows platforms don't like ':' in the pathname.
1241    timestamp_started = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
1242    if not configuration.sdir_name:
1243        configuration.sdir_name = timestamp_started
1244    os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(
1245        os.getcwd(), configuration.sdir_name)
1246
1247    sys.stderr.write(
1248        "\nSession logs for test failures/errors/unexpected successes"
1249        " will go into directory '%s'\n" %
1250        configuration.sdir_name)
1251    sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
1252
1253    if not os.path.isdir(configuration.sdir_name):
1254        try:
1255            os.mkdir(configuration.sdir_name)
1256        except OSError as exception:
1257            if exception.errno != errno.EEXIST:
1258                raise
1259
1260    #
1261    # Invoke the default TextTestRunner to run the test suite
1262    #
1263    checkCompiler()
1264
1265    if not configuration.parsable:
1266        print("compiler=%s" % configuration.compiler)
1267
1268    # Iterating over all possible architecture and compiler combinations.
1269    os.environ["ARCH"] = configuration.arch
1270    os.environ["CC"] = configuration.compiler
1271    configString = "arch=%s compiler=%s" % (configuration.arch,
1272                                            configuration.compiler)
1273
1274    # Translate ' ' to '-' for pathname component.
1275    if six.PY2:
1276        import string
1277        tbl = string.maketrans(' ', '-')
1278    else:
1279        tbl = str.maketrans(' ', '-')
1280    configPostfix = configString.translate(tbl)
1281
1282    # Output the configuration.
1283    if not configuration.parsable:
1284        sys.stderr.write("\nConfiguration: " + configString + "\n")
1285
1286    # First, write out the number of collected test cases.
1287    if not configuration.parsable:
1288        sys.stderr.write(configuration.separator + "\n")
1289        sys.stderr.write(
1290            "Collected %d test%s\n\n" %
1291            (configuration.suite.countTestCases(),
1292             configuration.suite.countTestCases() != 1 and "s" or ""))
1293
1294    if configuration.parsable:
1295        v = 0
1296    else:
1297        v = configuration.verbose
1298
1299    # Invoke the test runner.
1300    if configuration.count == 1:
1301        result = unittest2.TextTestRunner(
1302            stream=sys.stderr,
1303            verbosity=v,
1304            resultclass=test_result.LLDBTestResult).run(
1305            configuration.suite)
1306    else:
1307        # We are invoking the same test suite more than once.  In this case,
1308        # mark __ignore_singleton__ flag as True so the signleton pattern is
1309        # not enforced.
1310        test_result.LLDBTestResult.__ignore_singleton__ = True
1311        for i in range(configuration.count):
1312
1313            result = unittest2.TextTestRunner(
1314                stream=sys.stderr,
1315                verbosity=v,
1316                resultclass=test_result.LLDBTestResult).run(
1317                configuration.suite)
1318
1319    configuration.failed = not result.wasSuccessful()
1320
1321    if configuration.sdir_has_content and not configuration.parsable:
1322        sys.stderr.write(
1323            "Session logs for test failures/errors/unexpected successes"
1324            " can be found in directory '%s'\n" %
1325            configuration.sdir_name)
1326
1327    if configuration.useCategories and len(
1328            configuration.failuresPerCategory) > 0:
1329        sys.stderr.write("Failures per category:\n")
1330        for category in configuration.failuresPerCategory:
1331            sys.stderr.write(
1332                "%s - %d\n" %
1333                (category, configuration.failuresPerCategory[category]))
1334
1335    # Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
1336    # This should not be necessary now.
1337    if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
1338        print("Terminating Test suite...")
1339        subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
1340
1341    # Exiting.
1342    exitTestSuite(configuration.failed)
1343
1344if __name__ == "__main__":
1345    print(
1346        __file__ +
1347        " is for use as a module only.  It should not be run as a standalone script.")
1348    sys.exit(-1)
1349