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 importlib
27import os
28import errno
29import platform
30import progress
31import signal
32import socket
33import subprocess
34import sys
35import inspect
36
37# Third-party modules
38import six
39import unittest2
40
41# LLDB Modules
42import lldbsuite
43from . import dotest_args
44from . import lldbtest_config
45from . import test_categories
46from . import test_results
47from .test_results import EventBuilder
48from ..support import seven
49
50def is_exe(fpath):
51    """Returns true if fpath is an executable."""
52    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
53
54def which(program):
55    """Returns the full path to a program; None otherwise."""
56    fpath, fname = os.path.split(program)
57    if fpath:
58        if is_exe(program):
59            return program
60    else:
61        for path in os.environ["PATH"].split(os.pathsep):
62            exe_file = os.path.join(path, program)
63            if is_exe(exe_file):
64                return exe_file
65    return None
66
67class _WritelnDecorator(object):
68    """Used to decorate file-like objects with a handy 'writeln' method"""
69    def __init__(self,stream):
70        self.stream = stream
71
72    def __getattr__(self, attr):
73        if attr in ('stream', '__getstate__'):
74            raise AttributeError(attr)
75        return getattr(self.stream,attr)
76
77    def writeln(self, arg=None):
78        if arg:
79            self.write(arg)
80        self.write('\n') # text-mode streams translate to \r\n if needed
81
82#
83# Global variables:
84#
85
86# The test suite.
87suite = unittest2.TestSuite()
88
89# By default, benchmarks tests are not run.
90just_do_benchmarks_test = False
91
92dont_do_dsym_test = False
93dont_do_dwarf_test = False
94dont_do_dwo_test = False
95
96# The blacklist is optional (-b blacklistFile) and allows a central place to skip
97# testclass's and/or testclass.testmethod's.
98blacklist = None
99
100# The dictionary as a result of sourcing blacklistFile.
101blacklistConfig = {}
102
103# The list of categories we said we care about
104categoriesList = None
105# set to true if we are going to use categories for cherry-picking test cases
106useCategories = False
107# Categories we want to skip
108skipCategories = []
109# use this to track per-category failures
110failuresPerCategory = {}
111
112# The path to LLDB.framework is optional.
113lldbFrameworkPath = None
114
115# The config file is optional.
116configFile = None
117
118# Test suite repeat count.  Can be overwritten with '-# count'.
119count = 1
120
121# The dictionary as a result of sourcing configFile.
122config = {}
123# The pre_flight and post_flight functions come from reading a config file.
124pre_flight = None
125post_flight = None
126# So do the lldbtest_remote_sandbox and lldbtest_remote_shell_template variables.
127lldbtest_remote_sandbox = None
128lldbtest_remote_shell_template = None
129
130# The 'archs' and 'compilers' can be specified via either command line or configFile,
131# with the command line overriding the configFile.  The corresponding options can be
132# specified more than once. For example, "-A x86_64 -A i386" => archs=['x86_64', 'i386']
133# and "-C gcc -C clang" => compilers=['gcc', 'clang'].
134archs = None        # Must be initialized after option parsing
135compilers = None    # Must be initialized after option parsing
136
137# The arch might dictate some specific CFLAGS to be passed to the toolchain to build
138# the inferior programs.  The global variable cflags_extras provides a hook to do
139# just that.
140cflags_extras = ''
141
142# Dump the Python sys.path variable.  Use '-D' to dump sys.path.
143dumpSysPath = False
144
145# Full path of the benchmark executable, as specified by the '-e' option.
146bmExecutable = None
147# The breakpoint specification of bmExecutable, as specified by the '-x' option.
148bmBreakpointSpec = None
149# The benchmark iteration count, as specified by the '-y' option.
150bmIterationCount = -1
151
152# By default, don't exclude any directories.  Use '-X' to add one excluded directory.
153excluded = set(['.svn', '.git'])
154
155# By default, failfast is False.  Use '-F' to overwrite it.
156failfast = False
157
158# The filters (testclass.testmethod) used to admit tests into our test suite.
159filters = []
160
161# The runhooks is a list of lldb commands specifically for the debugger.
162# Use '-k' to specify a runhook.
163runHooks = []
164
165# If '-g' is specified, the filterspec is not exclusive.  If a test module does
166# not contain testclass.testmethod which matches the filterspec, the whole test
167# module is still admitted into our test suite.  fs4all flag defaults to True.
168fs4all = True
169
170# Ignore the build search path relative to this script to locate the lldb.py module.
171ignore = False
172
173# By default, we do not skip build and cleanup.  Use '-S' option to override.
174skip_build_and_cleanup = False
175
176# By default, we skip long running test case.  Use '-l' option to override.
177skip_long_running_test = True
178
179# By default, we print the build dir, lldb version, and svn info.  Use '-n' option to
180# turn it off.
181noHeaders = False
182
183# Parsable mode silences headers, and any other output this script might generate, and instead
184# prints machine-readable output similar to what clang tests produce.
185parsable = False
186
187# The regular expression pattern to match against eligible filenames as our test cases.
188regexp = None
189
190# By default, tests are executed in place and cleanups are performed afterwards.
191# Use '-r dir' option to relocate the tests and their intermediate files to a
192# different directory and to forgo any cleanups.  The directory specified must
193# not exist yet.
194rdir = None
195
196# By default, recorded session info for errored/failed test are dumped into its
197# own file under a session directory named after the timestamp of the test suite
198# run.  Use '-s session-dir-name' to specify a specific dir name.
199sdir_name = None
200
201# Set this flag if there is any session info dumped during the test run.
202sdir_has_content = False
203
204# svn_info stores the output from 'svn info lldb.base.dir'.
205svn_info = ''
206
207# svn_silent means do not try to obtain svn status
208svn_silent = True
209
210# Default verbosity is 0.
211verbose = 1
212
213# Set to True only if verbose is 0 and LLDB trace mode is off.
214progress_bar = False
215
216# By default, search from the script directory.
217# We can't use sys.path[0] to determine the script directory
218# because it doesn't work under a debugger
219testdirs = [ os.path.dirname(os.path.realpath(__file__)) ]
220
221# Separator string.
222separator = '-' * 70
223
224failed = False
225
226# LLDB Remote platform setting
227lldb_platform_name = None
228lldb_platform_url = None
229lldb_platform_working_dir = None
230
231# Parallel execution settings
232is_inferior_test_runner = False
233multiprocess_test_subdir = None
234num_threads = None
235output_on_success = False
236no_multiprocess_test_runner = False
237test_runner_name = None
238
239# Test results handling globals
240results_filename = None
241results_port = None
242results_file_object = None
243results_formatter_name = None
244results_formatter_object = None
245results_formatter_options = None
246
247# The names of all tests. Used to assert we don't have two tests with the same base name.
248all_tests = set()
249
250def usage(parser):
251    parser.print_help()
252    if verbose > 0:
253        print("""
254Examples:
255
256This is an example of using the -f option to pinpoint to a specific test class
257and test method to be run:
258
259$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
260----------------------------------------------------------------------
261Collected 1 test
262
263test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
264Test 'frame variable this' when stopped on a class constructor. ... ok
265
266----------------------------------------------------------------------
267Ran 1 test in 1.396s
268
269OK
270
271And this is an example of using the -p option to run a single file (the filename
272matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):
273
274$ ./dotest.py -v -p ObjC
275----------------------------------------------------------------------
276Collected 4 tests
277
278test_break_with_dsym (TestObjCMethods.FoundationTestCase)
279Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
280test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
281Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
282test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
283Lookup objective-c data types and evaluate expressions. ... ok
284test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
285Lookup objective-c data types and evaluate expressions. ... ok
286
287----------------------------------------------------------------------
288Ran 4 tests in 16.661s
289
290OK
291
292Running of this script also sets up the LLDB_TEST environment variable so that
293individual test cases can locate their supporting files correctly.  The script
294tries to set up Python's search paths for modules by looking at the build tree
295relative to this script.  See also the '-i' option in the following example.
296
297Finally, this is an example of using the lldb.py module distributed/installed by
298Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
299option to add some delay between two tests.  It uses ARCH=x86_64 to specify that
300as the architecture and CC=clang to specify the compiler used for the test run:
301
302$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward
303
304Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
305----------------------------------------------------------------------
306Collected 2 tests
307
308test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
309Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
310test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
311Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
312
313----------------------------------------------------------------------
314Ran 2 tests in 5.659s
315
316OK
317
318The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
319notify the directory containing the session logs for test failures or errors.
320In case there is any test failure/error, a similar message is appended at the
321end of the stderr output for your convenience.
322
323ENABLING LOGS FROM TESTS
324
325Option 1:
326
327Writing logs into different files per test case::
328
329This option is particularly useful when multiple dotest instances are created
330by dosep.py
331
332$ ./dotest.py --channel "lldb all"
333
334$ ./dotest.py --channel "lldb all" --channel "gdb-remote packets"
335
336These log files are written to:
337
338<session-dir>/<test-id>-host.log (logs from lldb host process)
339<session-dir>/<test-id>-server.log (logs from debugserver/lldb-server)
340<session-dir>/<test-id>-<test-result>.log (console logs)
341
342By default, logs from successful runs are deleted.  Use the --log-success flag
343to create reference logs for debugging.
344
345$ ./dotest.py --log-success
346
347Option 2: (DEPRECATED)
348
349The following options can only enable logs from the host lldb process.
350Only categories from the "lldb" or "gdb-remote" channels can be enabled
351They also do not automatically enable logs in locally running debug servers.
352Also, logs from all test case are written into each log file
353
354o LLDB_LOG: if defined, specifies the log file pathname for the 'lldb' subsystem
355  with a default option of 'event process' if LLDB_LOG_OPTION is not defined.
356
357o GDB_REMOTE_LOG: if defined, specifies the log file pathname for the
358  'process.gdb-remote' subsystem with a default option of 'packets' if
359  GDB_REMOTE_LOG_OPTION is not defined.
360
361""")
362    sys.exit(0)
363
364
365def setCrashInfoHook_Mac(text):
366    from . import crashinfo
367    crashinfo.setCrashReporterDescription(text)
368
369# implement this in some suitable way for your platform, and then bind it
370# to setCrashInfoHook
371def setCrashInfoHook_NonMac(text):
372    pass
373
374setCrashInfoHook = None
375
376def deleteCrashInfoDylib(dylib_path):
377    try:
378        # Need to modify this to handle multiple tests running at the same time.  If we move this
379        # to the test's real dir, all should be we run sequentially within a test directory.
380        # os.remove(dylib_path)
381        None
382    finally:
383        pass
384
385def setupCrashInfoHook():
386    global setCrashInfoHook
387    setCrashInfoHook = setCrashInfoHook_NonMac # safe default
388    if platform.system() == "Darwin":
389        from . import lock
390        test_dir = os.environ['LLDB_TEST']
391        if not test_dir or not os.path.exists(test_dir):
392            return
393        dylib_lock = os.path.join(test_dir,"crashinfo.lock")
394        dylib_src = os.path.join(test_dir,"crashinfo.c")
395        dylib_dst = os.path.join(test_dir,"crashinfo.so")
396        try:
397            compile_lock = lock.Lock(dylib_lock)
398            compile_lock.acquire()
399            if not os.path.isfile(dylib_dst) or os.path.getmtime(dylib_dst) < os.path.getmtime(dylib_src):
400                # we need to compile
401                cmd = "SDKROOT= xcrun clang %s -o %s -framework Python -Xlinker -dylib -iframework /System/Library/Frameworks/ -Xlinker -F /System/Library/Frameworks/" % (dylib_src,dylib_dst)
402                if subprocess.call(cmd,shell=True) != 0 or not os.path.isfile(dylib_dst):
403                    raise Exception('command failed: "{}"'.format(cmd))
404        finally:
405            compile_lock.release()
406            del compile_lock
407
408        setCrashInfoHook = setCrashInfoHook_Mac
409
410    else:
411        pass
412
413def shouldSkipBecauseOfCategories(test_categories):
414    global useCategories, categoriesList, skipCategories
415
416    if useCategories:
417        if len(test_categories) == 0 or len(categoriesList & set(test_categories)) == 0:
418            return True
419
420    for category in skipCategories:
421        if category in test_categories:
422            return True
423
424    return False
425
426def parseOptionsAndInitTestdirs():
427    """Initialize the list of directories containing our unittest scripts.
428
429    '-h/--help as the first option prints out usage info and exit the program.
430    """
431
432    global just_do_benchmarks_test
433    global dont_do_dsym_test
434    global dont_do_dwarf_test
435    global dont_do_dwo_test
436    global blacklist
437    global blacklistConfig
438    global categoriesList
439    global validCategories
440    global useCategories
441    global skipCategories
442    global lldbFrameworkPath
443    global configFile
444    global archs
445    global compilers
446    global count
447    global dumpSysPath
448    global bmExecutable
449    global bmBreakpointSpec
450    global bmIterationCount
451    global failfast
452    global filters
453    global fs4all
454    global ignore
455    global progress_bar
456    global runHooks
457    global skip_build_and_cleanup
458    global skip_long_running_test
459    global noHeaders
460    global parsable
461    global regexp
462    global rdir
463    global sdir_name
464    global svn_silent
465    global verbose
466    global testdirs
467    global lldb_platform_name
468    global lldb_platform_url
469    global lldb_platform_working_dir
470    global setCrashInfoHook
471    global is_inferior_test_runner
472    global multiprocess_test_subdir
473    global num_threads
474    global output_on_success
475    global no_multiprocess_test_runner
476    global test_runner_name
477    global results_filename
478    global results_formatter_name
479    global results_formatter_options
480    global results_port
481
482    do_help = False
483
484    platform_system = platform.system()
485    platform_machine = platform.machine()
486
487    parser = dotest_args.create_parser()
488    args = dotest_args.parse_args(parser, sys.argv[1:])
489
490    if args.unset_env_varnames:
491        for env_var in args.unset_env_varnames:
492            if env_var in os.environ:
493                # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
494                # is automatically translated into a corresponding call to unsetenv().
495                del os.environ[env_var]
496                #os.unsetenv(env_var)
497
498    if args.set_env_vars:
499        for env_var in args.set_env_vars:
500            parts = env_var.split('=', 1)
501            if len(parts) == 1:
502                os.environ[parts[0]] = ""
503            else:
504                os.environ[parts[0]] = parts[1]
505
506    # only print the args if being verbose (and parsable is off)
507    if args.v and not args.q:
508        print(sys.argv)
509
510    if args.h:
511        do_help = True
512
513    if args.compilers:
514        compilers = args.compilers
515    else:
516        # Use a compiler appropriate appropriate for the Apple SDK if one was specified
517        if platform_system == 'Darwin' and args.apple_sdk:
518            compilers = [seven.get_command_output('xcrun -sdk "%s" -find clang 2> /dev/null' % (args.apple_sdk))]
519        else:
520            # 'clang' on ubuntu 14.04 is 3.4 so we try clang-3.5 first
521            candidateCompilers = ['clang-3.5', 'clang', 'gcc']
522            for candidate in candidateCompilers:
523                if which(candidate):
524                    compilers = [candidate]
525                    break
526
527    if args.channels:
528        lldbtest_config.channels = args.channels
529
530    if args.log_success:
531        lldbtest_config.log_success = args.log_success
532
533    # Set SDKROOT if we are using an Apple SDK
534    if platform_system == 'Darwin' and args.apple_sdk:
535        os.environ['SDKROOT'] = seven.get_command_output('xcrun --sdk "%s" --show-sdk-path 2> /dev/null' % (args.apple_sdk))
536
537    if args.archs:
538        archs = args.archs
539        for arch in archs:
540            if arch.startswith('arm') and platform_system == 'Darwin' and not args.apple_sdk:
541                os.environ['SDKROOT'] = seven.get_command_output('xcrun --sdk iphoneos.internal --show-sdk-path 2> /dev/null')
542                if not os.path.exists(os.environ['SDKROOT']):
543                    os.environ['SDKROOT'] = seven.get_command_output('xcrun --sdk iphoneos --show-sdk-path 2> /dev/null')
544    else:
545        archs = [platform_machine]
546
547    if args.categoriesList:
548        categoriesList = set(test_categories.validate(args.categoriesList, False))
549        useCategories = True
550    else:
551        categoriesList = []
552
553    if args.skipCategories:
554        skipCategories = test_categories.validate(args.skipCategories, False)
555
556    if args.D:
557        dumpSysPath = True
558
559    if args.E:
560        cflags_extras = args.E
561        os.environ['CFLAGS_EXTRAS'] = cflags_extras
562
563    # argparse makes sure we have correct options
564    if args.N == 'dwarf':
565        dont_do_dwarf_test = True
566    elif args.N == 'dwo':
567        dont_do_dwo_test = True
568    elif args.N == 'dsym':
569        dont_do_dsym_test = True
570
571    if args.a or args.plus_a:
572        print("Options '-a' and '+a' have been deprecated. Please use the test category\n"
573              "functionality (-G pyapi, --skip-category pyapi) instead.")
574        sys.exit(1)
575
576    if args.m or args.plus_m:
577        print("Options '-m' and '+m' have been deprecated. Please use the test category\n"
578              "functionality (-G lldb-mi, --skip-category lldb-mi) instead.")
579        sys.exit(1)
580
581    if args.plus_b:
582        just_do_benchmarks_test = True
583
584    if args.b:
585        if args.b.startswith('-'):
586            usage(parser)
587        blacklistFile = args.b
588        if not os.path.isfile(blacklistFile):
589            print('Blacklist file:', blacklistFile, 'does not exist!')
590            usage(parser)
591        # Now read the blacklist contents and assign it to blacklist.
592        execfile(blacklistFile, globals(), blacklistConfig)
593        blacklist = blacklistConfig.get('blacklist')
594
595    if args.c:
596        if args.c.startswith('-'):
597            usage(parser)
598        configFile = args.c
599        if not os.path.isfile(configFile):
600            print('Config file:', configFile, 'does not exist!')
601            usage(parser)
602
603    if args.d:
604        sys.stdout.write("Suspending the process %d to wait for debugger to attach...\n" % os.getpid())
605        sys.stdout.flush()
606        os.kill(os.getpid(), signal.SIGSTOP)
607
608    if args.e:
609        if args.e.startswith('-'):
610            usage(parser)
611        bmExecutable = args.e
612        if not is_exe(bmExecutable):
613            usage(parser)
614
615    if args.F:
616        failfast = True
617
618    if args.f:
619        if any([x.startswith('-') for x in args.f]):
620            usage(parser)
621        filters.extend(args.f)
622        # Shut off multiprocessing mode when additional filters are specified.
623        # The rational is that the user is probably going after a very specific
624        # test and doesn't need a bunch of parallel test runners all looking for
625        # it in a frenzy.  Also, '-v' now spits out all test run output even
626        # on success, so the standard recipe for redoing a failing test (with -v
627        # and a -f to filter to the specific test) now causes all test scanning
628        # (in parallel) to print results for do-nothing runs in a very distracting
629        # manner.  If we really need filtered parallel runs in the future, consider
630        # adding a --no-output-on-success that prevents -v from setting
631        # output-on-success.
632        no_multiprocess_test_runner = True
633
634    if args.g:
635        fs4all = False
636
637    if args.i:
638        ignore = True
639
640    if args.k:
641        runHooks.extend(args.k)
642
643    if args.l:
644        skip_long_running_test = False
645
646    if args.framework:
647        lldbFrameworkPath = args.framework
648
649    if args.executable:
650        lldbtest_config.lldbExec = args.executable
651
652    if args.libcxx:
653        os.environ["LIBCXX_PATH"] = args.libcxx
654
655    if args.n:
656        noHeaders = True
657
658    if args.p:
659        if args.p.startswith('-'):
660            usage(parser)
661        regexp = args.p
662
663    if args.q:
664        noHeaders = True
665        parsable = True
666
667    if args.P and not args.v:
668        progress_bar = True
669        verbose = 0
670
671    if args.R:
672        if args.R.startswith('-'):
673            usage(parser)
674        rdir = os.path.abspath(args.R)
675        if os.path.exists(rdir):
676            import shutil
677            print('Removing tree:', rdir)
678            shutil.rmtree(rdir)
679
680    if args.r:
681        if args.r.startswith('-'):
682            usage(parser)
683        rdir = os.path.abspath(args.r)
684        if os.path.exists(rdir):
685            print('Relocated directory:', rdir, 'must not exist!')
686            usage(parser)
687
688    if args.S:
689        skip_build_and_cleanup = True
690
691    if args.s:
692        if args.s.startswith('-'):
693            usage(parser)
694        sdir_name = args.s
695
696    if args.t:
697        os.environ['LLDB_COMMAND_TRACE'] = 'YES'
698
699    if args.T:
700        svn_silent = False
701
702    if args.v:
703        verbose = 2
704
705    if args.w:
706        os.environ['LLDB_WAIT_BETWEEN_TEST_CASES'] = 'YES'
707
708    if args.X:
709        if args.X.startswith('-'):
710            usage(parser)
711        excluded.add(args.X)
712
713    if args.x:
714        if args.x.startswith('-'):
715            usage(parser)
716        bmBreakpointSpec = args.x
717
718    # argparse makes sure we have a number
719    if args.y:
720        bmIterationCount = args.y
721
722    # argparse makes sure we have a number
723    if args.sharp:
724        count = args.sharp
725
726    if sys.platform.startswith('win32'):
727        os.environ['LLDB_DISABLE_CRASH_DIALOG'] = str(args.disable_crash_dialog)
728        os.environ['LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE'] = str(args.hide_inferior_console)
729
730    if do_help == True:
731        usage(parser)
732
733    if args.no_multiprocess:
734        no_multiprocess_test_runner = True
735
736    if args.inferior:
737        is_inferior_test_runner = True
738
739    # Turn on output_on_sucess if either explicitly added or -v specified.
740    if args.output_on_success or args.v:
741        output_on_success = True
742
743    if args.num_threads:
744        num_threads = args.num_threads
745
746    if args.test_subdir:
747        multiprocess_test_subdir = args.test_subdir
748
749    if args.test_runner_name:
750        test_runner_name = args.test_runner_name
751
752    # Capture test results-related args.
753    if args.curses and not args.inferior:
754        # Act as if the following args were set.
755        args.results_formatter = "lldbsuite.test.curses_results.Curses"
756        args.results_file = "stdout"
757
758    if args.results_file:
759        results_filename = args.results_file
760
761    if args.results_port:
762        results_port = args.results_port
763
764    if args.results_file and args.results_port:
765        sys.stderr.write(
766            "only one of --results-file and --results-port should "
767            "be specified\n")
768        usage(args)
769
770    if args.results_formatter:
771        results_formatter_name = args.results_formatter
772    if args.results_formatter_options:
773        results_formatter_options = args.results_formatter_options
774
775    if args.lldb_platform_name:
776        lldb_platform_name = args.lldb_platform_name
777    if args.lldb_platform_url:
778        lldb_platform_url = args.lldb_platform_url
779    if args.lldb_platform_working_dir:
780        lldb_platform_working_dir = args.lldb_platform_working_dir
781
782    if args.event_add_entries and len(args.event_add_entries) > 0:
783        entries = {}
784        # Parse out key=val pairs, separated by comma
785        for keyval in args.event_add_entries.split(","):
786            key_val_entry = keyval.split("=")
787            if len(key_val_entry) == 2:
788                (key, val) = key_val_entry
789                val_parts = val.split(':')
790                if len(val_parts) > 1:
791                    (val, val_type) = val_parts
792                    if val_type == 'int':
793                        val = int(val)
794                entries[key] = val
795        # Tell the event builder to create all events with these
796        # key/val pairs in them.
797        if len(entries) > 0:
798            test_results.EventBuilder.add_entries_to_all_events(entries)
799
800    # Gather all the dirs passed on the command line.
801    if len(args.args) > 0:
802        testdirs = list(map(os.path.abspath, args.args))
803        # Shut off multiprocessing mode when test directories are specified.
804        no_multiprocess_test_runner = True
805
806    # If '-r dir' is specified, the tests should be run under the relocated
807    # directory.  Let's copy the testdirs over.
808    if rdir:
809        from shutil import copytree, ignore_patterns
810
811        tmpdirs = []
812        orig_testdirs = testdirs[:]
813        for srcdir in testdirs:
814            # For example, /Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/hello_watchpoint
815            # shall be split into ['/Volumes/data/lldb/svn/ToT/', 'functionalities/watchpoint/hello_watchpoint'].
816            # Utilize the relative path to the 'test' directory to make our destination dir path.
817            if ("test" + os.sep) in srcdir:
818                to_split_on = "test" + os.sep
819            else:
820                to_split_on = "test"
821            dstdir = os.path.join(rdir, srcdir.split(to_split_on)[1])
822            dstdir = dstdir.rstrip(os.sep)
823            # Don't copy the *.pyc and .svn stuffs.
824            copytree(srcdir, dstdir, ignore=ignore_patterns('*.pyc', '.svn'))
825            tmpdirs.append(dstdir)
826
827        # This will be our modified testdirs.
828        testdirs = tmpdirs
829
830        # With '-r dir' specified, there's no cleanup of intermediate test files.
831        os.environ["LLDB_DO_CLEANUP"] = 'NO'
832
833        # If the original testdirs is ['test'], the make directory has already been copied
834        # recursively and is contained within the rdir/test dir.  For anything
835        # else, we would need to copy over the make directory and its contents,
836        # so that, os.listdir(rdir) looks like, for example:
837        #
838        #     array_types conditional_break make
839        #
840        # where the make directory contains the Makefile.rules file.
841        if len(testdirs) != 1 or os.path.basename(orig_testdirs[0]) != 'test':
842            scriptdir = os.path.dirname(__file__)
843            # Don't copy the .svn stuffs.
844            copytree(os.path.join(scriptdir, 'make'), os.path.join(rdir, 'make'),
845                     ignore=ignore_patterns('.svn'))
846
847    #print("testdirs:", testdirs)
848
849    # Source the configFile if specified.
850    # The side effect, if any, will be felt from this point on.  An example
851    # config file may be these simple two lines:
852    #
853    # sys.stderr = open("/tmp/lldbtest-stderr", "w")
854    # sys.stdout = open("/tmp/lldbtest-stdout", "w")
855    #
856    # which will reassign the two file objects to sys.stderr and sys.stdout,
857    # respectively.
858    #
859    # See also lldb-trunk/examples/test/usage-config.
860    global config, pre_flight, post_flight, lldbtest_remote_sandbox, lldbtest_remote_shell_template
861    if configFile:
862        # Pass config (a dictionary) as the locals namespace for side-effect.
863        execfile(configFile, globals(), config)
864        #print("config:", config)
865        if "pre_flight" in config:
866            pre_flight = config["pre_flight"]
867            if not six.callable(pre_flight):
868                print("fatal error: pre_flight is not callable, exiting.")
869                sys.exit(1)
870        if "post_flight" in config:
871            post_flight = config["post_flight"]
872            if not six.callable(post_flight):
873                print("fatal error: post_flight is not callable, exiting.")
874                sys.exit(1)
875        if "lldbtest_remote_sandbox" in config:
876            lldbtest_remote_sandbox = config["lldbtest_remote_sandbox"]
877        if "lldbtest_remote_shell_template" in config:
878            lldbtest_remote_shell_template = config["lldbtest_remote_shell_template"]
879        #print("sys.stderr:", sys.stderr)
880        #print("sys.stdout:", sys.stdout)
881
882def getXcodeOutputPaths(lldbRootDirectory):
883    result = []
884
885    # These are for xcode build directories.
886    xcode3_build_dir = ['build']
887    xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
888
889    configurations = [['Debug'], ['DebugClang'], ['Release'], ['BuildAndIntegration']]
890    xcode_build_dirs = [xcode3_build_dir, xcode4_build_dir]
891    for configuration in configurations:
892        for xcode_build_dir in xcode_build_dirs:
893            outputPath = os.path.join(lldbRootDirectory, *(xcode_build_dir+configuration) )
894            result.append(outputPath)
895
896    return result
897
898
899def createSocketToLocalPort(port):
900    def socket_closer(s):
901        """Close down an opened socket properly."""
902        s.shutdown(socket.SHUT_RDWR)
903        s.close()
904
905    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
906    sock.connect(("localhost", port))
907    return (sock, lambda: socket_closer(sock))
908
909
910def setupTestResults():
911    """Sets up test results-related objects based on arg settings."""
912    global results_filename
913    global results_file_object
914    global results_formatter_name
915    global results_formatter_object
916    global results_formatter_options
917    global results_port
918
919    default_formatter_name = None
920    cleanup_func = None
921
922    if results_filename:
923        # Open the results file for writing.
924        if results_filename == 'stdout':
925            results_file_object = sys.stdout
926            cleanup_func = None
927        elif results_filename == 'stderr':
928            results_file_object = sys.stderr
929            cleanup_func = None
930        else:
931            results_file_object = open(results_filename, "w")
932            cleanup_func = results_file_object.close
933        default_formatter_name = "lldbsuite.test.test_results.XunitFormatter"
934    elif results_port:
935        # Connect to the specified localhost port.
936        results_file_object, cleanup_func = createSocketToLocalPort(
937            results_port)
938        default_formatter_name = "lldbsuite.test.test_results.RawPickledFormatter"
939
940    if results_file_object:
941        # We care about the formatter.  Choose user-specified or, if
942        # none specified, use the default for the output type.
943        if results_formatter_name:
944            formatter_name = results_formatter_name
945        else:
946            formatter_name = default_formatter_name
947
948        # Create an instance of the class.  First figure out the package/module.
949        components = formatter_name.split(".")
950        module = importlib.import_module(".".join(components[:-1]))
951
952        # Create the class name we need to load.
953        clazz = getattr(module, components[-1])
954
955        # Handle formatter options for the results formatter class.
956        formatter_arg_parser = clazz.arg_parser()
957        if results_formatter_options and len(results_formatter_options) > 0:
958            command_line_options = results_formatter_options
959        else:
960            command_line_options = []
961
962        formatter_options = formatter_arg_parser.parse_args(
963            command_line_options)
964
965        # Create the TestResultsFormatter given the processed options.
966        results_formatter_object = clazz(results_file_object, formatter_options)
967
968        # Start the results formatter session - we'll only have one
969        # during a given dotest process invocation.
970        initialize_event = EventBuilder.bare_event("initialize")
971        if isMultiprocessTestRunner():
972            if test_runner_name is not None and test_runner_name == "serial":
973                # Only one worker queue here.
974                worker_count = 1
975            else:
976                # Workers will be the number of threads specified.
977                worker_count = num_threads
978        else:
979            worker_count = 1
980        initialize_event["worker_count"] = worker_count
981
982        results_formatter_object.handle_event(initialize_event)
983
984        def shutdown_formatter():
985            # Tell the formatter to write out anything it may have
986            # been saving until the very end (e.g. xUnit results
987            # can't complete its output until this point).
988            results_formatter_object.send_terminate_as_needed()
989
990            # And now close out the output file-like object.
991            if cleanup_func is not None:
992                cleanup_func()
993
994        atexit.register(shutdown_formatter)
995
996
997def getOutputPaths(lldbRootDirectory):
998    """
999    Returns typical build output paths for the lldb executable
1000
1001    lldbDirectory - path to the root of the lldb svn/git repo
1002    """
1003    result = []
1004
1005    if sys.platform == 'darwin':
1006        result.extend(getXcodeOutputPaths(lldbRootDirectory))
1007
1008    # cmake builds?  look for build or build/host folder next to llvm directory
1009    # lldb is located in llvm/tools/lldb so we need to go up three levels
1010    llvmParentDir = os.path.abspath(os.path.join(lldbRootDirectory, os.pardir, os.pardir, os.pardir))
1011    result.append(os.path.join(llvmParentDir, 'build', 'bin'))
1012    result.append(os.path.join(llvmParentDir, 'build', 'host', 'bin'))
1013
1014    # some cmake developers keep their build directory beside their lldb directory
1015    lldbParentDir = os.path.abspath(os.path.join(lldbRootDirectory, os.pardir))
1016    result.append(os.path.join(lldbParentDir, 'build', 'bin'))
1017    result.append(os.path.join(lldbParentDir, 'build', 'host', 'bin'))
1018
1019    return result
1020
1021def setupSysPath():
1022    """
1023    Add LLDB.framework/Resources/Python to the search paths for modules.
1024    As a side effect, we also discover the 'lldb' executable and export it here.
1025    """
1026
1027    global rdir
1028    global testdirs
1029    global dumpSysPath
1030    global noHeaders
1031    global svn_info
1032    global svn_silent
1033    global lldbFrameworkPath
1034
1035    # Get the directory containing the current script.
1036    if "DOTEST_PROFILE" in os.environ and "DOTEST_SCRIPT_DIR" in os.environ:
1037        scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
1038    else:
1039        scriptPath = os.path.dirname(os.path.realpath(__file__))
1040    if not scriptPath.endswith('test'):
1041        print("This script expects to reside in lldb's test directory.")
1042        sys.exit(-1)
1043
1044    if rdir:
1045        # Set up the LLDB_TEST environment variable appropriately, so that the
1046        # individual tests can be located relatively.
1047        #
1048        # See also lldbtest.TestBase.setUpClass(cls).
1049        if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
1050            os.environ["LLDB_TEST"] = os.path.join(rdir, 'test')
1051        else:
1052            os.environ["LLDB_TEST"] = rdir
1053    else:
1054        os.environ["LLDB_TEST"] = scriptPath
1055
1056    # Set up the LLDB_SRC environment variable, so that the tests can locate
1057    # the LLDB source code.
1058    os.environ["LLDB_SRC"] = lldbsuite.lldb_root
1059
1060    pluginPath = os.path.join(scriptPath, 'plugins')
1061    toolsLLDBMIPath = os.path.join(scriptPath, 'tools', 'lldb-mi')
1062    toolsLLDBServerPath = os.path.join(scriptPath, 'tools', 'lldb-server')
1063
1064    # Insert script dir, plugin dir, lldb-mi dir and lldb-server dir to the sys.path.
1065    sys.path.insert(0, pluginPath)
1066    sys.path.insert(0, toolsLLDBMIPath)      # Adding test/tools/lldb-mi to the path makes it easy
1067                                             # to "import lldbmi_testcase" from the MI tests
1068    sys.path.insert(0, toolsLLDBServerPath)  # Adding test/tools/lldb-server to the path makes it easy
1069                                             # to "import lldbgdbserverutils" from the lldb-server tests
1070
1071    # This is the root of the lldb git/svn checkout
1072    # When this changes over to a package instead of a standalone script, this
1073    # will be `lldbsuite.lldb_root`
1074    lldbRootDirectory = lldbsuite.lldb_root
1075
1076    # Some of the tests can invoke the 'lldb' command directly.
1077    # We'll try to locate the appropriate executable right here.
1078
1079    # The lldb executable can be set from the command line
1080    # if it's not set, we try to find it now
1081    # first, we try the environment
1082    if not lldbtest_config.lldbExec:
1083        # First, you can define an environment variable LLDB_EXEC specifying the
1084        # full pathname of the lldb executable.
1085        if "LLDB_EXEC" in os.environ:
1086            lldbtest_config.lldbExec = os.environ["LLDB_EXEC"]
1087
1088    if not lldbtest_config.lldbExec:
1089        outputPaths = getOutputPaths(lldbRootDirectory)
1090        for outputPath in outputPaths:
1091            candidatePath = os.path.join(outputPath, 'lldb')
1092            if is_exe(candidatePath):
1093                lldbtest_config.lldbExec = candidatePath
1094                break
1095
1096    if not lldbtest_config.lldbExec:
1097        # Last, check the path
1098        lldbtest_config.lldbExec = which('lldb')
1099
1100    if lldbtest_config.lldbExec and not is_exe(lldbtest_config.lldbExec):
1101        print("'{}' is not a path to a valid executable".format(lldbtest_config.lldbExec))
1102        lldbtest_config.lldbExec = None
1103
1104    if not lldbtest_config.lldbExec:
1105        print("The 'lldb' executable cannot be located.  Some of the tests may not be run as a result.")
1106        sys.exit(-1)
1107
1108    lldbLibDir = os.path.dirname(lldbtest_config.lldbExec)  # confusingly, this is the "bin" directory
1109    os.environ["LLDB_LIB_DIR"] = lldbLibDir
1110    lldbImpLibDir = os.path.join(lldbLibDir, '..', 'lib') if sys.platform.startswith('win32') else lldbLibDir
1111    os.environ["LLDB_IMPLIB_DIR"] = lldbImpLibDir
1112    if not noHeaders:
1113        print("LLDB library dir:", os.environ["LLDB_LIB_DIR"])
1114        print("LLDB import library dir:", os.environ["LLDB_IMPLIB_DIR"])
1115        os.system('%s -v' % lldbtest_config.lldbExec)
1116
1117    # Assume lldb-mi is in same place as lldb
1118    # If not found, disable the lldb-mi tests
1119    lldbMiExec = None
1120    if lldbtest_config.lldbExec and is_exe(lldbtest_config.lldbExec + "-mi"):
1121        lldbMiExec = lldbtest_config.lldbExec + "-mi"
1122    if not lldbMiExec:
1123        if not shouldSkipBecauseOfCategories(["lldb-mi"]):
1124            print("The 'lldb-mi' executable cannot be located.  The lldb-mi tests can not be run as a result.")
1125            skipCategories.append("lldb-mi")
1126    else:
1127        os.environ["LLDBMI_EXEC"] = lldbMiExec
1128
1129    # Skip printing svn/git information when running in parsable (lit-test compatibility) mode
1130    if not svn_silent and not parsable:
1131        if os.path.isdir(os.path.join(lldbRootDirectory, '.svn')) and which("svn") is not None:
1132            pipe = subprocess.Popen([which("svn"), "info", lldbRootDirectory], stdout = subprocess.PIPE)
1133            svn_info = pipe.stdout.read()
1134        elif os.path.isdir(os.path.join(lldbRootDirectory, '.git')) and which("git") is not None:
1135            pipe = subprocess.Popen([which("git"), "svn", "info", lldbRootDirectory], stdout = subprocess.PIPE)
1136            svn_info = pipe.stdout.read()
1137        if not noHeaders:
1138            print(svn_info)
1139
1140    global ignore
1141
1142    lldbPythonDir = None # The directory that contains 'lldb/__init__.py'
1143    if lldbFrameworkPath:
1144        candidatePath = os.path.join(lldbFrameworkPath, 'Resources', 'Python')
1145        if os.path.isfile(os.path.join(candidatePath, 'lldb/__init__.py')):
1146            lldbPythonDir = candidatePath
1147        if not lldbPythonDir:
1148            print('Resources/Python/lldb/__init__.py was not found in ' + lldbFrameworkPath)
1149            sys.exit(-1)
1150    else:
1151        # The '-i' option is used to skip looking for lldb.py in the build tree.
1152        if ignore:
1153            return
1154
1155        # If our lldb supports the -P option, use it to find the python path:
1156        init_in_python_dir = os.path.join('lldb', '__init__.py')
1157
1158        lldb_dash_p_result = subprocess.check_output([lldbtest_config.lldbExec, "-P"], stderr=subprocess.STDOUT, universal_newlines=True)
1159
1160        if lldb_dash_p_result and not lldb_dash_p_result.startswith(("<", "lldb: invalid option:")) \
1161							  and not lldb_dash_p_result.startswith("Traceback"):
1162            lines = lldb_dash_p_result.splitlines()
1163
1164            # Workaround for readline vs libedit issue on FreeBSD.  If stdout
1165            # is not a terminal Python executes
1166            #     rl_variable_bind ("enable-meta-key", "off");
1167            # This produces a warning with FreeBSD's libedit because the
1168            # enable-meta-key variable is unknown.  Not an issue on Apple
1169            # because cpython commit f0ab6f9f0603 added a #ifndef __APPLE__
1170            # around the call.  See http://bugs.python.org/issue19884 for more
1171            # information.  For now we just discard the warning output.
1172            if len(lines) >= 1 and lines[0].startswith("bind: Invalid command"):
1173                lines.pop(0)
1174
1175            # Taking the last line because lldb outputs
1176            # 'Cannot read termcap database;\nusing dumb terminal settings.\n'
1177            # before the path
1178            if len(lines) >= 1 and os.path.isfile(os.path.join(lines[-1], init_in_python_dir)):
1179                lldbPythonDir = lines[-1]
1180                if "freebsd" in sys.platform or "linux" in sys.platform:
1181                    os.environ['LLDB_LIB_DIR'] = os.path.join(lldbPythonDir, '..', '..')
1182
1183        if not lldbPythonDir:
1184            if platform.system() == "Darwin":
1185                python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
1186                outputPaths = getXcodeOutputPaths()
1187                for outputPath in outputPaths:
1188                    candidatePath = os.path.join(outputPath, python_resource_dir)
1189                    if os.path.isfile(os.path.join(candidatePath, init_in_python_dir)):
1190                        lldbPythonDir = candidatePath
1191                        break
1192
1193                if not lldbPythonDir:
1194                    print('This script requires lldb.py to be in either ' + dbgPath + ',', end=' ')
1195                    print(relPath + ', or ' + baiPath + '. Some tests might fail.')
1196            else:
1197                print("Unable to load lldb extension module.  Possible reasons for this include:")
1198                print("  1) LLDB was built with LLDB_DISABLE_PYTHON=1")
1199                print("  2) PYTHONPATH and PYTHONHOME are not set correctly.  PYTHONHOME should refer to")
1200                print("     the version of Python that LLDB built and linked against, and PYTHONPATH")
1201                print("     should contain the Lib directory for the same python distro, as well as the")
1202                print("     location of LLDB\'s site-packages folder.")
1203                print("  3) A different version of Python than that which was built against is exported in")
1204                print("     the system\'s PATH environment variable, causing conflicts.")
1205                print("  4) The executable '%s' could not be found.  Please check " % lldbExecutable)
1206                print("     that it exists and is executable.")
1207
1208    if lldbPythonDir:
1209        lldbPythonDir = os.path.normpath(lldbPythonDir)
1210        # Some of the code that uses this path assumes it hasn't resolved the Versions... link.
1211        # If the path we've constructed looks like that, then we'll strip out the Versions/A part.
1212        (before, frameWithVersion, after) = lldbPythonDir.rpartition("LLDB.framework/Versions/A")
1213        if frameWithVersion != "" :
1214            lldbPythonDir = before + "LLDB.framework" + after
1215
1216        lldbPythonDir = os.path.abspath(lldbPythonDir)
1217
1218        # If tests need to find LLDB_FRAMEWORK, now they can do it
1219        os.environ["LLDB_FRAMEWORK"] = os.path.dirname(os.path.dirname(lldbPythonDir))
1220
1221        # This is to locate the lldb.py module.  Insert it right after sys.path[0].
1222        sys.path[1:1] = [lldbPythonDir]
1223        if dumpSysPath:
1224            print("sys.path:", sys.path)
1225
1226def visit(prefix, dir, names):
1227    """Visitor function for os.path.walk(path, visit, arg)."""
1228
1229    global suite
1230    global regexp
1231    global filters
1232    global fs4all
1233    global excluded
1234    global all_tests
1235
1236    if set(dir.split(os.sep)).intersection(excluded):
1237        #print("Detected an excluded dir component: %s" % dir)
1238        return
1239
1240    for name in names:
1241        if '.py' == os.path.splitext(name)[1] and name.startswith(prefix):
1242
1243            if name in all_tests:
1244                raise Exception("Found multiple tests with the name %s" % name)
1245            all_tests.add(name)
1246
1247            # Try to match the regexp pattern, if specified.
1248            if regexp:
1249                import re
1250                if re.search(regexp, name):
1251                    #print("Filename: '%s' matches pattern: '%s'" % (name, regexp))
1252                    pass
1253                else:
1254                    #print("Filename: '%s' does not match pattern: '%s'" % (name, regexp))
1255                    continue
1256
1257            # We found a match for our test.  Add it to the suite.
1258
1259            # Update the sys.path first.
1260            if not sys.path.count(dir):
1261                sys.path.insert(0, dir)
1262            base = os.path.splitext(name)[0]
1263
1264            # Thoroughly check the filterspec against the base module and admit
1265            # the (base, filterspec) combination only when it makes sense.
1266            filterspec = None
1267            for filterspec in filters:
1268                # Optimistically set the flag to True.
1269                filtered = True
1270                module = __import__(base)
1271                parts = filterspec.split('.')
1272                obj = module
1273                for part in parts:
1274                    try:
1275                        parent, obj = obj, getattr(obj, part)
1276                    except AttributeError:
1277                        # The filterspec has failed.
1278                        filtered = False
1279                        break
1280
1281                # If filtered, we have a good filterspec.  Add it.
1282                if filtered:
1283                    #print("adding filter spec %s to module %s" % (filterspec, module))
1284                    suite.addTests(
1285                        unittest2.defaultTestLoader.loadTestsFromName(filterspec, module))
1286                    continue
1287
1288            # Forgo this module if the (base, filterspec) combo is invalid
1289            # and no '-g' option is specified
1290            if filters and fs4all and not filtered:
1291                continue
1292
1293            # Add either the filtered test case(s) (which is done before) or the entire test class.
1294            if not filterspec or not filtered:
1295                # A simple case of just the module name.  Also the failover case
1296                # from the filterspec branch when the (base, filterspec) combo
1297                # doesn't make sense.
1298                suite.addTests(unittest2.defaultTestLoader.loadTestsFromName(base))
1299
1300
1301def disabledynamics():
1302    import lldb
1303    ci = lldb.DBG.GetCommandInterpreter()
1304    res = lldb.SBCommandReturnObject()
1305    ci.HandleCommand("setting set target.prefer-dynamic-value no-dynamic-values", res, False)
1306    if not res.Succeeded():
1307        raise Exception('disabling dynamic type support failed')
1308
1309def lldbLoggings():
1310    import lldb
1311    """Check and do lldb loggings if necessary."""
1312
1313    # Turn on logging for debugging purposes if ${LLDB_LOG} environment variable is
1314    # defined.  Use ${LLDB_LOG} to specify the log file.
1315    ci = lldb.DBG.GetCommandInterpreter()
1316    res = lldb.SBCommandReturnObject()
1317    if ("LLDB_LOG" in os.environ):
1318        open(os.environ["LLDB_LOG"], 'w').close()
1319        if ("LLDB_LOG_OPTION" in os.environ):
1320            lldb_log_option = os.environ["LLDB_LOG_OPTION"]
1321        else:
1322            lldb_log_option = "event process expr state api"
1323        ci.HandleCommand(
1324            "log enable -n -f " + os.environ["LLDB_LOG"] + " lldb " + lldb_log_option,
1325            res)
1326        if not res.Succeeded():
1327            raise Exception('log enable failed (check LLDB_LOG env variable)')
1328
1329    if ("LLDB_LINUX_LOG" in os.environ):
1330        open(os.environ["LLDB_LINUX_LOG"], 'w').close()
1331        if ("LLDB_LINUX_LOG_OPTION" in os.environ):
1332            lldb_log_option = os.environ["LLDB_LINUX_LOG_OPTION"]
1333        else:
1334            lldb_log_option = "event process expr state api"
1335        ci.HandleCommand(
1336            "log enable -n -f " + os.environ["LLDB_LINUX_LOG"] + " linux " + lldb_log_option,
1337            res)
1338        if not res.Succeeded():
1339            raise Exception('log enable failed (check LLDB_LINUX_LOG env variable)')
1340
1341    # Ditto for gdb-remote logging if ${GDB_REMOTE_LOG} environment variable is defined.
1342    # Use ${GDB_REMOTE_LOG} to specify the log file.
1343    if ("GDB_REMOTE_LOG" in os.environ):
1344        if ("GDB_REMOTE_LOG_OPTION" in os.environ):
1345            gdb_remote_log_option = os.environ["GDB_REMOTE_LOG_OPTION"]
1346        else:
1347            gdb_remote_log_option = "packets process"
1348        ci.HandleCommand(
1349            "log enable -n -f " + os.environ["GDB_REMOTE_LOG"] + " gdb-remote "
1350            + gdb_remote_log_option,
1351            res)
1352        if not res.Succeeded():
1353            raise Exception('log enable failed (check GDB_REMOTE_LOG env variable)')
1354
1355def getMyCommandLine():
1356    return ' '.join(sys.argv)
1357
1358# ======================================== #
1359#                                          #
1360# Execution of the test driver starts here #
1361#                                          #
1362# ======================================== #
1363
1364def checkDsymForUUIDIsNotOn():
1365    cmd = ["defaults", "read", "com.apple.DebugSymbols"]
1366    pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1367    cmd_output = pipe.stdout.read()
1368    if cmd_output and "DBGFileMappedPaths = " in cmd_output:
1369        print("%s =>" % ' '.join(cmd))
1370        print(cmd_output)
1371        print("Disable automatic lookup and caching of dSYMs before running the test suite!")
1372        print("Exiting...")
1373        sys.exit(0)
1374
1375def exitTestSuite(exitCode = None):
1376    import lldb
1377    lldb.SBDebugger.Terminate()
1378    if exitCode:
1379        sys.exit(exitCode)
1380
1381
1382def isMultiprocessTestRunner():
1383    # We're not multiprocess when we're either explicitly
1384    # the inferior (as specified by the multiprocess test
1385    # runner) OR we've been told to skip using the multiprocess
1386    # test runner
1387    return not (is_inferior_test_runner or no_multiprocess_test_runner)
1388
1389def getVersionForSDK(sdk):
1390    sdk = str.lower(sdk)
1391    full_path = seven.get_command_output('xcrun -sdk %s --show-sdk-path' % sdk)
1392    basename = os.path.basename(full_path)
1393    basename = os.path.splitext(basename)[0]
1394    basename = str.lower(basename)
1395    ver = basename.replace(sdk, '')
1396    return ver
1397
1398def getPathForSDK(sdk):
1399    sdk = str.lower(sdk)
1400    full_path = seven.get_command_output('xcrun -sdk %s --show-sdk-path' % sdk)
1401    if os.path.exists(full_path): return full_path
1402    return None
1403
1404def setDefaultTripleForPlatform():
1405    if lldb_platform_name == 'ios-simulator':
1406        triple_str = 'x86_64-apple-ios%s' % (getVersionForSDK('iphonesimulator'))
1407        os.environ['TRIPLE'] = triple_str
1408        return {'TRIPLE':triple_str}
1409    return {}
1410
1411def run_suite():
1412    global just_do_benchmarks_test
1413    global dont_do_dsym_test
1414    global dont_do_dwarf_test
1415    global dont_do_dwo_test
1416    global blacklist
1417    global blacklistConfig
1418    global categoriesList
1419    global validCategories
1420    global useCategories
1421    global skipCategories
1422    global lldbFrameworkPath
1423    global configFile
1424    global archs
1425    global compilers
1426    global count
1427    global dumpSysPath
1428    global bmExecutable
1429    global bmBreakpointSpec
1430    global bmIterationCount
1431    global failed
1432    global failfast
1433    global filters
1434    global fs4all
1435    global ignore
1436    global progress_bar
1437    global runHooks
1438    global skip_build_and_cleanup
1439    global skip_long_running_test
1440    global noHeaders
1441    global parsable
1442    global regexp
1443    global rdir
1444    global sdir_name
1445    global svn_silent
1446    global verbose
1447    global testdirs
1448    global lldb_platform_name
1449    global lldb_platform_url
1450    global lldb_platform_working_dir
1451    global setCrashInfoHook
1452    global is_inferior_test_runner
1453    global multiprocess_test_subdir
1454    global num_threads
1455    global output_on_success
1456    global no_multiprocess_test_runner
1457    global test_runner_name
1458    global results_filename
1459    global results_formatter_name
1460    global results_formatter_options
1461    global results_port
1462
1463    # On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
1464    # does not exist before proceeding to running the test suite.
1465    if sys.platform.startswith("darwin"):
1466        checkDsymForUUIDIsNotOn()
1467
1468    #
1469    # Start the actions by first parsing the options while setting up the test
1470    # directories, followed by setting up the search paths for lldb utilities;
1471    # then, we walk the directory trees and collect the tests into our test suite.
1472    #
1473    parseOptionsAndInitTestdirs()
1474
1475    # Setup test results (test results formatter and output handling).
1476    setupTestResults()
1477
1478    # If we are running as the multiprocess test runner, kick off the
1479    # multiprocess test runner here.
1480    if isMultiprocessTestRunner():
1481        from . import dosep
1482        dosep.main(output_on_success, num_threads, multiprocess_test_subdir,
1483                   test_runner_name, results_formatter_object)
1484        raise Exception("should never get here")
1485    elif is_inferior_test_runner:
1486        # Shut off Ctrl-C processing in inferiors.  The parallel
1487        # test runner handles this more holistically.
1488        signal.signal(signal.SIGINT, signal.SIG_IGN)
1489
1490    setupSysPath()
1491    setupCrashInfoHook()
1492
1493    #
1494    # If '-l' is specified, do not skip the long running tests.
1495    if not skip_long_running_test:
1496        os.environ["LLDB_SKIP_LONG_RUNNING_TEST"] = "NO"
1497
1498    # For the time being, let's bracket the test runner within the
1499    # lldb.SBDebugger.Initialize()/Terminate() pair.
1500    import lldb
1501
1502    # Create a singleton SBDebugger in the lldb namespace.
1503    lldb.DBG = lldb.SBDebugger.Create()
1504
1505    if lldb_platform_name:
1506        print("Setting up remote platform '%s'" % (lldb_platform_name))
1507        lldb.remote_platform = lldb.SBPlatform(lldb_platform_name)
1508        lldb.remote_platform_name = lldb_platform_name
1509        if not lldb.remote_platform.IsValid():
1510            print("error: unable to create the LLDB platform named '%s'." % (lldb_platform_name))
1511            exitTestSuite(1)
1512        if lldb_platform_url:
1513            # We must connect to a remote platform if a LLDB platform URL was specified
1514            print("Connecting to remote platform '%s' at '%s'..." % (lldb_platform_name, lldb_platform_url))
1515            lldb.platform_url = lldb_platform_url
1516            platform_connect_options = lldb.SBPlatformConnectOptions(lldb_platform_url)
1517            err = lldb.remote_platform.ConnectRemote(platform_connect_options)
1518            if err.Success():
1519                print("Connected.")
1520            else:
1521                print("error: failed to connect to remote platform using URL '%s': %s" % (lldb_platform_url, err))
1522                exitTestSuite(1)
1523        else:
1524            lldb.platform_url = None
1525
1526    platform_changes = setDefaultTripleForPlatform()
1527    first = True
1528    for key in platform_changes:
1529        if first:
1530            print("Environment variables setup for platform support:")
1531            first = False
1532        print("%s = %s" % (key,platform_changes[key]))
1533
1534    if lldb_platform_working_dir:
1535        print("Setting remote platform working directory to '%s'..." % (lldb_platform_working_dir))
1536        lldb.remote_platform.SetWorkingDirectory(lldb_platform_working_dir)
1537        lldb.remote_platform_working_dir = lldb_platform_working_dir
1538        lldb.DBG.SetSelectedPlatform(lldb.remote_platform)
1539    else:
1540        lldb.remote_platform = None
1541        lldb.remote_platform_working_dir = None
1542        lldb.platform_url = None
1543
1544    target_platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
1545
1546    # By default, both dsym, dwarf and dwo tests are performed.
1547    # Use @dsym_test, @dwarf_test or @dwo_test decorators, defined in lldbtest.py, to mark a test as
1548    # a dsym, dwarf or dwo test.  Use '-N dsym', '-N dwarf' or '-N dwo' to exclude dsym, dwarf or
1549    # dwo tests from running.
1550    dont_do_dsym_test = dont_do_dsym_test or any(platform in target_platform for platform in ["linux", "freebsd", "windows"])
1551    dont_do_dwo_test = dont_do_dwo_test or any(platform in target_platform for platform in ["darwin", "macosx", "ios"])
1552
1553    # Don't do debugserver tests on everything except OS X.
1554    dont_do_debugserver_test = "linux" in target_platform or "freebsd" in target_platform or "windows" in target_platform
1555
1556    # Don't do lldb-server (llgs) tests on anything except Linux.
1557    dont_do_llgs_test = not ("linux" in target_platform)
1558
1559    #
1560    # Walk through the testdirs while collecting tests.
1561    #
1562    for testdir in testdirs:
1563        for (dirpath, dirnames, filenames) in os.walk(testdir):
1564            visit('Test', dirpath, filenames)
1565
1566    #
1567    # Now that we have loaded all the test cases, run the whole test suite.
1568    #
1569
1570    # Put the blacklist in the lldb namespace, to be used by lldb.TestBase.
1571    lldb.blacklist = blacklist
1572
1573    # The pre_flight and post_flight come from reading a config file.
1574    lldb.pre_flight = pre_flight
1575    lldb.post_flight = post_flight
1576    def getsource_if_available(obj):
1577        """
1578        Return the text of the source code for an object if available.  Otherwise,
1579        a print representation is returned.
1580        """
1581        import inspect
1582        try:
1583            return inspect.getsource(obj)
1584        except:
1585            return repr(obj)
1586
1587    if not noHeaders:
1588        print("lldb.pre_flight:", getsource_if_available(lldb.pre_flight))
1589        print("lldb.post_flight:", getsource_if_available(lldb.post_flight))
1590
1591    # If either pre_flight or post_flight is defined, set lldb.test_remote to True.
1592    if lldb.pre_flight or lldb.post_flight:
1593        lldb.test_remote = True
1594    else:
1595        lldb.test_remote = False
1596
1597    # So do the lldbtest_remote_sandbox and lldbtest_remote_shell_template variables.
1598    lldb.lldbtest_remote_sandbox = lldbtest_remote_sandbox
1599    lldb.lldbtest_remote_sandboxed_executable = None
1600    lldb.lldbtest_remote_shell_template = lldbtest_remote_shell_template
1601
1602    # Put all these test decorators in the lldb namespace.
1603    lldb.just_do_benchmarks_test = just_do_benchmarks_test
1604    lldb.dont_do_dsym_test = dont_do_dsym_test
1605    lldb.dont_do_dwarf_test = dont_do_dwarf_test
1606    lldb.dont_do_dwo_test = dont_do_dwo_test
1607    lldb.dont_do_debugserver_test = dont_do_debugserver_test
1608    lldb.dont_do_llgs_test = dont_do_llgs_test
1609
1610    # Do we need to skip build and cleanup?
1611    lldb.skip_build_and_cleanup = skip_build_and_cleanup
1612
1613    # Put bmExecutable, bmBreakpointSpec, and bmIterationCount into the lldb namespace, too.
1614    lldb.bmExecutable = bmExecutable
1615    lldb.bmBreakpointSpec = bmBreakpointSpec
1616    lldb.bmIterationCount = bmIterationCount
1617
1618    # And don't forget the runHooks!
1619    lldb.runHooks = runHooks
1620
1621    # Turn on lldb loggings if necessary.
1622    lldbLoggings()
1623
1624    # Disable default dynamic types for testing purposes
1625    disabledynamics()
1626
1627    # Install the control-c handler.
1628    unittest2.signals.installHandler()
1629
1630    # If sdir_name is not specified through the '-s sdir_name' option, get a
1631    # timestamp string and export it as LLDB_SESSION_DIR environment var.  This will
1632    # be used when/if we want to dump the session info of individual test cases
1633    # later on.
1634    #
1635    # See also TestBase.dumpSessionInfo() in lldbtest.py.
1636    import datetime
1637    # The windows platforms don't like ':' in the pathname.
1638    timestamp_started = datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S")
1639    if not sdir_name:
1640        sdir_name = timestamp_started
1641    os.environ["LLDB_SESSION_DIRNAME"] = os.path.join(os.getcwd(), sdir_name)
1642
1643    if not noHeaders:
1644        sys.stderr.write("\nSession logs for test failures/errors/unexpected successes"
1645                         " will go into directory '%s'\n" % sdir_name)
1646        sys.stderr.write("Command invoked: %s\n" % getMyCommandLine())
1647
1648    if not os.path.isdir(sdir_name):
1649        try:
1650            os.mkdir(sdir_name)
1651        except OSError as exception:
1652            if exception.errno != errno.EEXIST:
1653                raise
1654    where_to_save_session = os.getcwd()
1655    fname = os.path.join(sdir_name, "TestStarted-%d" % os.getpid())
1656    with open(fname, "w") as f:
1657        print("Test started at: %s\n" % timestamp_started, file=f)
1658        print(svn_info, file=f)
1659        print("Command invoked: %s\n" % getMyCommandLine(), file=f)
1660
1661    #
1662    # Invoke the default TextTestRunner to run the test suite, possibly iterating
1663    # over different configurations.
1664    #
1665
1666    iterArchs = False
1667    iterCompilers = False
1668
1669    if not archs and "archs" in config:
1670        archs = config["archs"]
1671
1672    if isinstance(archs, list) and len(archs) >= 1:
1673        iterArchs = True
1674
1675    if not compilers and "compilers" in config:
1676        compilers = config["compilers"]
1677
1678    #
1679    # Add some intervention here to sanity check that the compilers requested are sane.
1680    # If found not to be an executable program, the invalid one is dropped from the list.
1681    for i in range(len(compilers)):
1682        c = compilers[i]
1683        if which(c):
1684            continue
1685        else:
1686            if sys.platform.startswith("darwin"):
1687                pipe = subprocess.Popen(['xcrun', '-find', c], stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
1688                cmd_output = pipe.stdout.read()
1689                if cmd_output:
1690                    if "not found" in cmd_output:
1691                        print("dropping %s from the compilers used" % c)
1692                        compilers.remove(i)
1693                    else:
1694                        compilers[i] = cmd_output.split('\n')[0]
1695                        print("'xcrun -find %s' returning %s" % (c, compilers[i]))
1696
1697    if not parsable:
1698        print("compilers=%s" % str(compilers))
1699
1700    if not compilers or len(compilers) == 0:
1701        print("No eligible compiler found, exiting.")
1702        exitTestSuite(1)
1703
1704    if isinstance(compilers, list) and len(compilers) >= 1:
1705        iterCompilers = True
1706
1707    # Make a shallow copy of sys.path, we need to manipulate the search paths later.
1708    # This is only necessary if we are relocated and with different configurations.
1709    if rdir:
1710        old_sys_path = sys.path[:]
1711    # If we iterate on archs or compilers, there is a chance we want to split stderr/stdout.
1712    if iterArchs or iterCompilers:
1713        old_stderr = sys.stderr
1714        old_stdout = sys.stdout
1715        new_stderr = None
1716        new_stdout = None
1717
1718    # Iterating over all possible architecture and compiler combinations.
1719    for ia in range(len(archs) if iterArchs else 1):
1720        archConfig = ""
1721        if iterArchs:
1722            os.environ["ARCH"] = archs[ia]
1723            archConfig = "arch=%s" % archs[ia]
1724        for ic in range(len(compilers) if iterCompilers else 1):
1725            if iterCompilers:
1726                os.environ["CC"] = compilers[ic]
1727                configString = "%s compiler=%s" % (archConfig, compilers[ic])
1728            else:
1729                configString = archConfig
1730
1731            if iterArchs or iterCompilers:
1732                # Translate ' ' to '-' for pathname component.
1733                if six.PY2:
1734                    import string
1735                    tbl = string.maketrans(' ', '-')
1736                else:
1737                    tbl = str.maketrans(' ', '-')
1738                configPostfix = configString.translate(tbl)
1739
1740                # Check whether we need to split stderr/stdout into configuration
1741                # specific files.
1742                if old_stderr.name != '<stderr>' and config.get('split_stderr'):
1743                    if new_stderr:
1744                        new_stderr.close()
1745                    new_stderr = open("%s.%s" % (old_stderr.name, configPostfix), "w")
1746                    sys.stderr = new_stderr
1747                if old_stdout.name != '<stdout>' and config.get('split_stdout'):
1748                    if new_stdout:
1749                        new_stdout.close()
1750                    new_stdout = open("%s.%s" % (old_stdout.name, configPostfix), "w")
1751                    sys.stdout = new_stdout
1752
1753                # If we specified a relocated directory to run the test suite, do
1754                # the extra housekeeping to copy the testdirs to a configStringified
1755                # directory and to update sys.path before invoking the test runner.
1756                # The purpose is to separate the configuration-specific directories
1757                # from each other.
1758                if rdir:
1759                    from shutil import copytree, rmtree, ignore_patterns
1760
1761                    newrdir = "%s.%s" % (rdir, configPostfix)
1762
1763                    # Copy the tree to a new directory with postfix name configPostfix.
1764                    if os.path.exists(newrdir):
1765                        rmtree(newrdir)
1766                    copytree(rdir, newrdir, ignore=ignore_patterns('*.pyc', '*.o', '*.d'))
1767
1768                    # Update the LLDB_TEST environment variable to reflect new top
1769                    # level test directory.
1770                    #
1771                    # See also lldbtest.TestBase.setUpClass(cls).
1772                    if len(testdirs) == 1 and os.path.basename(testdirs[0]) == 'test':
1773                        os.environ["LLDB_TEST"] = os.path.join(newrdir, 'test')
1774                    else:
1775                        os.environ["LLDB_TEST"] = newrdir
1776
1777                    # And update the Python search paths for modules.
1778                    sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
1779
1780                # Output the configuration.
1781                if not parsable:
1782                    sys.stderr.write("\nConfiguration: " + configString + "\n")
1783
1784            #print("sys.stderr name is", sys.stderr.name)
1785            #print("sys.stdout name is", sys.stdout.name)
1786
1787            # First, write out the number of collected test cases.
1788            if not parsable:
1789                sys.stderr.write(separator + "\n")
1790                sys.stderr.write("Collected %d test%s\n\n"
1791                                 % (suite.countTestCases(),
1792                                    suite.countTestCases() != 1 and "s" or ""))
1793
1794            class LLDBTestResult(unittest2.TextTestResult):
1795                """
1796                Enforce a singleton pattern to allow introspection of test progress.
1797
1798                Overwrite addError(), addFailure(), and addExpectedFailure() methods
1799                to enable each test instance to track its failure/error status.  It
1800                is used in the LLDB test framework to emit detailed trace messages
1801                to a log file for easier human inspection of test failures/errors.
1802                """
1803                __singleton__ = None
1804                __ignore_singleton__ = False
1805
1806                @staticmethod
1807                def getTerminalSize():
1808                    import os
1809                    env = os.environ
1810                    def ioctl_GWINSZ(fd):
1811                        try:
1812                            import fcntl, termios, struct, os
1813                            cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
1814                        '1234'))
1815                        except:
1816                            return
1817                        return cr
1818                    cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
1819                    if not cr:
1820                        try:
1821                            fd = os.open(os.ctermid(), os.O_RDONLY)
1822                            cr = ioctl_GWINSZ(fd)
1823                            os.close(fd)
1824                        except:
1825                            pass
1826                    if not cr:
1827                        cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
1828                    return int(cr[1]), int(cr[0])
1829
1830                def __init__(self, *args):
1831                    if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
1832                        raise Exception("LLDBTestResult instantiated more than once")
1833                    super(LLDBTestResult, self).__init__(*args)
1834                    LLDBTestResult.__singleton__ = self
1835                    # Now put this singleton into the lldb module namespace.
1836                    lldb.test_result = self
1837                    # Computes the format string for displaying the counter.
1838                    global suite
1839                    counterWidth = len(str(suite.countTestCases()))
1840                    self.fmt = "%" + str(counterWidth) + "d: "
1841                    self.indentation = ' ' * (counterWidth + 2)
1842                    # This counts from 1 .. suite.countTestCases().
1843                    self.counter = 0
1844                    (width, height) = LLDBTestResult.getTerminalSize()
1845                    self.progressbar = None
1846                    global progress_bar
1847                    if width > 10 and not parsable and progress_bar:
1848                        try:
1849                            self.progressbar = progress.ProgressWithEvents(stdout=self.stream,start=0,end=suite.countTestCases(),width=width-10)
1850                        except:
1851                            self.progressbar = None
1852                    self.results_formatter = results_formatter_object
1853
1854                def _config_string(self, test):
1855                  compiler = getattr(test, "getCompiler", None)
1856                  arch = getattr(test, "getArchitecture", None)
1857                  return "%s-%s" % (compiler() if compiler else "", arch() if arch else "")
1858
1859                def _exc_info_to_string(self, err, test):
1860                    """Overrides superclass TestResult's method in order to append
1861                    our test config info string to the exception info string."""
1862                    if hasattr(test, "getArchitecture") and hasattr(test, "getCompiler"):
1863                        return '%sConfig=%s-%s' % (super(LLDBTestResult, self)._exc_info_to_string(err, test),
1864                                                                  test.getArchitecture(),
1865                                                                  test.getCompiler())
1866                    else:
1867                        return super(LLDBTestResult, self)._exc_info_to_string(err, test)
1868
1869                def getDescription(self, test):
1870                    doc_first_line = test.shortDescription()
1871                    if self.descriptions and doc_first_line:
1872                        return '\n'.join((str(test), self.indentation + doc_first_line))
1873                    else:
1874                        return str(test)
1875
1876                def getCategoriesForTest(self,test):
1877                    if hasattr(test,"_testMethodName"):
1878                        test_method = getattr(test,"_testMethodName")
1879                        test_method = getattr(test,test_method)
1880                    else:
1881                        test_method = None
1882                    if test_method != None and hasattr(test_method,"getCategories"):
1883                        test_categories = test_method.getCategories(test)
1884                    elif hasattr(test,"getCategories"):
1885                        test_categories = test.getCategories()
1886                    elif inspect.ismethod(test) and test.__self__ != None and hasattr(test.__self__,"getCategories"):
1887                        test_categories = test.__self__.getCategories()
1888                    else:
1889                        test_categories = []
1890                    if test_categories == None:
1891                        test_categories = []
1892                    return test_categories
1893
1894                def hardMarkAsSkipped(self,test):
1895                    getattr(test, test._testMethodName).__func__.__unittest_skip__ = True
1896                    getattr(test, test._testMethodName).__func__.__unittest_skip_why__ = "test case does not fall in any category of interest for this run"
1897                    test.__class__.__unittest_skip__ = True
1898                    test.__class__.__unittest_skip_why__ = "test case does not fall in any category of interest for this run"
1899
1900                def startTest(self, test):
1901                    if shouldSkipBecauseOfCategories(self.getCategoriesForTest(test)):
1902                        self.hardMarkAsSkipped(test)
1903                    global setCrashInfoHook
1904                    setCrashInfoHook("%s at %s" % (str(test),inspect.getfile(test.__class__)))
1905                    self.counter += 1
1906                    #if self.counter == 4:
1907                    #    import crashinfo
1908                    #    crashinfo.testCrashReporterDescription(None)
1909                    test.test_number = self.counter
1910                    if self.showAll:
1911                        self.stream.write(self.fmt % self.counter)
1912                    super(LLDBTestResult, self).startTest(test)
1913                    if self.results_formatter:
1914                        self.results_formatter.handle_event(
1915                            EventBuilder.event_for_start(test))
1916
1917                def addSuccess(self, test):
1918                    global parsable
1919                    super(LLDBTestResult, self).addSuccess(test)
1920                    if parsable:
1921                        self.stream.write("PASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1922                    if self.results_formatter:
1923                        self.results_formatter.handle_event(
1924                            EventBuilder.event_for_success(test))
1925
1926                def addError(self, test, err):
1927                    global sdir_has_content
1928                    global parsable
1929                    sdir_has_content = True
1930                    super(LLDBTestResult, self).addError(test, err)
1931                    method = getattr(test, "markError", None)
1932                    if method:
1933                        method()
1934                    if parsable:
1935                        self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1936                    if self.results_formatter:
1937                        self.results_formatter.handle_event(
1938                            EventBuilder.event_for_error(test, err))
1939
1940                def addCleanupError(self, test, err):
1941                    global sdir_has_content
1942                    global parsable
1943                    sdir_has_content = True
1944                    super(LLDBTestResult, self).addCleanupError(test, err)
1945                    method = getattr(test, "markCleanupError", None)
1946                    if method:
1947                        method()
1948                    if parsable:
1949                        self.stream.write("CLEANUP ERROR: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1950                    if self.results_formatter:
1951                        self.results_formatter.handle_event(
1952                            EventBuilder.event_for_cleanup_error(
1953                                test, err))
1954
1955                def addFailure(self, test, err):
1956                    global sdir_has_content
1957                    global failuresPerCategory
1958                    global parsable
1959                    sdir_has_content = True
1960                    super(LLDBTestResult, self).addFailure(test, err)
1961                    method = getattr(test, "markFailure", None)
1962                    if method:
1963                        method()
1964                    if parsable:
1965                        self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1966                    if useCategories:
1967                        test_categories = self.getCategoriesForTest(test)
1968                        for category in test_categories:
1969                            if category in failuresPerCategory:
1970                                failuresPerCategory[category] = failuresPerCategory[category] + 1
1971                            else:
1972                                failuresPerCategory[category] = 1
1973                    if self.results_formatter:
1974                        self.results_formatter.handle_event(
1975                            EventBuilder.event_for_failure(test, err))
1976
1977
1978                def addExpectedFailure(self, test, err, bugnumber):
1979                    global sdir_has_content
1980                    global parsable
1981                    sdir_has_content = True
1982                    super(LLDBTestResult, self).addExpectedFailure(test, err, bugnumber)
1983                    method = getattr(test, "markExpectedFailure", None)
1984                    if method:
1985                        method(err, bugnumber)
1986                    if parsable:
1987                        self.stream.write("XFAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
1988                    if self.results_formatter:
1989                        self.results_formatter.handle_event(
1990                            EventBuilder.event_for_expected_failure(
1991                            test, err, bugnumber))
1992
1993                def addSkip(self, test, reason):
1994                    global sdir_has_content
1995                    global parsable
1996                    sdir_has_content = True
1997                    super(LLDBTestResult, self).addSkip(test, reason)
1998                    method = getattr(test, "markSkippedTest", None)
1999                    if method:
2000                        method()
2001                    if parsable:
2002                        self.stream.write("UNSUPPORTED: LLDB (%s) :: %s (%s) \n" % (self._config_string(test), str(test), reason))
2003                    if self.results_formatter:
2004                        self.results_formatter.handle_event(
2005                            EventBuilder.event_for_skip(test, reason))
2006
2007                def addUnexpectedSuccess(self, test, bugnumber):
2008                    global sdir_has_content
2009                    global parsable
2010                    sdir_has_content = True
2011                    super(LLDBTestResult, self).addUnexpectedSuccess(test, bugnumber)
2012                    method = getattr(test, "markUnexpectedSuccess", None)
2013                    if method:
2014                        method(bugnumber)
2015                    if parsable:
2016                        self.stream.write("XPASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
2017                    if self.results_formatter:
2018                        self.results_formatter.handle_event(
2019                            EventBuilder.event_for_unexpected_success(
2020                                test, bugnumber))
2021
2022
2023            if parsable:
2024                v = 0
2025            elif progress_bar:
2026                v = 1
2027            else:
2028                v = verbose
2029
2030            # Invoke the test runner.
2031            if count == 1:
2032                result = unittest2.TextTestRunner(stream=sys.stderr,
2033                                                  verbosity=v,
2034                                                  failfast=failfast,
2035                                                  resultclass=LLDBTestResult).run(suite)
2036            else:
2037                # We are invoking the same test suite more than once.  In this case,
2038                # mark __ignore_singleton__ flag as True so the signleton pattern is
2039                # not enforced.
2040                LLDBTestResult.__ignore_singleton__ = True
2041                for i in range(count):
2042
2043                    result = unittest2.TextTestRunner(stream=sys.stderr,
2044                                                      verbosity=v,
2045                                                      failfast=failfast,
2046                                                      resultclass=LLDBTestResult).run(suite)
2047
2048            failed = failed or not result.wasSuccessful()
2049
2050    if sdir_has_content and not parsable:
2051        sys.stderr.write("Session logs for test failures/errors/unexpected successes"
2052                         " can be found in directory '%s'\n" % sdir_name)
2053
2054    if useCategories and len(failuresPerCategory) > 0:
2055        sys.stderr.write("Failures per category:\n")
2056        for category in failuresPerCategory:
2057            sys.stderr.write("%s - %d\n" % (category,failuresPerCategory[category]))
2058
2059    os.chdir(where_to_save_session)
2060    fname = os.path.join(sdir_name, "TestFinished-%d" % os.getpid())
2061    with open(fname, "w") as f:
2062        print("Test finished at: %s\n" % datetime.datetime.now().strftime("%Y-%m-%d-%H_%M_%S"), file=f)
2063
2064    # Terminate the test suite if ${LLDB_TESTSUITE_FORCE_FINISH} is defined.
2065    # This should not be necessary now.
2066    if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ):
2067        print("Terminating Test suite...")
2068        subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
2069
2070    # Exiting.
2071    exitTestSuite(failed)
2072
2073if __name__ == "__main__":
2074    print(__file__ + " is for use as a module only.  It should not be run as a standalone script.")
2075    sys.exit(-1)
2076