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