1"""
2LLDB module which provides the abstract base class of lldb test case.
3
4The concrete subclass can override lldbtest.TesBase in order to inherit the
5common behavior for unitest.TestCase.setUp/tearDown implemented in this file.
6
7The subclass should override the attribute mydir in order for the python runtime
8to locate the individual test cases when running as part of a large test suite
9or when running each test case as a separate python invocation.
10
11./dotest.py provides a test driver which sets up the environment to run the
12entire of part of the test suite .  Example:
13
14# Exercises the test suite in the types directory....
15/Volumes/data/lldb/svn/ToT/test $ ./dotest.py -A x86_64 types
16...
17
18Session logs for test failures/errors/unexpected successes will go into directory '2012-05-16-13_35_42'
19Command invoked: python ./dotest.py -A x86_64 types
20compilers=['clang']
21
22Configuration: arch=x86_64 compiler=clang
23----------------------------------------------------------------------
24Collected 72 tests
25
26........................................................................
27----------------------------------------------------------------------
28Ran 72 tests in 135.468s
29
30OK
31$
32"""
33
34from __future__ import print_function
35
36import use_lldb_suite
37
38import abc
39import gc
40import glob
41import os, sys, traceback
42import os.path
43import re
44import signal
45from subprocess import *
46import time
47import types
48import unittest2
49import lldb
50import lldbtest_config
51import lldbutil
52import test_categories
53
54from six import add_metaclass
55from six import StringIO as SixStringIO
56from six.moves.urllib import parse as urlparse
57import six
58import collections
59
60# dosep.py starts lots and lots of dotest instances
61# This option helps you find if two (or more) dotest instances are using the same
62# directory at the same time
63# Enable it to cause test failures and stderr messages if dotest instances try to run in
64# the same directory simultaneously
65# it is disabled by default because it litters the test directories with ".dirlock" files
66debug_confirm_directory_exclusivity = False
67
68# See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
69# LLDB_COMMAND_TRACE and LLDB_DO_CLEANUP are set from '-t' and '-r dir' options.
70
71# By default, traceAlways is False.
72if "LLDB_COMMAND_TRACE" in os.environ and os.environ["LLDB_COMMAND_TRACE"]=="YES":
73    traceAlways = True
74else:
75    traceAlways = False
76
77# By default, doCleanup is True.
78if "LLDB_DO_CLEANUP" in os.environ and os.environ["LLDB_DO_CLEANUP"]=="NO":
79    doCleanup = False
80else:
81    doCleanup = True
82
83
84#
85# Some commonly used assert messages.
86#
87
88COMMAND_FAILED_AS_EXPECTED = "Command has failed as expected"
89
90CURRENT_EXECUTABLE_SET = "Current executable set successfully"
91
92PROCESS_IS_VALID = "Process is valid"
93
94PROCESS_KILLED = "Process is killed successfully"
95
96PROCESS_EXITED = "Process exited successfully"
97
98PROCESS_STOPPED = "Process status should be stopped"
99
100RUN_SUCCEEDED = "Process is launched successfully"
101
102RUN_COMPLETED = "Process exited successfully"
103
104BACKTRACE_DISPLAYED_CORRECTLY = "Backtrace displayed correctly"
105
106BREAKPOINT_CREATED = "Breakpoint created successfully"
107
108BREAKPOINT_STATE_CORRECT = "Breakpoint state is correct"
109
110BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
111
112BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1"
113
114BREAKPOINT_HIT_TWICE = "Breakpoint resolved with hit cout = 2"
115
116BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit cout = 3"
117
118MISSING_EXPECTED_REGISTERS = "At least one expected register is unavailable."
119
120OBJECT_PRINTED_CORRECTLY = "Object printed correctly"
121
122SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly"
123
124STEP_OUT_SUCCEEDED = "Thread step-out succeeded"
125
126STOPPED_DUE_TO_EXC_BAD_ACCESS = "Process should be stopped due to bad access exception"
127
128STOPPED_DUE_TO_ASSERT = "Process should be stopped due to an assertion"
129
130STOPPED_DUE_TO_BREAKPOINT = "Process should be stopped due to breakpoint"
131
132STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS = "%s, %s" % (
133    STOPPED_DUE_TO_BREAKPOINT, "instead, the actual stop reason is: '%s'")
134
135STOPPED_DUE_TO_BREAKPOINT_CONDITION = "Stopped due to breakpoint condition"
136
137STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT = "Stopped due to breakpoint and ignore count"
138
139STOPPED_DUE_TO_SIGNAL = "Process state is stopped due to signal"
140
141STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"
142
143STOPPED_DUE_TO_WATCHPOINT = "Process should be stopped due to watchpoint"
144
145DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
146
147VALID_BREAKPOINT = "Got a valid breakpoint"
148
149VALID_BREAKPOINT_LOCATION = "Got a valid breakpoint location"
150
151VALID_COMMAND_INTERPRETER = "Got a valid command interpreter"
152
153VALID_FILESPEC = "Got a valid filespec"
154
155VALID_MODULE = "Got a valid module"
156
157VALID_PROCESS = "Got a valid process"
158
159VALID_SYMBOL = "Got a valid symbol"
160
161VALID_TARGET = "Got a valid target"
162
163VALID_PLATFORM = "Got a valid platform"
164
165VALID_TYPE = "Got a valid type"
166
167VALID_VARIABLE = "Got a valid variable"
168
169VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
170
171WATCHPOINT_CREATED = "Watchpoint created successfully"
172
173def CMD_MSG(str):
174    '''A generic "Command '%s' returns successfully" message generator.'''
175    return "Command '%s' returns successfully" % str
176
177def COMPLETION_MSG(str_before, str_after):
178    '''A generic message generator for the completion mechanism.'''
179    return "'%s' successfully completes to '%s'" % (str_before, str_after)
180
181def EXP_MSG(str, exe):
182    '''A generic "'%s' returns expected result" message generator if exe.
183    Otherwise, it generates "'%s' matches expected result" message.'''
184    return "'%s' %s expected result" % (str, 'returns' if exe else 'matches')
185
186def SETTING_MSG(setting):
187    '''A generic "Value of setting '%s' is correct" message generator.'''
188    return "Value of setting '%s' is correct" % setting
189
190def EnvArray():
191    """Returns an env variable array from the os.environ map object."""
192    return list(map(lambda k,v: k+"="+v, list(os.environ.keys()), list(os.environ.values())))
193
194def line_number(filename, string_to_match):
195    """Helper function to return the line number of the first matched string."""
196    with open(filename, 'r') as f:
197        for i, line in enumerate(f):
198            if line.find(string_to_match) != -1:
199                # Found our match.
200                return i+1
201    raise Exception("Unable to find '%s' within file %s" % (string_to_match, filename))
202
203def pointer_size():
204    """Return the pointer size of the host system."""
205    import ctypes
206    a_pointer = ctypes.c_void_p(0xffff)
207    return 8 * ctypes.sizeof(a_pointer)
208
209def is_exe(fpath):
210    """Returns true if fpath is an executable."""
211    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
212
213def which(program):
214    """Returns the full path to a program; None otherwise."""
215    fpath, fname = os.path.split(program)
216    if fpath:
217        if is_exe(program):
218            return program
219    else:
220        for path in os.environ["PATH"].split(os.pathsep):
221            exe_file = os.path.join(path, program)
222            if is_exe(exe_file):
223                return exe_file
224    return None
225
226class recording(SixStringIO):
227    """
228    A nice little context manager for recording the debugger interactions into
229    our session object.  If trace flag is ON, it also emits the interactions
230    into the stderr.
231    """
232    def __init__(self, test, trace):
233        """Create a SixStringIO instance; record the session obj and trace flag."""
234        SixStringIO.__init__(self)
235        # The test might not have undergone the 'setUp(self)' phase yet, so that
236        # the attribute 'session' might not even exist yet.
237        self.session = getattr(test, "session", None) if test else None
238        self.trace = trace
239
240    def __enter__(self):
241        """
242        Context management protocol on entry to the body of the with statement.
243        Just return the SixStringIO object.
244        """
245        return self
246
247    def __exit__(self, type, value, tb):
248        """
249        Context management protocol on exit from the body of the with statement.
250        If trace is ON, it emits the recordings into stderr.  Always add the
251        recordings to our session object.  And close the SixStringIO object, too.
252        """
253        if self.trace:
254            print(self.getvalue(), file=sys.stderr)
255        if self.session:
256            print(self.getvalue(), file=self.session)
257        self.close()
258
259@add_metaclass(abc.ABCMeta)
260class _BaseProcess(object):
261
262    @abc.abstractproperty
263    def pid(self):
264        """Returns process PID if has been launched already."""
265
266    @abc.abstractmethod
267    def launch(self, executable, args):
268        """Launches new process with given executable and args."""
269
270    @abc.abstractmethod
271    def terminate(self):
272        """Terminates previously launched process.."""
273
274class _LocalProcess(_BaseProcess):
275
276    def __init__(self, trace_on):
277        self._proc = None
278        self._trace_on = trace_on
279        self._delayafterterminate = 0.1
280
281    @property
282    def pid(self):
283        return self._proc.pid
284
285    def launch(self, executable, args):
286        self._proc = Popen([executable] + args,
287                           stdout = open(os.devnull) if not self._trace_on else None,
288                           stdin = PIPE)
289
290    def terminate(self):
291        if self._proc.poll() == None:
292            # Terminate _proc like it does the pexpect
293            signals_to_try = [sig for sig in ['SIGHUP', 'SIGCONT', 'SIGINT'] if sig in dir(signal)]
294            for sig in signals_to_try:
295                try:
296                    self._proc.send_signal(getattr(signal, sig))
297                    time.sleep(self._delayafterterminate)
298                    if self._proc.poll() != None:
299                        return
300                except ValueError:
301                    pass  # Windows says SIGINT is not a valid signal to send
302            self._proc.terminate()
303            time.sleep(self._delayafterterminate)
304            if self._proc.poll() != None:
305                return
306            self._proc.kill()
307            time.sleep(self._delayafterterminate)
308
309    def poll(self):
310        return self._proc.poll()
311
312class _RemoteProcess(_BaseProcess):
313
314    def __init__(self, install_remote):
315        self._pid = None
316        self._install_remote = install_remote
317
318    @property
319    def pid(self):
320        return self._pid
321
322    def launch(self, executable, args):
323        if self._install_remote:
324            src_path = executable
325            dst_path = lldbutil.append_to_process_working_directory(os.path.basename(executable))
326
327            dst_file_spec = lldb.SBFileSpec(dst_path, False)
328            err = lldb.remote_platform.Install(lldb.SBFileSpec(src_path, True), dst_file_spec)
329            if err.Fail():
330                raise Exception("remote_platform.Install('%s', '%s') failed: %s" % (src_path, dst_path, err))
331        else:
332            dst_path = executable
333            dst_file_spec = lldb.SBFileSpec(executable, False)
334
335        launch_info = lldb.SBLaunchInfo(args)
336        launch_info.SetExecutableFile(dst_file_spec, True)
337        launch_info.SetWorkingDirectory(lldb.remote_platform.GetWorkingDirectory())
338
339        # Redirect stdout and stderr to /dev/null
340        launch_info.AddSuppressFileAction(1, False, True)
341        launch_info.AddSuppressFileAction(2, False, True)
342
343        err = lldb.remote_platform.Launch(launch_info)
344        if err.Fail():
345            raise Exception("remote_platform.Launch('%s', '%s') failed: %s" % (dst_path, args, err))
346        self._pid = launch_info.GetProcessID()
347
348    def terminate(self):
349        lldb.remote_platform.Kill(self._pid)
350
351# From 2.7's subprocess.check_output() convenience function.
352# Return a tuple (stdoutdata, stderrdata).
353def system(commands, **kwargs):
354    r"""Run an os command with arguments and return its output as a byte string.
355
356    If the exit code was non-zero it raises a CalledProcessError.  The
357    CalledProcessError object will have the return code in the returncode
358    attribute and output in the output attribute.
359
360    The arguments are the same as for the Popen constructor.  Example:
361
362    >>> check_output(["ls", "-l", "/dev/null"])
363    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
364
365    The stdout argument is not allowed as it is used internally.
366    To capture standard error in the result, use stderr=STDOUT.
367
368    >>> check_output(["/bin/sh", "-c",
369    ...               "ls -l non_existent_file ; exit 0"],
370    ...              stderr=STDOUT)
371    'ls: non_existent_file: No such file or directory\n'
372    """
373
374    # Assign the sender object to variable 'test' and remove it from kwargs.
375    test = kwargs.pop('sender', None)
376
377    # [['make', 'clean', 'foo'], ['make', 'foo']] -> ['make clean foo', 'make foo']
378    commandList = [' '.join(x) for x in commands]
379    output = ""
380    error = ""
381    for shellCommand in commandList:
382        if 'stdout' in kwargs:
383            raise ValueError('stdout argument not allowed, it will be overridden.')
384        if 'shell' in kwargs and kwargs['shell']==False:
385            raise ValueError('shell=False not allowed')
386        process = Popen(shellCommand, stdout=PIPE, stderr=PIPE, shell=True, **kwargs)
387        pid = process.pid
388        this_output, this_error = process.communicate()
389        retcode = process.poll()
390
391        # Enable trace on failure return while tracking down FreeBSD buildbot issues
392        trace = traceAlways
393        if not trace and retcode and sys.platform.startswith("freebsd"):
394            trace = True
395
396        with recording(test, trace) as sbuf:
397            print(file=sbuf)
398            print("os command:", shellCommand, file=sbuf)
399            print("with pid:", pid, file=sbuf)
400            print("stdout:", this_output, file=sbuf)
401            print("stderr:", this_error, file=sbuf)
402            print("retcode:", retcode, file=sbuf)
403            print(file=sbuf)
404
405        if retcode:
406            cmd = kwargs.get("args")
407            if cmd is None:
408                cmd = shellCommand
409            raise CalledProcessError(retcode, cmd)
410        output = output + this_output
411        error = error + this_error
412    return (output, error)
413
414def getsource_if_available(obj):
415    """
416    Return the text of the source code for an object if available.  Otherwise,
417    a print representation is returned.
418    """
419    import inspect
420    try:
421        return inspect.getsource(obj)
422    except:
423        return repr(obj)
424
425def builder_module():
426    if sys.platform.startswith("freebsd"):
427        return __import__("builder_freebsd")
428    return __import__("builder_" + sys.platform)
429
430def run_adb_command(cmd, device_id):
431    device_id_args = []
432    if device_id:
433        device_id_args = ["-s", device_id]
434    full_cmd = ["adb"] + device_id_args + cmd
435    p = Popen(full_cmd, stdout=PIPE, stderr=PIPE)
436    stdout, stderr = p.communicate()
437    return p.returncode, stdout, stderr
438
439def append_android_envs(dictionary):
440    if dictionary is None:
441        dictionary = {}
442    dictionary["OS"] = "Android"
443    if android_device_api() >= 16:
444        dictionary["PIE"] = 1
445    return dictionary
446
447def target_is_android():
448    if not hasattr(target_is_android, 'result'):
449        triple = lldb.DBG.GetSelectedPlatform().GetTriple()
450        match = re.match(".*-.*-.*-android", triple)
451        target_is_android.result = match is not None
452    return target_is_android.result
453
454def android_device_api():
455    if not hasattr(android_device_api, 'result'):
456        assert lldb.platform_url is not None
457        device_id = None
458        parsed_url = urlparse.urlparse(lldb.platform_url)
459        if parsed_url.scheme == "adb":
460            device_id = parsed_url.netloc.split(":")[0]
461        retcode, stdout, stderr = run_adb_command(
462            ["shell", "getprop", "ro.build.version.sdk"], device_id)
463        if retcode == 0:
464            android_device_api.result = int(stdout)
465        else:
466            raise LookupError(
467                ">>> Unable to determine the API level of the Android device.\n"
468                ">>> stdout:\n%s\n"
469                ">>> stderr:\n%s\n" % (stdout, stderr))
470    return android_device_api.result
471
472#
473# Decorators for categorizing test cases.
474#
475from functools import wraps
476def add_test_categories(cat):
477    """Decorate an item with test categories"""
478    cat = test_categories.validate(cat, True)
479    def impl(func):
480        func.getCategories = lambda test: cat
481        return func
482    return impl
483
484def benchmarks_test(func):
485    """Decorate the item as a benchmarks test."""
486    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
487        raise Exception("@benchmarks_test can only be used to decorate a test method")
488    @wraps(func)
489    def wrapper(self, *args, **kwargs):
490        if not lldb.just_do_benchmarks_test:
491            self.skipTest("benchmarks tests")
492        return func(self, *args, **kwargs)
493
494    # Mark this function as such to separate them from the regular tests.
495    wrapper.__benchmarks_test__ = True
496    return wrapper
497
498def no_debug_info_test(func):
499    """Decorate the item as a test what don't use any debug info. If this annotation is specified
500       then the test runner won't generate a separate test for each debug info format. """
501    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
502        raise Exception("@no_debug_info_test can only be used to decorate a test method")
503    @wraps(func)
504    def wrapper(self, *args, **kwargs):
505        return func(self, *args, **kwargs)
506
507    # Mark this function as such to separate them from the regular tests.
508    wrapper.__no_debug_info_test__ = True
509    return wrapper
510
511def dsym_test(func):
512    """Decorate the item as a dsym test."""
513    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
514        raise Exception("@dsym_test can only be used to decorate a test method")
515    @wraps(func)
516    def wrapper(self, *args, **kwargs):
517        if lldb.dont_do_dsym_test:
518            self.skipTest("dsym tests")
519        return func(self, *args, **kwargs)
520
521    # Mark this function as such to separate them from the regular tests.
522    wrapper.__dsym_test__ = True
523    return wrapper
524
525def dwarf_test(func):
526    """Decorate the item as a dwarf test."""
527    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
528        raise Exception("@dwarf_test can only be used to decorate a test method")
529    @wraps(func)
530    def wrapper(self, *args, **kwargs):
531        if lldb.dont_do_dwarf_test:
532            self.skipTest("dwarf tests")
533        return func(self, *args, **kwargs)
534
535    # Mark this function as such to separate them from the regular tests.
536    wrapper.__dwarf_test__ = True
537    return wrapper
538
539def dwo_test(func):
540    """Decorate the item as a dwo test."""
541    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
542        raise Exception("@dwo_test can only be used to decorate a test method")
543    @wraps(func)
544    def wrapper(self, *args, **kwargs):
545        if lldb.dont_do_dwo_test:
546            self.skipTest("dwo tests")
547        return func(self, *args, **kwargs)
548
549    # Mark this function as such to separate them from the regular tests.
550    wrapper.__dwo_test__ = True
551    return wrapper
552
553def debugserver_test(func):
554    """Decorate the item as a debugserver test."""
555    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
556        raise Exception("@debugserver_test can only be used to decorate a test method")
557    @wraps(func)
558    def wrapper(self, *args, **kwargs):
559        if lldb.dont_do_debugserver_test:
560            self.skipTest("debugserver tests")
561        return func(self, *args, **kwargs)
562
563    # Mark this function as such to separate them from the regular tests.
564    wrapper.__debugserver_test__ = True
565    return wrapper
566
567def llgs_test(func):
568    """Decorate the item as a lldb-server test."""
569    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
570        raise Exception("@llgs_test can only be used to decorate a test method")
571    @wraps(func)
572    def wrapper(self, *args, **kwargs):
573        if lldb.dont_do_llgs_test:
574            self.skipTest("llgs tests")
575        return func(self, *args, **kwargs)
576
577    # Mark this function as such to separate them from the regular tests.
578    wrapper.__llgs_test__ = True
579    return wrapper
580
581def not_remote_testsuite_ready(func):
582    """Decorate the item as a test which is not ready yet for remote testsuite."""
583    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
584        raise Exception("@not_remote_testsuite_ready can only be used to decorate a test method")
585    @wraps(func)
586    def wrapper(self, *args, **kwargs):
587        if lldb.lldbtest_remote_sandbox or lldb.remote_platform:
588            self.skipTest("not ready for remote testsuite")
589        return func(self, *args, **kwargs)
590
591    # Mark this function as such to separate them from the regular tests.
592    wrapper.__not_ready_for_remote_testsuite_test__ = True
593    return wrapper
594
595def expectedFailure(expected_fn, bugnumber=None):
596    def expectedFailure_impl(func):
597        @wraps(func)
598        def wrapper(*args, **kwargs):
599            from unittest2 import case
600            self = args[0]
601            try:
602                func(*args, **kwargs)
603            except Exception:
604                if expected_fn(self):
605                    raise case._ExpectedFailure(sys.exc_info(), bugnumber)
606                else:
607                    raise
608            if expected_fn(self):
609                raise case._UnexpectedSuccess(sys.exc_info(), bugnumber)
610        return wrapper
611    # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
612    # return decorator in this case, so it will be used to decorating original method
613    if six.callable(bugnumber):
614        return expectedFailure_impl(bugnumber)
615    else:
616        return expectedFailure_impl
617
618# provide a function to xfail on defined oslist, compiler version, and archs
619# if none is specified for any argument, that argument won't be checked and thus means for all
620# for example,
621# @expectedFailureAll, xfail for all platform/compiler/arch,
622# @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture
623# @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386
624def expectedFailureAll(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None, triple=None, debug_info=None):
625    def fn(self):
626        return ((oslist is None or self.getPlatform() in oslist) and
627                (compiler is None or (compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version))) and
628                self.expectedArch(archs) and
629                (triple is None or re.match(triple, lldb.DBG.GetSelectedPlatform().GetTriple())) and
630                (debug_info is None or self.debug_info in debug_info))
631    return expectedFailure(fn, bugnumber)
632
633def expectedFailureDwarf(bugnumber=None):
634    return expectedFailureAll(bugnumber=bugnumber, debug_info="dwarf")
635
636def expectedFailureDwo(bugnumber=None):
637    return expectedFailureAll(bugnumber=bugnumber, debug_info="dwo")
638
639def expectedFailureDsym(bugnumber=None):
640    return expectedFailureAll(bugnumber=bugnumber, debug_info="dsym")
641
642def expectedFailureCompiler(compiler, compiler_version=None, bugnumber=None):
643    if compiler_version is None:
644        compiler_version=['=', None]
645    return expectedFailureAll(bugnumber=bugnumber, compiler=compiler, compiler_version=compiler_version)
646
647# to XFAIL a specific clang versions, try this
648# @expectedFailureClang('bugnumber', ['<=', '3.4'])
649def expectedFailureClang(bugnumber=None, compiler_version=None):
650    return expectedFailureCompiler('clang', compiler_version, bugnumber)
651
652def expectedFailureGcc(bugnumber=None, compiler_version=None):
653    return expectedFailureCompiler('gcc', compiler_version, bugnumber)
654
655def expectedFailureIcc(bugnumber=None):
656    return expectedFailureCompiler('icc', None, bugnumber)
657
658def expectedFailureArch(arch, bugnumber=None):
659    def fn(self):
660        return arch in self.getArchitecture()
661    return expectedFailure(fn, bugnumber)
662
663def expectedFailurei386(bugnumber=None):
664    return expectedFailureArch('i386', bugnumber)
665
666def expectedFailurex86_64(bugnumber=None):
667    return expectedFailureArch('x86_64', bugnumber)
668
669def expectedFailureOS(oslist, bugnumber=None, compilers=None, debug_info=None):
670    def fn(self):
671        return (self.getPlatform() in oslist and
672                self.expectedCompiler(compilers) and
673                (debug_info is None or self.debug_info in debug_info))
674    return expectedFailure(fn, bugnumber)
675
676def expectedFailureHostOS(oslist, bugnumber=None, compilers=None):
677    def fn(self):
678        return (getHostPlatform() in oslist and
679                self.expectedCompiler(compilers))
680    return expectedFailure(fn, bugnumber)
681
682def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None):
683    # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
684    return expectedFailureOS(getDarwinOSTriples(), bugnumber, compilers, debug_info=debug_info)
685
686def expectedFailureFreeBSD(bugnumber=None, compilers=None, debug_info=None):
687    return expectedFailureOS(['freebsd'], bugnumber, compilers, debug_info=debug_info)
688
689def expectedFailureLinux(bugnumber=None, compilers=None, debug_info=None):
690    return expectedFailureOS(['linux'], bugnumber, compilers, debug_info=debug_info)
691
692def expectedFailureWindows(bugnumber=None, compilers=None, debug_info=None):
693    return expectedFailureOS(['windows'], bugnumber, compilers, debug_info=debug_info)
694
695def expectedFailureHostWindows(bugnumber=None, compilers=None):
696    return expectedFailureHostOS(['windows'], bugnumber, compilers)
697
698def matchAndroid(api_levels=None, archs=None):
699    def match(self):
700        if not target_is_android():
701            return False
702        if archs is not None and self.getArchitecture() not in archs:
703            return False
704        if api_levels is not None and android_device_api() not in api_levels:
705            return False
706        return True
707    return match
708
709
710def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
711    """ Mark a test as xfail for Android.
712
713    Arguments:
714        bugnumber - The LLVM pr associated with the problem.
715        api_levels - A sequence of numbers specifying the Android API levels
716            for which a test is expected to fail. None means all API level.
717        arch - A sequence of architecture names specifying the architectures
718            for which a test is expected to fail. None means all architectures.
719    """
720    return expectedFailure(matchAndroid(api_levels, archs), bugnumber)
721
722# if the test passes on the first try, we're done (success)
723# if the test fails once, then passes on the second try, raise an ExpectedFailure
724# if the test fails twice in a row, re-throw the exception from the second test run
725def expectedFlakey(expected_fn, bugnumber=None):
726    def expectedFailure_impl(func):
727        @wraps(func)
728        def wrapper(*args, **kwargs):
729            from unittest2 import case
730            self = args[0]
731            try:
732                func(*args, **kwargs)
733            # don't retry if the test case is already decorated with xfail or skip
734            except (case._ExpectedFailure, case.SkipTest, case._UnexpectedSuccess):
735                raise
736            except Exception:
737                if expected_fn(self):
738                    # before retry, run tearDown for previous run and setup for next
739                    try:
740                        self.tearDown()
741                        self.setUp()
742                        func(*args, **kwargs)
743                    except Exception:
744                        # oh snap! two failures in a row, record a failure/error
745                        raise
746                    # record the expected failure
747                    raise case._ExpectedFailure(sys.exc_info(), bugnumber)
748                else:
749                    raise
750        return wrapper
751    # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
752    # return decorator in this case, so it will be used to decorating original method
753    if six.callable(bugnumber):
754        return expectedFailure_impl(bugnumber)
755    else:
756        return expectedFailure_impl
757
758def expectedFlakeyDwarf(bugnumber=None):
759    def fn(self):
760        return self.debug_info == "dwarf"
761    return expectedFlakey(fn, bugnumber)
762
763def expectedFlakeyDsym(bugnumber=None):
764    def fn(self):
765        return self.debug_info == "dwarf"
766    return expectedFlakey(fn, bugnumber)
767
768def expectedFlakeyOS(oslist, bugnumber=None, compilers=None):
769    def fn(self):
770        return (self.getPlatform() in oslist and
771                self.expectedCompiler(compilers))
772    return expectedFlakey(fn, bugnumber)
773
774def expectedFlakeyDarwin(bugnumber=None, compilers=None):
775    # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
776    return expectedFlakeyOS(getDarwinOSTriples(), bugnumber, compilers)
777
778def expectedFlakeyLinux(bugnumber=None, compilers=None):
779    return expectedFlakeyOS(['linux'], bugnumber, compilers)
780
781def expectedFlakeyFreeBSD(bugnumber=None, compilers=None):
782    return expectedFlakeyOS(['freebsd'], bugnumber, compilers)
783
784def expectedFlakeyCompiler(compiler, compiler_version=None, bugnumber=None):
785    if compiler_version is None:
786        compiler_version=['=', None]
787    def fn(self):
788        return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
789    return expectedFlakey(fn, bugnumber)
790
791# @expectedFlakeyClang('bugnumber', ['<=', '3.4'])
792def expectedFlakeyClang(bugnumber=None, compiler_version=None):
793    return expectedFlakeyCompiler('clang', compiler_version, bugnumber)
794
795# @expectedFlakeyGcc('bugnumber', ['<=', '3.4'])
796def expectedFlakeyGcc(bugnumber=None, compiler_version=None):
797    return expectedFlakeyCompiler('gcc', compiler_version, bugnumber)
798
799def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None):
800    return expectedFlakey(matchAndroid(api_levels, archs), bugnumber)
801
802def skipIfRemote(func):
803    """Decorate the item to skip tests if testing remotely."""
804    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
805        raise Exception("@skipIfRemote can only be used to decorate a test method")
806    @wraps(func)
807    def wrapper(*args, **kwargs):
808        from unittest2 import case
809        if lldb.remote_platform:
810            self = args[0]
811            self.skipTest("skip on remote platform")
812        else:
813            func(*args, **kwargs)
814    return wrapper
815
816def skipUnlessListedRemote(remote_list=None):
817    def myImpl(func):
818        if isinstance(func, type) and issubclass(func, unittest2.TestCase):
819            raise Exception("@skipIfRemote can only be used to decorate a "
820                            "test method")
821
822        @wraps(func)
823        def wrapper(*args, **kwargs):
824            if remote_list and lldb.remote_platform:
825                self = args[0]
826                triple = self.dbg.GetSelectedPlatform().GetTriple()
827                for r in remote_list:
828                    if r in triple:
829                        func(*args, **kwargs)
830                        return
831                self.skipTest("skip on remote platform %s" % str(triple))
832            else:
833                func(*args, **kwargs)
834        return wrapper
835
836    return myImpl
837
838def skipIfRemoteDueToDeadlock(func):
839    """Decorate the item to skip tests if testing remotely due to the test deadlocking."""
840    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
841        raise Exception("@skipIfRemote can only be used to decorate a test method")
842    @wraps(func)
843    def wrapper(*args, **kwargs):
844        from unittest2 import case
845        if lldb.remote_platform:
846            self = args[0]
847            self.skipTest("skip on remote platform (deadlocks)")
848        else:
849            func(*args, **kwargs)
850    return wrapper
851
852def skipIfNoSBHeaders(func):
853    """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
854    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
855        raise Exception("@skipIfNoSBHeaders can only be used to decorate a test method")
856    @wraps(func)
857    def wrapper(*args, **kwargs):
858        from unittest2 import case
859        self = args[0]
860        if sys.platform.startswith("darwin"):
861            header = os.path.join(os.environ["LLDB_LIB_DIR"], 'LLDB.framework', 'Versions','Current','Headers','LLDB.h')
862        else:
863            header = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h")
864        platform = sys.platform
865        if not os.path.exists(header):
866            self.skipTest("skip because LLDB.h header not found")
867        else:
868            func(*args, **kwargs)
869    return wrapper
870
871def skipIfFreeBSD(func):
872    """Decorate the item to skip tests that should be skipped on FreeBSD."""
873    return skipIfPlatform(["freebsd"])(func)
874
875def getDarwinOSTriples():
876    return ['darwin', 'macosx', 'ios']
877
878def skipIfDarwin(func):
879    """Decorate the item to skip tests that should be skipped on Darwin."""
880    return skipIfPlatform(getDarwinOSTriples())(func)
881
882def skipIfLinux(func):
883    """Decorate the item to skip tests that should be skipped on Linux."""
884    return skipIfPlatform(["linux"])(func)
885
886def skipUnlessHostLinux(func):
887    """Decorate the item to skip tests that should be skipped on any non Linux host."""
888    return skipUnlessHostPlatform(["linux"])(func)
889
890def skipIfWindows(func):
891    """Decorate the item to skip tests that should be skipped on Windows."""
892    return skipIfPlatform(["windows"])(func)
893
894def skipIfHostWindows(func):
895    """Decorate the item to skip tests that should be skipped on Windows."""
896    return skipIfHostPlatform(["windows"])(func)
897
898def skipUnlessWindows(func):
899    """Decorate the item to skip tests that should be skipped on any non-Windows platform."""
900    return skipUnlessPlatform(["windows"])(func)
901
902def skipUnlessDarwin(func):
903    """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
904    return skipUnlessPlatform(getDarwinOSTriples())(func)
905
906def skipUnlessGoInstalled(func):
907    """Decorate the item to skip tests when no Go compiler is available."""
908    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
909        raise Exception("@skipIfGcc can only be used to decorate a test method")
910    @wraps(func)
911    def wrapper(*args, **kwargs):
912        from unittest2 import case
913        self = args[0]
914        compiler = self.getGoCompilerVersion()
915        if not compiler:
916            self.skipTest("skipping because go compiler not found")
917        else:
918            # Ensure the version is the minimum version supported by
919            # the LLDB go support.
920            match_version = re.search(r"(\d+\.\d+(\.\d+)?)", compiler)
921            if not match_version:
922                # Couldn't determine version.
923                self.skipTest(
924                    "skipping because go version could not be parsed "
925                    "out of {}".format(compiler))
926            else:
927                from distutils.version import StrictVersion
928                min_strict_version = StrictVersion("1.4.0")
929                compiler_strict_version = StrictVersion(match_version.group(1))
930                if compiler_strict_version < min_strict_version:
931                    self.skipTest(
932                        "skipping because available go version ({}) does "
933                        "not meet minimum required go version ({})".format(
934                            compiler_strict_version,
935                            min_strict_version))
936            func(*args, **kwargs)
937    return wrapper
938
939def getPlatform():
940    """Returns the target platform which the tests are running on."""
941    platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
942    if platform.startswith('freebsd'):
943        platform = 'freebsd'
944    return platform
945
946def getHostPlatform():
947    """Returns the host platform running the test suite."""
948    # Attempts to return a platform name matching a target Triple platform.
949    if sys.platform.startswith('linux'):
950        return 'linux'
951    elif sys.platform.startswith('win32'):
952        return 'windows'
953    elif sys.platform.startswith('darwin'):
954        return 'darwin'
955    elif sys.platform.startswith('freebsd'):
956        return 'freebsd'
957    else:
958        return sys.platform
959
960def platformIsDarwin():
961    """Returns true if the OS triple for the selected platform is any valid apple OS"""
962    return getPlatform() in getDarwinOSTriples()
963
964def skipIfHostIncompatibleWithRemote(func):
965    """Decorate the item to skip tests if binaries built on this host are incompatible."""
966    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
967        raise Exception("@skipIfHostIncompatibleWithRemote can only be used to decorate a test method")
968    @wraps(func)
969    def wrapper(*args, **kwargs):
970        from unittest2 import case
971        self = args[0]
972        host_arch = self.getLldbArchitecture()
973        host_platform = getHostPlatform()
974        target_arch = self.getArchitecture()
975        target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform()
976        if not (target_arch == 'x86_64' and host_arch == 'i386') and host_arch != target_arch:
977            self.skipTest("skipping because target %s is not compatible with host architecture %s" % (target_arch, host_arch))
978        elif target_platform != host_platform:
979            self.skipTest("skipping because target is %s but host is %s" % (target_platform, host_platform))
980        else:
981            func(*args, **kwargs)
982    return wrapper
983
984def skipIfHostPlatform(oslist):
985    """Decorate the item to skip tests if running on one of the listed host platforms."""
986    return unittest2.skipIf(getHostPlatform() in oslist,
987                            "skip on %s" % (", ".join(oslist)))
988
989def skipUnlessHostPlatform(oslist):
990    """Decorate the item to skip tests unless running on one of the listed host platforms."""
991    return unittest2.skipUnless(getHostPlatform() in oslist,
992                                "requires on of %s" % (", ".join(oslist)))
993
994def skipUnlessArch(archlist):
995    """Decorate the item to skip tests unless running on one of the listed architectures."""
996    def myImpl(func):
997        if isinstance(func, type) and issubclass(func, unittest2.TestCase):
998            raise Exception("@skipUnlessArch can only be used to decorate a test method")
999
1000        @wraps(func)
1001        def wrapper(*args, **kwargs):
1002            self = args[0]
1003            if self.getArchitecture() not in archlist:
1004                self.skipTest("skipping for architecture %s (requires one of %s)" %
1005                    (self.getArchitecture(), ", ".join(archlist)))
1006            else:
1007                func(*args, **kwargs)
1008        return wrapper
1009
1010    return myImpl
1011
1012def skipIfPlatform(oslist):
1013    """Decorate the item to skip tests if running on one of the listed platforms."""
1014    return unittest2.skipIf(getPlatform() in oslist,
1015                            "skip on %s" % (", ".join(oslist)))
1016
1017def skipUnlessPlatform(oslist):
1018    """Decorate the item to skip tests unless running on one of the listed platforms."""
1019    return unittest2.skipUnless(getPlatform() in oslist,
1020                                "requires on of %s" % (", ".join(oslist)))
1021
1022def skipIfLinuxClang(func):
1023    """Decorate the item to skip tests that should be skipped if building on
1024       Linux with clang.
1025    """
1026    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1027        raise Exception("@skipIfLinuxClang can only be used to decorate a test method")
1028    @wraps(func)
1029    def wrapper(*args, **kwargs):
1030        from unittest2 import case
1031        self = args[0]
1032        compiler = self.getCompiler()
1033        platform = self.getPlatform()
1034        if "clang" in compiler and platform == "linux":
1035            self.skipTest("skipping because Clang is used on Linux")
1036        else:
1037            func(*args, **kwargs)
1038    return wrapper
1039
1040# provide a function to skip on defined oslist, compiler version, and archs
1041# if none is specified for any argument, that argument won't be checked and thus means for all
1042# for example,
1043# @skipIf, skip for all platform/compiler/arch,
1044# @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
1045# @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
1046
1047# TODO: refactor current code, to make skipIfxxx functions to call this function
1048def skipIf(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None, debug_info=None):
1049    def fn(self):
1050        return ((oslist is None or self.getPlatform() in oslist) and
1051                (compiler is None or (compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version))) and
1052                self.expectedArch(archs) and
1053                (debug_info is None or self.debug_info in debug_info))
1054    return skipTestIfFn(fn, bugnumber, skipReason="skipping because os:%s compiler: %s %s arch: %s debug info: %s"%(oslist, compiler, compiler_version, archs, debug_info))
1055
1056def skipIfDebugInfo(bugnumber=None, debug_info=None):
1057    return skipIf(bugnumber=bugnumber, debug_info=debug_info)
1058
1059def skipIfDWO(bugnumber=None):
1060    return skipIfDebugInfo(bugnumber, ["dwo"])
1061
1062def skipIfDwarf(bugnumber=None):
1063    return skipIfDebugInfo(bugnumber, ["dwarf"])
1064
1065def skipIfDsym(bugnumber=None):
1066    return skipIfDebugInfo(bugnumber, ["dsym"])
1067
1068def skipTestIfFn(expected_fn, bugnumber=None, skipReason=None):
1069    def skipTestIfFn_impl(func):
1070        @wraps(func)
1071        def wrapper(*args, **kwargs):
1072            from unittest2 import case
1073            self = args[0]
1074            if expected_fn(self):
1075               self.skipTest(skipReason)
1076            else:
1077                func(*args, **kwargs)
1078        return wrapper
1079    if six.callable(bugnumber):
1080        return skipTestIfFn_impl(bugnumber)
1081    else:
1082        return skipTestIfFn_impl
1083
1084def skipIfGcc(func):
1085    """Decorate the item to skip tests that should be skipped if building with gcc ."""
1086    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1087        raise Exception("@skipIfGcc can only be used to decorate a test method")
1088    @wraps(func)
1089    def wrapper(*args, **kwargs):
1090        from unittest2 import case
1091        self = args[0]
1092        compiler = self.getCompiler()
1093        if "gcc" in compiler:
1094            self.skipTest("skipping because gcc is the test compiler")
1095        else:
1096            func(*args, **kwargs)
1097    return wrapper
1098
1099def skipIfIcc(func):
1100    """Decorate the item to skip tests that should be skipped if building with icc ."""
1101    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1102        raise Exception("@skipIfIcc can only be used to decorate a test method")
1103    @wraps(func)
1104    def wrapper(*args, **kwargs):
1105        from unittest2 import case
1106        self = args[0]
1107        compiler = self.getCompiler()
1108        if "icc" in compiler:
1109            self.skipTest("skipping because icc is the test compiler")
1110        else:
1111            func(*args, **kwargs)
1112    return wrapper
1113
1114def skipIfi386(func):
1115    """Decorate the item to skip tests that should be skipped if building 32-bit."""
1116    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1117        raise Exception("@skipIfi386 can only be used to decorate a test method")
1118    @wraps(func)
1119    def wrapper(*args, **kwargs):
1120        from unittest2 import case
1121        self = args[0]
1122        if "i386" == self.getArchitecture():
1123            self.skipTest("skipping because i386 is not a supported architecture")
1124        else:
1125            func(*args, **kwargs)
1126    return wrapper
1127
1128def skipIfTargetAndroid(api_levels=None, archs=None):
1129    """Decorator to skip tests when the target is Android.
1130
1131    Arguments:
1132        api_levels - The API levels for which the test should be skipped. If
1133            it is None, then the test will be skipped for all API levels.
1134        arch - A sequence of architecture names specifying the architectures
1135            for which a test is skipped. None means all architectures.
1136    """
1137    def myImpl(func):
1138        if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1139            raise Exception("@skipIfTargetAndroid can only be used to "
1140                            "decorate a test method")
1141        @wraps(func)
1142        def wrapper(*args, **kwargs):
1143            from unittest2 import case
1144            self = args[0]
1145            if matchAndroid(api_levels, archs)(self):
1146                self.skipTest("skiped on Android target with API %d and architecture %s" %
1147                        (android_device_api(), self.getArchitecture()))
1148            func(*args, **kwargs)
1149        return wrapper
1150    return myImpl
1151
1152def skipUnlessCompilerRt(func):
1153    """Decorate the item to skip tests if testing remotely."""
1154    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1155        raise Exception("@skipUnless can only be used to decorate a test method")
1156    @wraps(func)
1157    def wrapper(*args, **kwargs):
1158        from unittest2 import case
1159        import os.path
1160        compilerRtPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "projects", "compiler-rt")
1161        if not os.path.exists(compilerRtPath):
1162            self = args[0]
1163            self.skipTest("skip if compiler-rt not found")
1164        else:
1165            func(*args, **kwargs)
1166    return wrapper
1167
1168class _PlatformContext(object):
1169    """Value object class which contains platform-specific options."""
1170
1171    def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
1172        self.shlib_environment_var = shlib_environment_var
1173        self.shlib_prefix = shlib_prefix
1174        self.shlib_extension = shlib_extension
1175
1176
1177class Base(unittest2.TestCase):
1178    """
1179    Abstract base for performing lldb (see TestBase) or other generic tests (see
1180    BenchBase for one example).  lldbtest.Base works with the test driver to
1181    accomplish things.
1182
1183    """
1184
1185    # The concrete subclass should override this attribute.
1186    mydir = None
1187
1188    # Keep track of the old current working directory.
1189    oldcwd = None
1190
1191    @staticmethod
1192    def compute_mydir(test_file):
1193        '''Subclasses should call this function to correctly calculate the required "mydir" attribute as follows:
1194
1195            mydir = TestBase.compute_mydir(__file__)'''
1196        test_dir = os.path.dirname(test_file)
1197        return test_dir[len(os.environ["LLDB_TEST"])+1:]
1198
1199    def TraceOn(self):
1200        """Returns True if we are in trace mode (tracing detailed test execution)."""
1201        return traceAlways
1202
1203    @classmethod
1204    def setUpClass(cls):
1205        """
1206        Python unittest framework class setup fixture.
1207        Do current directory manipulation.
1208        """
1209        # Fail fast if 'mydir' attribute is not overridden.
1210        if not cls.mydir or len(cls.mydir) == 0:
1211            raise Exception("Subclasses must override the 'mydir' attribute.")
1212
1213        # Save old working directory.
1214        cls.oldcwd = os.getcwd()
1215
1216        # Change current working directory if ${LLDB_TEST} is defined.
1217        # See also dotest.py which sets up ${LLDB_TEST}.
1218        if ("LLDB_TEST" in os.environ):
1219            full_dir = os.path.join(os.environ["LLDB_TEST"], cls.mydir)
1220            if traceAlways:
1221                print("Change dir to:", full_dir, file=sys.stderr)
1222            os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
1223
1224        if debug_confirm_directory_exclusivity:
1225            import lock
1226            cls.dir_lock = lock.Lock(os.path.join(full_dir, ".dirlock"))
1227            try:
1228                cls.dir_lock.try_acquire()
1229                # write the class that owns the lock into the lock file
1230                cls.dir_lock.handle.write(cls.__name__)
1231            except IOError as ioerror:
1232                # nothing else should have this directory lock
1233                # wait here until we get a lock
1234                cls.dir_lock.acquire()
1235                # read the previous owner from the lock file
1236                lock_id = cls.dir_lock.handle.read()
1237                print("LOCK ERROR: {} wants to lock '{}' but it is already locked by '{}'".format(cls.__name__, full_dir, lock_id), file=sys.stderr)
1238                raise ioerror
1239
1240        # Set platform context.
1241        if platformIsDarwin():
1242            cls.platformContext = _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
1243        elif getPlatform() == "linux" or getPlatform() == "freebsd":
1244            cls.platformContext = _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
1245        else:
1246            cls.platformContext = None
1247
1248    @classmethod
1249    def tearDownClass(cls):
1250        """
1251        Python unittest framework class teardown fixture.
1252        Do class-wide cleanup.
1253        """
1254
1255        if doCleanup and not lldb.skip_build_and_cleanup:
1256            # First, let's do the platform-specific cleanup.
1257            module = builder_module()
1258            module.cleanup()
1259
1260            # Subclass might have specific cleanup function defined.
1261            if getattr(cls, "classCleanup", None):
1262                if traceAlways:
1263                    print("Call class-specific cleanup function for class:", cls, file=sys.stderr)
1264                try:
1265                    cls.classCleanup()
1266                except:
1267                    exc_type, exc_value, exc_tb = sys.exc_info()
1268                    traceback.print_exception(exc_type, exc_value, exc_tb)
1269
1270        if debug_confirm_directory_exclusivity:
1271            cls.dir_lock.release()
1272            del cls.dir_lock
1273
1274        # Restore old working directory.
1275        if traceAlways:
1276            print("Restore dir to:", cls.oldcwd, file=sys.stderr)
1277        os.chdir(cls.oldcwd)
1278
1279    @classmethod
1280    def skipLongRunningTest(cls):
1281        """
1282        By default, we skip long running test case.
1283        This can be overridden by passing '-l' to the test driver (dotest.py).
1284        """
1285        if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
1286            return False
1287        else:
1288            return True
1289
1290    def enableLogChannelsForCurrentTest(self):
1291        if len(lldbtest_config.channels) == 0:
1292            return
1293
1294        # if debug channels are specified in lldbtest_config.channels,
1295        # create a new set of log files for every test
1296        log_basename = self.getLogBasenameForCurrentTest()
1297
1298        # confirm that the file is writeable
1299        host_log_path = "{}-host.log".format(log_basename)
1300        open(host_log_path, 'w').close()
1301
1302        log_enable = "log enable -Tpn -f {} ".format(host_log_path)
1303        for channel_with_categories in lldbtest_config.channels:
1304            channel_then_categories = channel_with_categories.split(' ', 1)
1305            channel = channel_then_categories[0]
1306            if len(channel_then_categories) > 1:
1307                categories = channel_then_categories[1]
1308            else:
1309                categories = "default"
1310
1311            if channel == "gdb-remote":
1312                # communicate gdb-remote categories to debugserver
1313                os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories
1314
1315            self.ci.HandleCommand(log_enable + channel_with_categories, self.res)
1316            if not self.res.Succeeded():
1317                raise Exception('log enable failed (check LLDB_LOG_OPTION env variable)')
1318
1319        # Communicate log path name to debugserver & lldb-server
1320        server_log_path = "{}-server.log".format(log_basename)
1321        open(server_log_path, 'w').close()
1322        os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
1323
1324        # Communicate channels to lldb-server
1325        os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(lldbtest_config.channels)
1326
1327        if len(lldbtest_config.channels) == 0:
1328            return
1329
1330    def disableLogChannelsForCurrentTest(self):
1331        # close all log files that we opened
1332        for channel_and_categories in lldbtest_config.channels:
1333            # channel format - <channel-name> [<category0> [<category1> ...]]
1334            channel = channel_and_categories.split(' ', 1)[0]
1335            self.ci.HandleCommand("log disable " + channel, self.res)
1336            if not self.res.Succeeded():
1337                raise Exception('log disable failed (check LLDB_LOG_OPTION env variable)')
1338
1339    def setUp(self):
1340        """Fixture for unittest test case setup.
1341
1342        It works with the test driver to conditionally skip tests and does other
1343        initializations."""
1344        #import traceback
1345        #traceback.print_stack()
1346
1347        if "LIBCXX_PATH" in os.environ:
1348            self.libcxxPath = os.environ["LIBCXX_PATH"]
1349        else:
1350            self.libcxxPath = None
1351
1352        if "LLDBMI_EXEC" in os.environ:
1353            self.lldbMiExec = os.environ["LLDBMI_EXEC"]
1354        else:
1355            self.lldbMiExec = None
1356
1357        # If we spawn an lldb process for test (via pexpect), do not load the
1358        # init file unless told otherwise.
1359        if "NO_LLDBINIT" in os.environ and "NO" == os.environ["NO_LLDBINIT"]:
1360            self.lldbOption = ""
1361        else:
1362            self.lldbOption = "--no-lldbinit"
1363
1364        # Assign the test method name to self.testMethodName.
1365        #
1366        # For an example of the use of this attribute, look at test/types dir.
1367        # There are a bunch of test cases under test/types and we don't want the
1368        # module cacheing subsystem to be confused with executable name "a.out"
1369        # used for all the test cases.
1370        self.testMethodName = self._testMethodName
1371
1372        # Benchmarks test is decorated with @benchmarks_test,
1373        # which also sets the "__benchmarks_test__" attribute of the
1374        # function object to True.
1375        try:
1376            if lldb.just_do_benchmarks_test:
1377                testMethod = getattr(self, self._testMethodName)
1378                if getattr(testMethod, "__benchmarks_test__", False):
1379                    pass
1380                else:
1381                    self.skipTest("non benchmarks test")
1382        except AttributeError:
1383            pass
1384
1385        # This is for the case of directly spawning 'lldb'/'gdb' and interacting
1386        # with it using pexpect.
1387        self.child = None
1388        self.child_prompt = "(lldb) "
1389        # If the child is interacting with the embedded script interpreter,
1390        # there are two exits required during tear down, first to quit the
1391        # embedded script interpreter and second to quit the lldb command
1392        # interpreter.
1393        self.child_in_script_interpreter = False
1394
1395        # These are for customized teardown cleanup.
1396        self.dict = None
1397        self.doTearDownCleanup = False
1398        # And in rare cases where there are multiple teardown cleanups.
1399        self.dicts = []
1400        self.doTearDownCleanups = False
1401
1402        # List of spawned subproces.Popen objects
1403        self.subprocesses = []
1404
1405        # List of forked process PIDs
1406        self.forkedProcessPids = []
1407
1408        # Create a string buffer to record the session info, to be dumped into a
1409        # test case specific file if test failure is encountered.
1410        self.log_basename = self.getLogBasenameForCurrentTest()
1411
1412        session_file = "{}.log".format(self.log_basename)
1413        unbuffered = 0 # 0 is the constant for unbuffered
1414        self.session = open(session_file, "w", unbuffered)
1415
1416        # Optimistically set __errored__, __failed__, __expected__ to False
1417        # initially.  If the test errored/failed, the session info
1418        # (self.session) is then dumped into a session specific file for
1419        # diagnosis.
1420        self.__cleanup_errored__ = False
1421        self.__errored__    = False
1422        self.__failed__     = False
1423        self.__expected__   = False
1424        # We are also interested in unexpected success.
1425        self.__unexpected__ = False
1426        # And skipped tests.
1427        self.__skipped__ = False
1428
1429        # See addTearDownHook(self, hook) which allows the client to add a hook
1430        # function to be run during tearDown() time.
1431        self.hooks = []
1432
1433        # See HideStdout(self).
1434        self.sys_stdout_hidden = False
1435
1436        if self.platformContext:
1437            # set environment variable names for finding shared libraries
1438            self.dylibPath = self.platformContext.shlib_environment_var
1439
1440        # Create the debugger instance if necessary.
1441        try:
1442            self.dbg = lldb.DBG
1443        except AttributeError:
1444            self.dbg = lldb.SBDebugger.Create()
1445
1446        if not self.dbg:
1447            raise Exception('Invalid debugger instance')
1448
1449        # Retrieve the associated command interpreter instance.
1450        self.ci = self.dbg.GetCommandInterpreter()
1451        if not self.ci:
1452            raise Exception('Could not get the command interpreter')
1453
1454        # And the result object.
1455        self.res = lldb.SBCommandReturnObject()
1456
1457        self.enableLogChannelsForCurrentTest()
1458
1459    def runHooks(self, child=None, child_prompt=None, use_cmd_api=False):
1460        """Perform the run hooks to bring lldb debugger to the desired state.
1461
1462        By default, expect a pexpect spawned child and child prompt to be
1463        supplied (use_cmd_api=False).  If use_cmd_api is true, ignore the child
1464        and child prompt and use self.runCmd() to run the hooks one by one.
1465
1466        Note that child is a process spawned by pexpect.spawn().  If not, your
1467        test case is mostly likely going to fail.
1468
1469        See also dotest.py where lldb.runHooks are processed/populated.
1470        """
1471        if not lldb.runHooks:
1472            self.skipTest("No runhooks specified for lldb, skip the test")
1473        if use_cmd_api:
1474            for hook in lldb.runhooks:
1475                self.runCmd(hook)
1476        else:
1477            if not child or not child_prompt:
1478                self.fail("Both child and child_prompt need to be defined.")
1479            for hook in lldb.runHooks:
1480                child.sendline(hook)
1481                child.expect_exact(child_prompt)
1482
1483    def setAsync(self, value):
1484        """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
1485        old_async = self.dbg.GetAsync()
1486        self.dbg.SetAsync(value)
1487        self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
1488
1489    def cleanupSubprocesses(self):
1490        # Ensure any subprocesses are cleaned up
1491        for p in self.subprocesses:
1492            p.terminate()
1493            del p
1494        del self.subprocesses[:]
1495        # Ensure any forked processes are cleaned up
1496        for pid in self.forkedProcessPids:
1497            if os.path.exists("/proc/" + str(pid)):
1498                os.kill(pid, signal.SIGTERM)
1499
1500    def spawnSubprocess(self, executable, args=[], install_remote=True):
1501        """ Creates a subprocess.Popen object with the specified executable and arguments,
1502            saves it in self.subprocesses, and returns the object.
1503            NOTE: if using this function, ensure you also call:
1504
1505              self.addTearDownHook(self.cleanupSubprocesses)
1506
1507            otherwise the test suite will leak processes.
1508        """
1509        proc = _RemoteProcess(install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
1510        proc.launch(executable, args)
1511        self.subprocesses.append(proc)
1512        return proc
1513
1514    def forkSubprocess(self, executable, args=[]):
1515        """ Fork a subprocess with its own group ID.
1516            NOTE: if using this function, ensure you also call:
1517
1518              self.addTearDownHook(self.cleanupSubprocesses)
1519
1520            otherwise the test suite will leak processes.
1521        """
1522        child_pid = os.fork()
1523        if child_pid == 0:
1524            # If more I/O support is required, this can be beefed up.
1525            fd = os.open(os.devnull, os.O_RDWR)
1526            os.dup2(fd, 1)
1527            os.dup2(fd, 2)
1528            # This call causes the child to have its of group ID
1529            os.setpgid(0,0)
1530            os.execvp(executable, [executable] + args)
1531        # Give the child time to get through the execvp() call
1532        time.sleep(0.1)
1533        self.forkedProcessPids.append(child_pid)
1534        return child_pid
1535
1536    def HideStdout(self):
1537        """Hide output to stdout from the user.
1538
1539        During test execution, there might be cases where we don't want to show the
1540        standard output to the user.  For example,
1541
1542            self.runCmd(r'''sc print("\n\n\tHello!\n")''')
1543
1544        tests whether command abbreviation for 'script' works or not.  There is no
1545        need to show the 'Hello' output to the user as long as the 'script' command
1546        succeeds and we are not in TraceOn() mode (see the '-t' option).
1547
1548        In this case, the test method calls self.HideStdout(self) to redirect the
1549        sys.stdout to a null device, and restores the sys.stdout upon teardown.
1550
1551        Note that you should only call this method at most once during a test case
1552        execution.  Any subsequent call has no effect at all."""
1553        if self.sys_stdout_hidden:
1554            return
1555
1556        self.sys_stdout_hidden = True
1557        old_stdout = sys.stdout
1558        sys.stdout = open(os.devnull, 'w')
1559        def restore_stdout():
1560            sys.stdout = old_stdout
1561        self.addTearDownHook(restore_stdout)
1562
1563    # =======================================================================
1564    # Methods for customized teardown cleanups as well as execution of hooks.
1565    # =======================================================================
1566
1567    def setTearDownCleanup(self, dictionary=None):
1568        """Register a cleanup action at tearDown() time with a dictinary"""
1569        self.dict = dictionary
1570        self.doTearDownCleanup = True
1571
1572    def addTearDownCleanup(self, dictionary):
1573        """Add a cleanup action at tearDown() time with a dictinary"""
1574        self.dicts.append(dictionary)
1575        self.doTearDownCleanups = True
1576
1577    def addTearDownHook(self, hook):
1578        """
1579        Add a function to be run during tearDown() time.
1580
1581        Hooks are executed in a first come first serve manner.
1582        """
1583        if six.callable(hook):
1584            with recording(self, traceAlways) as sbuf:
1585                print("Adding tearDown hook:", getsource_if_available(hook), file=sbuf)
1586            self.hooks.append(hook)
1587
1588        return self
1589
1590    def deletePexpectChild(self):
1591        # This is for the case of directly spawning 'lldb' and interacting with it
1592        # using pexpect.
1593        if self.child and self.child.isalive():
1594            import pexpect
1595            with recording(self, traceAlways) as sbuf:
1596                print("tearing down the child process....", file=sbuf)
1597            try:
1598                if self.child_in_script_interpreter:
1599                    self.child.sendline('quit()')
1600                    self.child.expect_exact(self.child_prompt)
1601                self.child.sendline('settings set interpreter.prompt-on-quit false')
1602                self.child.sendline('quit')
1603                self.child.expect(pexpect.EOF)
1604            except (ValueError, pexpect.ExceptionPexpect):
1605                # child is already terminated
1606                pass
1607            except OSError as exception:
1608                import errno
1609                if exception.errno != errno.EIO:
1610                    # unexpected error
1611                    raise
1612                # child is already terminated
1613                pass
1614            finally:
1615                # Give it one final blow to make sure the child is terminated.
1616                self.child.close()
1617
1618    def tearDown(self):
1619        """Fixture for unittest test case teardown."""
1620        #import traceback
1621        #traceback.print_stack()
1622
1623        self.deletePexpectChild()
1624
1625        # Check and run any hook functions.
1626        for hook in reversed(self.hooks):
1627            with recording(self, traceAlways) as sbuf:
1628                print("Executing tearDown hook:", getsource_if_available(hook), file=sbuf)
1629            import inspect
1630            hook_argc = len(inspect.getargspec(hook).args)
1631            if hook_argc == 0 or getattr(hook,'im_self',None):
1632                hook()
1633            elif hook_argc == 1:
1634                hook(self)
1635            else:
1636                hook() # try the plain call and hope it works
1637
1638        del self.hooks
1639
1640        # Perform registered teardown cleanup.
1641        if doCleanup and self.doTearDownCleanup:
1642            self.cleanup(dictionary=self.dict)
1643
1644        # In rare cases where there are multiple teardown cleanups added.
1645        if doCleanup and self.doTearDownCleanups:
1646            if self.dicts:
1647                for dict in reversed(self.dicts):
1648                    self.cleanup(dictionary=dict)
1649
1650        self.disableLogChannelsForCurrentTest()
1651
1652    # =========================================================
1653    # Various callbacks to allow introspection of test progress
1654    # =========================================================
1655
1656    def markError(self):
1657        """Callback invoked when an error (unexpected exception) errored."""
1658        self.__errored__ = True
1659        with recording(self, False) as sbuf:
1660            # False because there's no need to write "ERROR" to the stderr twice.
1661            # Once by the Python unittest framework, and a second time by us.
1662            print("ERROR", file=sbuf)
1663
1664    def markCleanupError(self):
1665        """Callback invoked when an error occurs while a test is cleaning up."""
1666        self.__cleanup_errored__ = True
1667        with recording(self, False) as sbuf:
1668            # False because there's no need to write "CLEANUP_ERROR" to the stderr twice.
1669            # Once by the Python unittest framework, and a second time by us.
1670            print("CLEANUP_ERROR", file=sbuf)
1671
1672    def markFailure(self):
1673        """Callback invoked when a failure (test assertion failure) occurred."""
1674        self.__failed__ = True
1675        with recording(self, False) as sbuf:
1676            # False because there's no need to write "FAIL" to the stderr twice.
1677            # Once by the Python unittest framework, and a second time by us.
1678            print("FAIL", file=sbuf)
1679
1680    def markExpectedFailure(self,err,bugnumber):
1681        """Callback invoked when an expected failure/error occurred."""
1682        self.__expected__ = True
1683        with recording(self, False) as sbuf:
1684            # False because there's no need to write "expected failure" to the
1685            # stderr twice.
1686            # Once by the Python unittest framework, and a second time by us.
1687            if bugnumber == None:
1688                print("expected failure", file=sbuf)
1689            else:
1690                print("expected failure (problem id:" + str(bugnumber) + ")", file=sbuf)
1691
1692    def markSkippedTest(self):
1693        """Callback invoked when a test is skipped."""
1694        self.__skipped__ = True
1695        with recording(self, False) as sbuf:
1696            # False because there's no need to write "skipped test" to the
1697            # stderr twice.
1698            # Once by the Python unittest framework, and a second time by us.
1699            print("skipped test", file=sbuf)
1700
1701    def markUnexpectedSuccess(self, bugnumber):
1702        """Callback invoked when an unexpected success occurred."""
1703        self.__unexpected__ = True
1704        with recording(self, False) as sbuf:
1705            # False because there's no need to write "unexpected success" to the
1706            # stderr twice.
1707            # Once by the Python unittest framework, and a second time by us.
1708            if bugnumber == None:
1709                print("unexpected success", file=sbuf)
1710            else:
1711                print("unexpected success (problem id:" + str(bugnumber) + ")", file=sbuf)
1712
1713    def getRerunArgs(self):
1714        return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
1715
1716    def getLogBasenameForCurrentTest(self, prefix=None):
1717        """
1718        returns a partial path that can be used as the beginning of the name of multiple
1719        log files pertaining to this test
1720
1721        <session-dir>/<arch>-<compiler>-<test-file>.<test-class>.<test-method>
1722        """
1723        dname = os.path.join(os.environ["LLDB_TEST"],
1724                     os.environ["LLDB_SESSION_DIRNAME"])
1725        if not os.path.isdir(dname):
1726            os.mkdir(dname)
1727
1728        compiler = self.getCompiler()
1729
1730        if compiler[1] == ':':
1731            compiler = compiler[2:]
1732        if os.path.altsep is not None:
1733            compiler = compiler.replace(os.path.altsep, os.path.sep)
1734
1735        fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), "_".join(compiler.split(os.path.sep)))
1736        if len(fname) > 200:
1737            fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), compiler.split(os.path.sep)[-1])
1738
1739        if prefix is not None:
1740            fname = "{}-{}".format(prefix, fname)
1741
1742        return os.path.join(dname, fname)
1743
1744    def dumpSessionInfo(self):
1745        """
1746        Dump the debugger interactions leading to a test error/failure.  This
1747        allows for more convenient postmortem analysis.
1748
1749        See also LLDBTestResult (dotest.py) which is a singlton class derived
1750        from TextTestResult and overwrites addError, addFailure, and
1751        addExpectedFailure methods to allow us to to mark the test instance as
1752        such.
1753        """
1754
1755        # We are here because self.tearDown() detected that this test instance
1756        # either errored or failed.  The lldb.test_result singleton contains
1757        # two lists (erros and failures) which get populated by the unittest
1758        # framework.  Look over there for stack trace information.
1759        #
1760        # The lists contain 2-tuples of TestCase instances and strings holding
1761        # formatted tracebacks.
1762        #
1763        # See http://docs.python.org/library/unittest.html#unittest.TestResult.
1764
1765        # output tracebacks into session
1766        pairs = []
1767        if self.__errored__:
1768            pairs = lldb.test_result.errors
1769            prefix = 'Error'
1770        elif self.__cleanup_errored__:
1771            pairs = lldb.test_result.cleanup_errors
1772            prefix = 'CleanupError'
1773        elif self.__failed__:
1774            pairs = lldb.test_result.failures
1775            prefix = 'Failure'
1776        elif self.__expected__:
1777            pairs = lldb.test_result.expectedFailures
1778            prefix = 'ExpectedFailure'
1779        elif self.__skipped__:
1780            prefix = 'SkippedTest'
1781        elif self.__unexpected__:
1782            prefix = 'UnexpectedSuccess'
1783        else:
1784            prefix = 'Success'
1785
1786        if not self.__unexpected__ and not self.__skipped__:
1787            for test, traceback in pairs:
1788                if test is self:
1789                    print(traceback, file=self.session)
1790
1791        # put footer (timestamp/rerun instructions) into session
1792        testMethod = getattr(self, self._testMethodName)
1793        if getattr(testMethod, "__benchmarks_test__", False):
1794            benchmarks = True
1795        else:
1796            benchmarks = False
1797
1798        import datetime
1799        print("Session info generated @", datetime.datetime.now().ctime(), file=self.session)
1800        print("To rerun this test, issue the following command from the 'test' directory:\n", file=self.session)
1801        print("./dotest.py %s -v %s %s" % (self.getRunOptions(),
1802                                                 ('+b' if benchmarks else '-t'),
1803                                                 self.getRerunArgs()), file=self.session)
1804        self.session.close()
1805        del self.session
1806
1807        # process the log files
1808        log_files_for_this_test = glob.glob(self.log_basename + "*")
1809
1810        if prefix != 'Success' or lldbtest_config.log_success:
1811            # keep all log files, rename them to include prefix
1812            dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
1813            for src in log_files_for_this_test:
1814                if os.path.isfile(src):
1815                    dst = src.replace(self.log_basename, dst_log_basename)
1816                    if os.name == "nt" and os.path.isfile(dst):
1817                        # On Windows, renaming a -> b will throw an exception if b exists.  On non-Windows platforms
1818                        # it silently replaces the destination.  Ultimately this means that atomic renames are not
1819                        # guaranteed to be possible on Windows, but we need this to work anyway, so just remove the
1820                        # destination first if it already exists.
1821                        os.remove(dst)
1822
1823                    os.rename(src, dst)
1824        else:
1825            # success!  (and we don't want log files) delete log files
1826            for log_file in log_files_for_this_test:
1827                try:
1828                    os.unlink(log_file)
1829                except:
1830                    # We've seen consistent unlink failures on Windows, perhaps because the
1831                    # just-created log file is being scanned by anti-virus.  Empirically, this
1832                    # sleep-and-retry approach allows tests to succeed much more reliably.
1833                    # Attempts to figure out exactly what process was still holding a file handle
1834                    # have failed because running instrumentation like Process Monitor seems to
1835                    # slow things down enough that the problem becomes much less consistent.
1836                    time.sleep(0.5)
1837                    os.unlink(log_file)
1838
1839    # ====================================================
1840    # Config. methods supported through a plugin interface
1841    # (enables reading of the current test configuration)
1842    # ====================================================
1843
1844    def getArchitecture(self):
1845        """Returns the architecture in effect the test suite is running with."""
1846        module = builder_module()
1847        arch = module.getArchitecture()
1848        if arch == 'amd64':
1849            arch = 'x86_64'
1850        return arch
1851
1852    def getLldbArchitecture(self):
1853        """Returns the architecture of the lldb binary."""
1854        if not hasattr(self, 'lldbArchitecture'):
1855
1856            # spawn local process
1857            command = [
1858                lldbtest_config.lldbExec,
1859                "-o",
1860                "file " + lldbtest_config.lldbExec,
1861                "-o",
1862                "quit"
1863            ]
1864
1865            output = check_output(command)
1866            str = output.decode("utf-8");
1867
1868            for line in str.splitlines():
1869                m = re.search("Current executable set to '.*' \\((.*)\\)\\.", line)
1870                if m:
1871                    self.lldbArchitecture = m.group(1)
1872                    break
1873
1874        return self.lldbArchitecture
1875
1876    def getCompiler(self):
1877        """Returns the compiler in effect the test suite is running with."""
1878        module = builder_module()
1879        return module.getCompiler()
1880
1881    def getCompilerBinary(self):
1882        """Returns the compiler binary the test suite is running with."""
1883        return self.getCompiler().split()[0]
1884
1885    def getCompilerVersion(self):
1886        """ Returns a string that represents the compiler version.
1887            Supports: llvm, clang.
1888        """
1889        from lldbutil import which
1890        version = 'unknown'
1891
1892        compiler = self.getCompilerBinary()
1893        version_output = system([[which(compiler), "-v"]])[1]
1894        for line in version_output.split(os.linesep):
1895            m = re.search('version ([0-9\.]+)', line)
1896            if m:
1897                version = m.group(1)
1898        return version
1899
1900    def getGoCompilerVersion(self):
1901        """ Returns a string that represents the go compiler version, or None if go is not found.
1902        """
1903        compiler = which("go")
1904        if compiler:
1905            version_output = system([[compiler, "version"]])[0]
1906            for line in version_output.split(os.linesep):
1907                m = re.search('go version (devel|go\\S+)', line)
1908                if m:
1909                    return m.group(1)
1910        return None
1911
1912    def platformIsDarwin(self):
1913        """Returns true if the OS triple for the selected platform is any valid apple OS"""
1914        return platformIsDarwin()
1915
1916    def getPlatform(self):
1917        """Returns the target platform the test suite is running on."""
1918        return getPlatform()
1919
1920    def isIntelCompiler(self):
1921        """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1922        return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1923
1924    def expectedCompilerVersion(self, compiler_version):
1925        """Returns True iff compiler_version[1] matches the current compiler version.
1926           Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1927           Any operator other than the following defaults to an equality test:
1928             '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1929        """
1930        if (compiler_version == None):
1931            return True
1932        operator = str(compiler_version[0])
1933        version = compiler_version[1]
1934
1935        if (version == None):
1936            return True
1937        if (operator == '>'):
1938            return self.getCompilerVersion() > version
1939        if (operator == '>=' or operator == '=>'):
1940            return self.getCompilerVersion() >= version
1941        if (operator == '<'):
1942            return self.getCompilerVersion() < version
1943        if (operator == '<=' or operator == '=<'):
1944            return self.getCompilerVersion() <= version
1945        if (operator == '!=' or operator == '!' or operator == 'not'):
1946            return str(version) not in str(self.getCompilerVersion())
1947        return str(version) in str(self.getCompilerVersion())
1948
1949    def expectedCompiler(self, compilers):
1950        """Returns True iff any element of compilers is a sub-string of the current compiler."""
1951        if (compilers == None):
1952            return True
1953
1954        for compiler in compilers:
1955            if compiler in self.getCompiler():
1956                return True
1957
1958        return False
1959
1960    def expectedArch(self, archs):
1961        """Returns True iff any element of archs is a sub-string of the current architecture."""
1962        if (archs == None):
1963            return True
1964
1965        for arch in archs:
1966            if arch in self.getArchitecture():
1967                return True
1968
1969        return False
1970
1971    def getRunOptions(self):
1972        """Command line option for -A and -C to run this test again, called from
1973        self.dumpSessionInfo()."""
1974        arch = self.getArchitecture()
1975        comp = self.getCompiler()
1976        if arch:
1977            option_str = "-A " + arch
1978        else:
1979            option_str = ""
1980        if comp:
1981            option_str += " -C " + comp
1982        return option_str
1983
1984    # ==================================================
1985    # Build methods supported through a plugin interface
1986    # ==================================================
1987
1988    def getstdlibFlag(self):
1989        """ Returns the proper -stdlib flag, or empty if not required."""
1990        if self.platformIsDarwin() or self.getPlatform() == "freebsd":
1991            stdlibflag = "-stdlib=libc++"
1992        else:
1993            stdlibflag = ""
1994        return stdlibflag
1995
1996    def getstdFlag(self):
1997        """ Returns the proper stdflag. """
1998        if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
1999          stdflag = "-std=c++0x"
2000        else:
2001          stdflag = "-std=c++11"
2002        return stdflag
2003
2004    def buildDriver(self, sources, exe_name):
2005        """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
2006            or LLDB.framework).
2007        """
2008
2009        stdflag = self.getstdFlag()
2010        stdlibflag = self.getstdlibFlag()
2011
2012        lib_dir = os.environ["LLDB_LIB_DIR"]
2013        if sys.platform.startswith("darwin"):
2014            dsym = os.path.join(lib_dir, 'LLDB.framework', 'LLDB')
2015            d = {'CXX_SOURCES' : sources,
2016                 'EXE' : exe_name,
2017                 'CFLAGS_EXTRAS' : "%s %s" % (stdflag, stdlibflag),
2018                 'FRAMEWORK_INCLUDES' : "-F%s" % lib_dir,
2019                 'LD_EXTRAS' : "%s -Wl,-rpath,%s" % (dsym, lib_dir),
2020                }
2021        elif sys.platform.startswith('freebsd') or sys.platform.startswith("linux") or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
2022            d = {'CXX_SOURCES' : sources,
2023                 'EXE' : exe_name,
2024                 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2025                 'LD_EXTRAS' : "-L%s -llldb" % lib_dir}
2026        elif sys.platform.startswith('win'):
2027            d = {'CXX_SOURCES' : sources,
2028                 'EXE' : exe_name,
2029                 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2030                 'LD_EXTRAS' : "-L%s -lliblldb" % os.environ["LLDB_IMPLIB_DIR"]}
2031        if self.TraceOn():
2032            print("Building LLDB Driver (%s) from sources %s" % (exe_name, sources))
2033
2034        self.buildDefault(dictionary=d)
2035
2036    def buildLibrary(self, sources, lib_name):
2037        """Platform specific way to build a default library. """
2038
2039        stdflag = self.getstdFlag()
2040
2041        lib_dir = os.environ["LLDB_LIB_DIR"]
2042        if self.platformIsDarwin():
2043            dsym = os.path.join(lib_dir, 'LLDB.framework', 'LLDB')
2044            d = {'DYLIB_CXX_SOURCES' : sources,
2045                 'DYLIB_NAME' : lib_name,
2046                 'CFLAGS_EXTRAS' : "%s -stdlib=libc++" % stdflag,
2047                 'FRAMEWORK_INCLUDES' : "-F%s" % lib_dir,
2048                 'LD_EXTRAS' : "%s -Wl,-rpath,%s -dynamiclib" % (dsym, lib_dir),
2049                }
2050        elif self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux' or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
2051            d = {'DYLIB_CXX_SOURCES' : sources,
2052                 'DYLIB_NAME' : lib_name,
2053                 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2054                 'LD_EXTRAS' : "-shared -L%s -llldb" % lib_dir}
2055        elif self.getPlatform() == 'windows':
2056            d = {'DYLIB_CXX_SOURCES' : sources,
2057                 'DYLIB_NAME' : lib_name,
2058                 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2059                 'LD_EXTRAS' : "-shared -l%s\liblldb.lib" % self.os.environ["LLDB_IMPLIB_DIR"]}
2060        if self.TraceOn():
2061            print("Building LLDB Library (%s) from sources %s" % (lib_name, sources))
2062
2063        self.buildDefault(dictionary=d)
2064
2065    def buildProgram(self, sources, exe_name):
2066        """ Platform specific way to build an executable from C/C++ sources. """
2067        d = {'CXX_SOURCES' : sources,
2068             'EXE' : exe_name}
2069        self.buildDefault(dictionary=d)
2070
2071    def buildDefault(self, architecture=None, compiler=None, dictionary=None, clean=True):
2072        """Platform specific way to build the default binaries."""
2073        if lldb.skip_build_and_cleanup:
2074            return
2075        module = builder_module()
2076        if target_is_android():
2077            dictionary = append_android_envs(dictionary)
2078        if not module.buildDefault(self, architecture, compiler, dictionary, clean):
2079            raise Exception("Don't know how to build default binary")
2080
2081    def buildDsym(self, architecture=None, compiler=None, dictionary=None, clean=True):
2082        """Platform specific way to build binaries with dsym info."""
2083        if lldb.skip_build_and_cleanup:
2084            return
2085        module = builder_module()
2086        if not module.buildDsym(self, architecture, compiler, dictionary, clean):
2087            raise Exception("Don't know how to build binary with dsym")
2088
2089    def buildDwarf(self, architecture=None, compiler=None, dictionary=None, clean=True):
2090        """Platform specific way to build binaries with dwarf maps."""
2091        if lldb.skip_build_and_cleanup:
2092            return
2093        module = builder_module()
2094        if target_is_android():
2095            dictionary = append_android_envs(dictionary)
2096        if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
2097            raise Exception("Don't know how to build binary with dwarf")
2098
2099    def buildDwo(self, architecture=None, compiler=None, dictionary=None, clean=True):
2100        """Platform specific way to build binaries with dwarf maps."""
2101        if lldb.skip_build_and_cleanup:
2102            return
2103        module = builder_module()
2104        if target_is_android():
2105            dictionary = append_android_envs(dictionary)
2106        if not module.buildDwo(self, architecture, compiler, dictionary, clean):
2107            raise Exception("Don't know how to build binary with dwo")
2108
2109    def buildGo(self):
2110        """Build the default go binary.
2111        """
2112        system([[which('go'), 'build -gcflags "-N -l" -o a.out main.go']])
2113
2114    def signBinary(self, binary_path):
2115        if sys.platform.startswith("darwin"):
2116            codesign_cmd = "codesign --force --sign lldb_codesign %s" % (binary_path)
2117            call(codesign_cmd, shell=True)
2118
2119    def findBuiltClang(self):
2120        """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
2121        paths_to_try = [
2122          "llvm-build/Release+Asserts/x86_64/Release+Asserts/bin/clang",
2123          "llvm-build/Debug+Asserts/x86_64/Debug+Asserts/bin/clang",
2124          "llvm-build/Release/x86_64/Release/bin/clang",
2125          "llvm-build/Debug/x86_64/Debug/bin/clang",
2126        ]
2127        lldb_root_path = os.path.join(os.path.dirname(__file__), "..")
2128        for p in paths_to_try:
2129            path = os.path.join(lldb_root_path, p)
2130            if os.path.exists(path):
2131                return path
2132
2133        # Tries to find clang at the same folder as the lldb
2134        path = os.path.join(os.path.dirname(lldbtest_config.lldbExec), "clang")
2135        if os.path.exists(path):
2136            return path
2137
2138        return os.environ["CC"]
2139
2140    def getBuildFlags(self, use_cpp11=True, use_libcxx=False, use_libstdcxx=False):
2141        """ Returns a dictionary (which can be provided to build* functions above) which
2142            contains OS-specific build flags.
2143        """
2144        cflags = ""
2145        ldflags = ""
2146
2147        # On Mac OS X, unless specifically requested to use libstdc++, use libc++
2148        if not use_libstdcxx and self.platformIsDarwin():
2149            use_libcxx = True
2150
2151        if use_libcxx and self.libcxxPath:
2152            cflags += "-stdlib=libc++ "
2153            if self.libcxxPath:
2154                libcxxInclude = os.path.join(self.libcxxPath, "include")
2155                libcxxLib = os.path.join(self.libcxxPath, "lib")
2156                if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
2157                    cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (libcxxInclude, libcxxLib, libcxxLib)
2158
2159        if use_cpp11:
2160            cflags += "-std="
2161            if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
2162                cflags += "c++0x"
2163            else:
2164                cflags += "c++11"
2165        if self.platformIsDarwin() or self.getPlatform() == "freebsd":
2166            cflags += " -stdlib=libc++"
2167        elif "clang" in self.getCompiler():
2168            cflags += " -stdlib=libstdc++"
2169
2170        return {'CFLAGS_EXTRAS' : cflags,
2171                'LD_EXTRAS' : ldflags,
2172               }
2173
2174    def cleanup(self, dictionary=None):
2175        """Platform specific way to do cleanup after build."""
2176        if lldb.skip_build_and_cleanup:
2177            return
2178        module = builder_module()
2179        if not module.cleanup(self, dictionary):
2180            raise Exception("Don't know how to do cleanup with dictionary: "+dictionary)
2181
2182    def getLLDBLibraryEnvVal(self):
2183        """ Returns the path that the OS-specific library search environment variable
2184            (self.dylibPath) should be set to in order for a program to find the LLDB
2185            library. If an environment variable named self.dylibPath is already set,
2186            the new path is appended to it and returned.
2187        """
2188        existing_library_path = os.environ[self.dylibPath] if self.dylibPath in os.environ else None
2189        lib_dir = os.environ["LLDB_LIB_DIR"]
2190        if existing_library_path:
2191            return "%s:%s" % (existing_library_path, lib_dir)
2192        elif sys.platform.startswith("darwin"):
2193            return os.path.join(lib_dir, 'LLDB.framework')
2194        else:
2195            return lib_dir
2196
2197    def getLibcPlusPlusLibs(self):
2198        if self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux':
2199            return ['libc++.so.1']
2200        else:
2201            return ['libc++.1.dylib','libc++abi.dylib']
2202
2203# Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
2204# We change the test methods to create a new test method for each test for each debug info we are
2205# testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
2206# the new test method we remove the old method at the same time.
2207class LLDBTestCaseFactory(type):
2208    def __new__(cls, name, bases, attrs):
2209        newattrs = {}
2210        for attrname, attrvalue in attrs.items():
2211            if attrname.startswith("test") and not getattr(attrvalue, "__no_debug_info_test__", False):
2212                @dsym_test
2213                @wraps(attrvalue)
2214                def dsym_test_method(self, attrvalue=attrvalue):
2215                    self.debug_info = "dsym"
2216                    return attrvalue(self)
2217                dsym_method_name = attrname + "_dsym"
2218                dsym_test_method.__name__ = dsym_method_name
2219                newattrs[dsym_method_name] = dsym_test_method
2220
2221                @dwarf_test
2222                @wraps(attrvalue)
2223                def dwarf_test_method(self, attrvalue=attrvalue):
2224                    self.debug_info = "dwarf"
2225                    return attrvalue(self)
2226                dwarf_method_name = attrname + "_dwarf"
2227                dwarf_test_method.__name__ = dwarf_method_name
2228                newattrs[dwarf_method_name] = dwarf_test_method
2229
2230                @dwo_test
2231                @wraps(attrvalue)
2232                def dwo_test_method(self, attrvalue=attrvalue):
2233                    self.debug_info = "dwo"
2234                    return attrvalue(self)
2235                dwo_method_name = attrname + "_dwo"
2236                dwo_test_method.__name__ = dwo_method_name
2237                newattrs[dwo_method_name] = dwo_test_method
2238            else:
2239                newattrs[attrname] = attrvalue
2240        return super(LLDBTestCaseFactory, cls).__new__(cls, name, bases, newattrs)
2241
2242# Setup the metaclass for this class to change the list of the test methods when a new class is loaded
2243@add_metaclass(LLDBTestCaseFactory)
2244class TestBase(Base):
2245    """
2246    This abstract base class is meant to be subclassed.  It provides default
2247    implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
2248    among other things.
2249
2250    Important things for test class writers:
2251
2252        - Overwrite the mydir class attribute, otherwise your test class won't
2253          run.  It specifies the relative directory to the top level 'test' so
2254          the test harness can change to the correct working directory before
2255          running your test.
2256
2257        - The setUp method sets up things to facilitate subsequent interactions
2258          with the debugger as part of the test.  These include:
2259              - populate the test method name
2260              - create/get a debugger set with synchronous mode (self.dbg)
2261              - get the command interpreter from with the debugger (self.ci)
2262              - create a result object for use with the command interpreter
2263                (self.res)
2264              - plus other stuffs
2265
2266        - The tearDown method tries to perform some necessary cleanup on behalf
2267          of the test to return the debugger to a good state for the next test.
2268          These include:
2269              - execute any tearDown hooks registered by the test method with
2270                TestBase.addTearDownHook(); examples can be found in
2271                settings/TestSettings.py
2272              - kill the inferior process associated with each target, if any,
2273                and, then delete the target from the debugger's target list
2274              - perform build cleanup before running the next test method in the
2275                same test class; examples of registering for this service can be
2276                found in types/TestIntegerTypes.py with the call:
2277                    - self.setTearDownCleanup(dictionary=d)
2278
2279        - Similarly setUpClass and tearDownClass perform classwise setup and
2280          teardown fixtures.  The tearDownClass method invokes a default build
2281          cleanup for the entire test class;  also, subclasses can implement the
2282          classmethod classCleanup(cls) to perform special class cleanup action.
2283
2284        - The instance methods runCmd and expect are used heavily by existing
2285          test cases to send a command to the command interpreter and to perform
2286          string/pattern matching on the output of such command execution.  The
2287          expect method also provides a mode to peform string/pattern matching
2288          without running a command.
2289
2290        - The build methods buildDefault, buildDsym, and buildDwarf are used to
2291          build the binaries used during a particular test scenario.  A plugin
2292          should be provided for the sys.platform running the test suite.  The
2293          Mac OS X implementation is located in plugins/darwin.py.
2294    """
2295
2296    # Maximum allowed attempts when launching the inferior process.
2297    # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
2298    maxLaunchCount = 3;
2299
2300    # Time to wait before the next launching attempt in second(s).
2301    # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
2302    timeWaitNextLaunch = 1.0;
2303
2304    def doDelay(self):
2305        """See option -w of dotest.py."""
2306        if ("LLDB_WAIT_BETWEEN_TEST_CASES" in os.environ and
2307            os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] == 'YES'):
2308            waitTime = 1.0
2309            if "LLDB_TIME_WAIT_BETWEEN_TEST_CASES" in os.environ:
2310                waitTime = float(os.environ["LLDB_TIME_WAIT_BETWEEN_TEST_CASES"])
2311            time.sleep(waitTime)
2312
2313    # Returns the list of categories to which this test case belongs
2314    # by default, look for a ".categories" file, and read its contents
2315    # if no such file exists, traverse the hierarchy - we guarantee
2316    # a .categories to exist at the top level directory so we do not end up
2317    # looping endlessly - subclasses are free to define their own categories
2318    # in whatever way makes sense to them
2319    def getCategories(self):
2320        import inspect
2321        import os.path
2322        folder = inspect.getfile(self.__class__)
2323        folder = os.path.dirname(folder)
2324        while folder != '/':
2325                categories_file_name = os.path.join(folder,".categories")
2326                if os.path.exists(categories_file_name):
2327                        categories_file = open(categories_file_name,'r')
2328                        categories = categories_file.readline()
2329                        categories_file.close()
2330                        categories = str.replace(categories,'\n','')
2331                        categories = str.replace(categories,'\r','')
2332                        return categories.split(',')
2333                else:
2334                        folder = os.path.dirname(folder)
2335                        continue
2336
2337    def setUp(self):
2338        #import traceback
2339        #traceback.print_stack()
2340
2341        # Works with the test driver to conditionally skip tests via decorators.
2342        Base.setUp(self)
2343
2344        try:
2345            if lldb.blacklist:
2346                className = self.__class__.__name__
2347                classAndMethodName = "%s.%s" % (className, self._testMethodName)
2348                if className in lldb.blacklist:
2349                    self.skipTest(lldb.blacklist.get(className))
2350                elif classAndMethodName in lldb.blacklist:
2351                    self.skipTest(lldb.blacklist.get(classAndMethodName))
2352        except AttributeError:
2353            pass
2354
2355        # Insert some delay between successive test cases if specified.
2356        self.doDelay()
2357
2358        if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
2359            self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
2360
2361        if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
2362            self.timeWaitNextLaunch = float(os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
2363
2364        #
2365        # Warning: MAJOR HACK AHEAD!
2366        # If we are running testsuite remotely (by checking lldb.lldbtest_remote_sandbox),
2367        # redefine the self.dbg.CreateTarget(filename) method to execute a "file filename"
2368        # command, instead.  See also runCmd() where it decorates the "file filename" call
2369        # with additional functionality when running testsuite remotely.
2370        #
2371        if lldb.lldbtest_remote_sandbox:
2372            def DecoratedCreateTarget(arg):
2373                self.runCmd("file %s" % arg)
2374                target = self.dbg.GetSelectedTarget()
2375                #
2376                # SBtarget.LaunchSimple () currently not working for remote platform?
2377                # johnny @ 04/23/2012
2378                #
2379                def DecoratedLaunchSimple(argv, envp, wd):
2380                    self.runCmd("run")
2381                    return target.GetProcess()
2382                target.LaunchSimple = DecoratedLaunchSimple
2383
2384                return target
2385            self.dbg.CreateTarget = DecoratedCreateTarget
2386            if self.TraceOn():
2387                print("self.dbg.Create is redefined to:\n%s" % getsource_if_available(DecoratedCreateTarget))
2388
2389        # We want our debugger to be synchronous.
2390        self.dbg.SetAsync(False)
2391
2392        # Retrieve the associated command interpreter instance.
2393        self.ci = self.dbg.GetCommandInterpreter()
2394        if not self.ci:
2395            raise Exception('Could not get the command interpreter')
2396
2397        # And the result object.
2398        self.res = lldb.SBCommandReturnObject()
2399
2400        # Run global pre-flight code, if defined via the config file.
2401        if lldb.pre_flight:
2402            lldb.pre_flight(self)
2403
2404        if lldb.remote_platform and lldb.remote_platform_working_dir:
2405            remote_test_dir = lldbutil.join_remote_paths(
2406                    lldb.remote_platform_working_dir,
2407                    self.getArchitecture(),
2408                    str(self.test_number),
2409                    self.mydir)
2410            error = lldb.remote_platform.MakeDirectory(remote_test_dir, 448) # 448 = 0o700
2411            if error.Success():
2412                lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
2413
2414                # This function removes all files from the current working directory while leaving
2415                # the directories in place. The cleaup is required to reduce the disk space required
2416                # by the test suit while leaving the directories untached is neccessary because
2417                # sub-directories might belong to an other test
2418                def clean_working_directory():
2419                    # TODO: Make it working on Windows when we need it for remote debugging support
2420                    # TODO: Replace the heuristic to remove the files with a logic what collects the
2421                    # list of files we have to remove during test runs.
2422                    shell_cmd = lldb.SBPlatformShellCommand("rm %s/*" % remote_test_dir)
2423                    lldb.remote_platform.Run(shell_cmd)
2424                self.addTearDownHook(clean_working_directory)
2425            else:
2426                print("error: making remote directory '%s': %s" % (remote_test_dir, error))
2427
2428    def registerSharedLibrariesWithTarget(self, target, shlibs):
2429        '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
2430
2431        Any modules in the target that have their remote install file specification set will
2432        get uploaded to the remote host. This function registers the local copies of the
2433        shared libraries with the target and sets their remote install locations so they will
2434        be uploaded when the target is run.
2435        '''
2436        if not shlibs or not self.platformContext:
2437            return None
2438
2439        shlib_environment_var = self.platformContext.shlib_environment_var
2440        shlib_prefix = self.platformContext.shlib_prefix
2441        shlib_extension = '.' + self.platformContext.shlib_extension
2442
2443        working_dir = self.get_process_working_directory()
2444        environment = ['%s=%s' % (shlib_environment_var, working_dir)]
2445        # Add any shared libraries to our target if remote so they get
2446        # uploaded into the working directory on the remote side
2447        for name in shlibs:
2448            # The path can be a full path to a shared library, or a make file name like "Foo" for
2449            # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
2450            # basename like "libFoo.so". So figure out which one it is and resolve the local copy
2451            # of the shared library accordingly
2452            if os.path.exists(name):
2453                local_shlib_path = name # name is the full path to the local shared library
2454            else:
2455                # Check relative names
2456                local_shlib_path = os.path.join(os.getcwd(), shlib_prefix + name + shlib_extension)
2457                if not os.path.exists(local_shlib_path):
2458                    local_shlib_path = os.path.join(os.getcwd(), name + shlib_extension)
2459                    if not os.path.exists(local_shlib_path):
2460                        local_shlib_path = os.path.join(os.getcwd(), name)
2461
2462                # Make sure we found the local shared library in the above code
2463                self.assertTrue(os.path.exists(local_shlib_path))
2464
2465            # Add the shared library to our target
2466            shlib_module = target.AddModule(local_shlib_path, None, None, None)
2467            if lldb.remote_platform:
2468                # We must set the remote install location if we want the shared library
2469                # to get uploaded to the remote target
2470                remote_shlib_path = lldbutil.append_to_process_working_directory(os.path.basename(local_shlib_path))
2471                shlib_module.SetRemoteInstallFileSpec(lldb.SBFileSpec(remote_shlib_path, False))
2472
2473        return environment
2474
2475    # utility methods that tests can use to access the current objects
2476    def target(self):
2477        if not self.dbg:
2478            raise Exception('Invalid debugger instance')
2479        return self.dbg.GetSelectedTarget()
2480
2481    def process(self):
2482        if not self.dbg:
2483            raise Exception('Invalid debugger instance')
2484        return self.dbg.GetSelectedTarget().GetProcess()
2485
2486    def thread(self):
2487        if not self.dbg:
2488            raise Exception('Invalid debugger instance')
2489        return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
2490
2491    def frame(self):
2492        if not self.dbg:
2493            raise Exception('Invalid debugger instance')
2494        return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
2495
2496    def get_process_working_directory(self):
2497        '''Get the working directory that should be used when launching processes for local or remote processes.'''
2498        if lldb.remote_platform:
2499            # Remote tests set the platform working directory up in TestBase.setUp()
2500            return lldb.remote_platform.GetWorkingDirectory()
2501        else:
2502            # local tests change directory into each test subdirectory
2503            return os.getcwd()
2504
2505    def tearDown(self):
2506        #import traceback
2507        #traceback.print_stack()
2508
2509        # Ensure all the references to SB objects have gone away so that we can
2510        # be sure that all test-specific resources have been freed before we
2511        # attempt to delete the targets.
2512        gc.collect()
2513
2514        # Delete the target(s) from the debugger as a general cleanup step.
2515        # This includes terminating the process for each target, if any.
2516        # We'd like to reuse the debugger for our next test without incurring
2517        # the initialization overhead.
2518        targets = []
2519        for target in self.dbg:
2520            if target:
2521                targets.append(target)
2522                process = target.GetProcess()
2523                if process:
2524                    rc = self.invoke(process, "Kill")
2525                    self.assertTrue(rc.Success(), PROCESS_KILLED)
2526        for target in targets:
2527            self.dbg.DeleteTarget(target)
2528
2529        # Run global post-flight code, if defined via the config file.
2530        if lldb.post_flight:
2531            lldb.post_flight(self)
2532
2533        # Do this last, to make sure it's in reverse order from how we setup.
2534        Base.tearDown(self)
2535
2536        # This must be the last statement, otherwise teardown hooks or other
2537        # lines might depend on this still being active.
2538        del self.dbg
2539
2540    def switch_to_thread_with_stop_reason(self, stop_reason):
2541        """
2542        Run the 'thread list' command, and select the thread with stop reason as
2543        'stop_reason'.  If no such thread exists, no select action is done.
2544        """
2545        from lldbutil import stop_reason_to_str
2546        self.runCmd('thread list')
2547        output = self.res.GetOutput()
2548        thread_line_pattern = re.compile("^[ *] thread #([0-9]+):.*stop reason = %s" %
2549                                         stop_reason_to_str(stop_reason))
2550        for line in output.splitlines():
2551            matched = thread_line_pattern.match(line)
2552            if matched:
2553                self.runCmd('thread select %s' % matched.group(1))
2554
2555    def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
2556        """
2557        Ask the command interpreter to handle the command and then check its
2558        return status.
2559        """
2560        # Fail fast if 'cmd' is not meaningful.
2561        if not cmd or len(cmd) == 0:
2562            raise Exception("Bad 'cmd' parameter encountered")
2563
2564        trace = (True if traceAlways else trace)
2565
2566        # This is an opportunity to insert the 'platform target-install' command if we are told so
2567        # via the settig of lldb.lldbtest_remote_sandbox.
2568        if cmd.startswith("target create "):
2569            cmd = cmd.replace("target create ", "file ")
2570        if cmd.startswith("file ") and lldb.lldbtest_remote_sandbox:
2571            with recording(self, trace) as sbuf:
2572                the_rest = cmd.split("file ")[1]
2573                # Split the rest of the command line.
2574                atoms = the_rest.split()
2575                #
2576                # NOTE: This assumes that the options, if any, follow the file command,
2577                # instead of follow the specified target.
2578                #
2579                target = atoms[-1]
2580                # Now let's get the absolute pathname of our target.
2581                abs_target = os.path.abspath(target)
2582                print("Found a file command, target (with absolute pathname)=%s" % abs_target, file=sbuf)
2583                fpath, fname = os.path.split(abs_target)
2584                parent_dir = os.path.split(fpath)[0]
2585                platform_target_install_command = 'platform target-install %s %s' % (fpath, lldb.lldbtest_remote_sandbox)
2586                print("Insert this command to be run first: %s" % platform_target_install_command, file=sbuf)
2587                self.ci.HandleCommand(platform_target_install_command, self.res)
2588                # And this is the file command we want to execute, instead.
2589                #
2590                # Warning: SIDE EFFECT AHEAD!!!
2591                # Populate the remote executable pathname into the lldb namespace,
2592                # so that test cases can grab this thing out of the namespace.
2593                #
2594                lldb.lldbtest_remote_sandboxed_executable = abs_target.replace(parent_dir, lldb.lldbtest_remote_sandbox)
2595                cmd = "file -P %s %s %s" % (lldb.lldbtest_remote_sandboxed_executable, the_rest.replace(target, ''), abs_target)
2596                print("And this is the replaced file command: %s" % cmd, file=sbuf)
2597
2598        running = (cmd.startswith("run") or cmd.startswith("process launch"))
2599
2600        for i in range(self.maxLaunchCount if running else 1):
2601            self.ci.HandleCommand(cmd, self.res, inHistory)
2602
2603            with recording(self, trace) as sbuf:
2604                print("runCmd:", cmd, file=sbuf)
2605                if not check:
2606                    print("check of return status not required", file=sbuf)
2607                if self.res.Succeeded():
2608                    print("output:", self.res.GetOutput(), file=sbuf)
2609                else:
2610                    print("runCmd failed!", file=sbuf)
2611                    print(self.res.GetError(), file=sbuf)
2612
2613            if self.res.Succeeded():
2614                break
2615            elif running:
2616                # For process launch, wait some time before possible next try.
2617                time.sleep(self.timeWaitNextLaunch)
2618                with recording(self, trace) as sbuf:
2619                    print("Command '" + cmd + "' failed!", file=sbuf)
2620
2621        if check:
2622            self.assertTrue(self.res.Succeeded(),
2623                            msg if msg else CMD_MSG(cmd))
2624
2625    def match (self, str, patterns, msg=None, trace=False, error=False, matching=True, exe=True):
2626        """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
2627
2628        Otherwise, all the arguments have the same meanings as for the expect function"""
2629
2630        trace = (True if traceAlways else trace)
2631
2632        if exe:
2633            # First run the command.  If we are expecting error, set check=False.
2634            # Pass the assert message along since it provides more semantic info.
2635            self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error)
2636
2637            # Then compare the output against expected strings.
2638            output = self.res.GetError() if error else self.res.GetOutput()
2639
2640            # If error is True, the API client expects the command to fail!
2641            if error:
2642                self.assertFalse(self.res.Succeeded(),
2643                                 "Command '" + str + "' is expected to fail!")
2644        else:
2645            # No execution required, just compare str against the golden input.
2646            output = str
2647            with recording(self, trace) as sbuf:
2648                print("looking at:", output, file=sbuf)
2649
2650        # The heading says either "Expecting" or "Not expecting".
2651        heading = "Expecting" if matching else "Not expecting"
2652
2653        for pattern in patterns:
2654            # Match Objects always have a boolean value of True.
2655            match_object = re.search(pattern, output)
2656            matched = bool(match_object)
2657            with recording(self, trace) as sbuf:
2658                print("%s pattern: %s" % (heading, pattern), file=sbuf)
2659                print("Matched" if matched else "Not matched", file=sbuf)
2660            if matched:
2661                break
2662
2663        self.assertTrue(matched if matching else not matched,
2664                        msg if msg else EXP_MSG(str, exe))
2665
2666        return match_object
2667
2668    def expect(self, str, msg=None, patterns=None, startstr=None, endstr=None, substrs=None, trace=False, error=False, matching=True, exe=True, inHistory=False):
2669        """
2670        Similar to runCmd; with additional expect style output matching ability.
2671
2672        Ask the command interpreter to handle the command and then check its
2673        return status.  The 'msg' parameter specifies an informational assert
2674        message.  We expect the output from running the command to start with
2675        'startstr', matches the substrings contained in 'substrs', and regexp
2676        matches the patterns contained in 'patterns'.
2677
2678        If the keyword argument error is set to True, it signifies that the API
2679        client is expecting the command to fail.  In this case, the error stream
2680        from running the command is retrieved and compared against the golden
2681        input, instead.
2682
2683        If the keyword argument matching is set to False, it signifies that the API
2684        client is expecting the output of the command not to match the golden
2685        input.
2686
2687        Finally, the required argument 'str' represents the lldb command to be
2688        sent to the command interpreter.  In case the keyword argument 'exe' is
2689        set to False, the 'str' is treated as a string to be matched/not-matched
2690        against the golden input.
2691        """
2692        trace = (True if traceAlways else trace)
2693
2694        if exe:
2695            # First run the command.  If we are expecting error, set check=False.
2696            # Pass the assert message along since it provides more semantic info.
2697            self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error, inHistory=inHistory)
2698
2699            # Then compare the output against expected strings.
2700            output = self.res.GetError() if error else self.res.GetOutput()
2701
2702            # If error is True, the API client expects the command to fail!
2703            if error:
2704                self.assertFalse(self.res.Succeeded(),
2705                                 "Command '" + str + "' is expected to fail!")
2706        else:
2707            # No execution required, just compare str against the golden input.
2708            if isinstance(str,lldb.SBCommandReturnObject):
2709                output = str.GetOutput()
2710            else:
2711                output = str
2712            with recording(self, trace) as sbuf:
2713                print("looking at:", output, file=sbuf)
2714
2715        # The heading says either "Expecting" or "Not expecting".
2716        heading = "Expecting" if matching else "Not expecting"
2717
2718        # Start from the startstr, if specified.
2719        # If there's no startstr, set the initial state appropriately.
2720        matched = output.startswith(startstr) if startstr else (True if matching else False)
2721
2722        if startstr:
2723            with recording(self, trace) as sbuf:
2724                print("%s start string: %s" % (heading, startstr), file=sbuf)
2725                print("Matched" if matched else "Not matched", file=sbuf)
2726
2727        # Look for endstr, if specified.
2728        keepgoing = matched if matching else not matched
2729        if endstr:
2730            matched = output.endswith(endstr)
2731            with recording(self, trace) as sbuf:
2732                print("%s end string: %s" % (heading, endstr), file=sbuf)
2733                print("Matched" if matched else "Not matched", file=sbuf)
2734
2735        # Look for sub strings, if specified.
2736        keepgoing = matched if matching else not matched
2737        if substrs and keepgoing:
2738            for str in substrs:
2739                matched = output.find(str) != -1
2740                with recording(self, trace) as sbuf:
2741                    print("%s sub string: %s" % (heading, str), file=sbuf)
2742                    print("Matched" if matched else "Not matched", file=sbuf)
2743                keepgoing = matched if matching else not matched
2744                if not keepgoing:
2745                    break
2746
2747        # Search for regular expression patterns, if specified.
2748        keepgoing = matched if matching else not matched
2749        if patterns and keepgoing:
2750            for pattern in patterns:
2751                # Match Objects always have a boolean value of True.
2752                matched = bool(re.search(pattern, output))
2753                with recording(self, trace) as sbuf:
2754                    print("%s pattern: %s" % (heading, pattern), file=sbuf)
2755                    print("Matched" if matched else "Not matched", file=sbuf)
2756                keepgoing = matched if matching else not matched
2757                if not keepgoing:
2758                    break
2759
2760        self.assertTrue(matched if matching else not matched,
2761                        msg if msg else EXP_MSG(str, exe))
2762
2763    def invoke(self, obj, name, trace=False):
2764        """Use reflection to call a method dynamically with no argument."""
2765        trace = (True if traceAlways else trace)
2766
2767        method = getattr(obj, name)
2768        import inspect
2769        self.assertTrue(inspect.ismethod(method),
2770                        name + "is a method name of object: " + str(obj))
2771        result = method()
2772        with recording(self, trace) as sbuf:
2773            print(str(method) + ":",  result, file=sbuf)
2774        return result
2775
2776    def build(self, architecture=None, compiler=None, dictionary=None, clean=True):
2777        """Platform specific way to build the default binaries."""
2778        if lldb.skip_build_and_cleanup:
2779            return
2780        module = builder_module()
2781        if target_is_android():
2782            dictionary = append_android_envs(dictionary)
2783        if self.debug_info is None:
2784            return self.buildDefault(architecture, compiler, dictionary, clean)
2785        elif self.debug_info == "dsym":
2786            return self.buildDsym(architecture, compiler, dictionary, clean)
2787        elif self.debug_info == "dwarf":
2788            return self.buildDwarf(architecture, compiler, dictionary, clean)
2789        elif self.debug_info == "dwo":
2790            return self.buildDwo(architecture, compiler, dictionary, clean)
2791        else:
2792            self.fail("Can't build for debug info: %s" % self.debug_info)
2793
2794    # =================================================
2795    # Misc. helper methods for debugging test execution
2796    # =================================================
2797
2798    def DebugSBValue(self, val):
2799        """Debug print a SBValue object, if traceAlways is True."""
2800        from lldbutil import value_type_to_str
2801
2802        if not traceAlways:
2803            return
2804
2805        err = sys.stderr
2806        err.write(val.GetName() + ":\n")
2807        err.write('\t' + "TypeName         -> " + val.GetTypeName()            + '\n')
2808        err.write('\t' + "ByteSize         -> " + str(val.GetByteSize())       + '\n')
2809        err.write('\t' + "NumChildren      -> " + str(val.GetNumChildren())    + '\n')
2810        err.write('\t' + "Value            -> " + str(val.GetValue())          + '\n')
2811        err.write('\t' + "ValueAsUnsigned  -> " + str(val.GetValueAsUnsigned())+ '\n')
2812        err.write('\t' + "ValueType        -> " + value_type_to_str(val.GetValueType()) + '\n')
2813        err.write('\t' + "Summary          -> " + str(val.GetSummary())        + '\n')
2814        err.write('\t' + "IsPointerType    -> " + str(val.TypeIsPointerType()) + '\n')
2815        err.write('\t' + "Location         -> " + val.GetLocation()            + '\n')
2816
2817    def DebugSBType(self, type):
2818        """Debug print a SBType object, if traceAlways is True."""
2819        if not traceAlways:
2820            return
2821
2822        err = sys.stderr
2823        err.write(type.GetName() + ":\n")
2824        err.write('\t' + "ByteSize        -> " + str(type.GetByteSize())     + '\n')
2825        err.write('\t' + "IsPointerType   -> " + str(type.IsPointerType())   + '\n')
2826        err.write('\t' + "IsReferenceType -> " + str(type.IsReferenceType()) + '\n')
2827
2828    def DebugPExpect(self, child):
2829        """Debug the spwaned pexpect object."""
2830        if not traceAlways:
2831            return
2832
2833        print(child)
2834
2835    @classmethod
2836    def RemoveTempFile(cls, file):
2837        if os.path.exists(file):
2838            os.remove(file)
2839