lldbtest.py revision 3d4d51cd1bdef32ab61ba9e1de75d5a4f4c1dbed
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
34import os, sys, traceback
35import os.path
36import re
37from subprocess import *
38import StringIO
39import time
40import types
41import unittest2
42import lldb
43
44# See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
45# LLDB_COMMAND_TRACE and LLDB_DO_CLEANUP are set from '-t' and '-r dir' options.
46
47# By default, traceAlways is False.
48if "LLDB_COMMAND_TRACE" in os.environ and os.environ["LLDB_COMMAND_TRACE"]=="YES":
49    traceAlways = True
50else:
51    traceAlways = False
52
53# By default, doCleanup is True.
54if "LLDB_DO_CLEANUP" in os.environ and os.environ["LLDB_DO_CLEANUP"]=="NO":
55    doCleanup = False
56else:
57    doCleanup = True
58
59
60#
61# Some commonly used assert messages.
62#
63
64COMMAND_FAILED_AS_EXPECTED = "Command has failed as expected"
65
66CURRENT_EXECUTABLE_SET = "Current executable set successfully"
67
68PROCESS_IS_VALID = "Process is valid"
69
70PROCESS_KILLED = "Process is killed successfully"
71
72PROCESS_EXITED = "Process exited successfully"
73
74PROCESS_STOPPED = "Process status should be stopped"
75
76RUN_SUCCEEDED = "Process is launched successfully"
77
78RUN_COMPLETED = "Process exited successfully"
79
80BACKTRACE_DISPLAYED_CORRECTLY = "Backtrace displayed correctly"
81
82BREAKPOINT_CREATED = "Breakpoint created successfully"
83
84BREAKPOINT_STATE_CORRECT = "Breakpoint state is correct"
85
86BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
87
88BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1"
89
90BREAKPOINT_HIT_TWICE = "Breakpoint resolved with hit cout = 2"
91
92BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit cout = 3"
93
94MISSING_EXPECTED_REGISTERS = "At least one expected register is unavailable."
95
96OBJECT_PRINTED_CORRECTLY = "Object printed correctly"
97
98SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly"
99
100STEP_OUT_SUCCEEDED = "Thread step-out succeeded"
101
102STOPPED_DUE_TO_EXC_BAD_ACCESS = "Process should be stopped due to bad access exception"
103
104STOPPED_DUE_TO_BREAKPOINT = "Process should be stopped due to breakpoint"
105
106STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS = "%s, %s" % (
107    STOPPED_DUE_TO_BREAKPOINT, "instead, the actual stop reason is: '%s'")
108
109STOPPED_DUE_TO_BREAKPOINT_CONDITION = "Stopped due to breakpoint condition"
110
111STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT = "Stopped due to breakpoint and ignore count"
112
113STOPPED_DUE_TO_SIGNAL = "Process state is stopped due to signal"
114
115STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"
116
117STOPPED_DUE_TO_WATCHPOINT = "Process should be stopped due to watchpoint"
118
119DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
120
121VALID_BREAKPOINT = "Got a valid breakpoint"
122
123VALID_BREAKPOINT_LOCATION = "Got a valid breakpoint location"
124
125VALID_COMMAND_INTERPRETER = "Got a valid command interpreter"
126
127VALID_FILESPEC = "Got a valid filespec"
128
129VALID_MODULE = "Got a valid module"
130
131VALID_PROCESS = "Got a valid process"
132
133VALID_SYMBOL = "Got a valid symbol"
134
135VALID_TARGET = "Got a valid target"
136
137VALID_TYPE = "Got a valid type"
138
139VALID_VARIABLE = "Got a valid variable"
140
141VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
142
143WATCHPOINT_CREATED = "Watchpoint created successfully"
144
145def CMD_MSG(str):
146    '''A generic "Command '%s' returns successfully" message generator.'''
147    return "Command '%s' returns successfully" % str
148
149def COMPLETION_MSG(str_before, str_after):
150    '''A generic message generator for the completion mechanism.'''
151    return "'%s' successfully completes to '%s'" % (str_before, str_after)
152
153def EXP_MSG(str, exe):
154    '''A generic "'%s' returns expected result" message generator if exe.
155    Otherwise, it generates "'%s' matches expected result" message.'''
156    return "'%s' %s expected result" % (str, 'returns' if exe else 'matches')
157
158def SETTING_MSG(setting):
159    '''A generic "Value of setting '%s' is correct" message generator.'''
160    return "Value of setting '%s' is correct" % setting
161
162def EnvArray():
163    """Returns an env variable array from the os.environ map object."""
164    return map(lambda k,v: k+"="+v, os.environ.keys(), os.environ.values())
165
166def line_number(filename, string_to_match):
167    """Helper function to return the line number of the first matched string."""
168    with open(filename, 'r') as f:
169        for i, line in enumerate(f):
170            if line.find(string_to_match) != -1:
171                # Found our match.
172                return i+1
173    raise Exception("Unable to find '%s' within file %s" % (string_to_match, filename))
174
175def pointer_size():
176    """Return the pointer size of the host system."""
177    import ctypes
178    a_pointer = ctypes.c_void_p(0xffff)
179    return 8 * ctypes.sizeof(a_pointer)
180
181def is_exe(fpath):
182    """Returns true if fpath is an executable."""
183    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
184
185def which(program):
186    """Returns the full path to a program; None otherwise."""
187    fpath, fname = os.path.split(program)
188    if fpath:
189        if is_exe(program):
190            return program
191    else:
192        for path in os.environ["PATH"].split(os.pathsep):
193            exe_file = os.path.join(path, program)
194            if is_exe(exe_file):
195                return exe_file
196    return None
197
198class recording(StringIO.StringIO):
199    """
200    A nice little context manager for recording the debugger interactions into
201    our session object.  If trace flag is ON, it also emits the interactions
202    into the stderr.
203    """
204    def __init__(self, test, trace):
205        """Create a StringIO instance; record the session obj and trace flag."""
206        StringIO.StringIO.__init__(self)
207        # The test might not have undergone the 'setUp(self)' phase yet, so that
208        # the attribute 'session' might not even exist yet.
209        self.session = getattr(test, "session", None) if test else None
210        self.trace = trace
211
212    def __enter__(self):
213        """
214        Context management protocol on entry to the body of the with statement.
215        Just return the StringIO object.
216        """
217        return self
218
219    def __exit__(self, type, value, tb):
220        """
221        Context management protocol on exit from the body of the with statement.
222        If trace is ON, it emits the recordings into stderr.  Always add the
223        recordings to our session object.  And close the StringIO object, too.
224        """
225        if self.trace:
226            print >> sys.stderr, self.getvalue()
227        if self.session:
228            print >> self.session, self.getvalue()
229        self.close()
230
231# From 2.7's subprocess.check_output() convenience function.
232# Return a tuple (stdoutdata, stderrdata).
233def system(*popenargs, **kwargs):
234    r"""Run an os command with arguments and return its output as a byte string.
235
236    If the exit code was non-zero it raises a CalledProcessError.  The
237    CalledProcessError object will have the return code in the returncode
238    attribute and output in the output attribute.
239
240    The arguments are the same as for the Popen constructor.  Example:
241
242    >>> check_output(["ls", "-l", "/dev/null"])
243    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
244
245    The stdout argument is not allowed as it is used internally.
246    To capture standard error in the result, use stderr=STDOUT.
247
248    >>> check_output(["/bin/sh", "-c",
249    ...               "ls -l non_existent_file ; exit 0"],
250    ...              stderr=STDOUT)
251    'ls: non_existent_file: No such file or directory\n'
252    """
253
254    # Assign the sender object to variable 'test' and remove it from kwargs.
255    test = kwargs.pop('sender', None)
256
257    if 'stdout' in kwargs:
258        raise ValueError('stdout argument not allowed, it will be overridden.')
259    process = Popen(stdout=PIPE, stderr=PIPE, *popenargs, **kwargs)
260    pid = process.pid
261    output, error = process.communicate()
262    retcode = process.poll()
263
264    with recording(test, traceAlways) as sbuf:
265        if isinstance(popenargs, types.StringTypes):
266            args = [popenargs]
267        else:
268            args = list(popenargs)
269        print >> sbuf
270        print >> sbuf, "os command:", args
271        print >> sbuf, "with pid:", pid
272        print >> sbuf, "stdout:", output
273        print >> sbuf, "stderr:", error
274        print >> sbuf, "retcode:", retcode
275        print >> sbuf
276
277    if retcode:
278        cmd = kwargs.get("args")
279        if cmd is None:
280            cmd = popenargs[0]
281        raise CalledProcessError(retcode, cmd)
282    return (output, error)
283
284def getsource_if_available(obj):
285    """
286    Return the text of the source code for an object if available.  Otherwise,
287    a print representation is returned.
288    """
289    import inspect
290    try:
291        return inspect.getsource(obj)
292    except:
293        return repr(obj)
294
295def builder_module():
296    return __import__("builder_" + sys.platform)
297
298#
299# Decorators for categorizing test cases.
300#
301
302from functools import wraps
303def python_api_test(func):
304    """Decorate the item as a Python API only test."""
305    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
306        raise Exception("@python_api_test can only be used to decorate a test method")
307    @wraps(func)
308    def wrapper(self, *args, **kwargs):
309        try:
310            if lldb.dont_do_python_api_test:
311                self.skipTest("python api tests")
312        except AttributeError:
313            pass
314        return func(self, *args, **kwargs)
315
316    # Mark this function as such to separate them from lldb command line tests.
317    wrapper.__python_api_test__ = True
318    return wrapper
319
320def benchmarks_test(func):
321    """Decorate the item as a benchmarks test."""
322    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
323        raise Exception("@benchmarks_test can only be used to decorate a test method")
324    @wraps(func)
325    def wrapper(self, *args, **kwargs):
326        try:
327            if not lldb.just_do_benchmarks_test:
328                self.skipTest("benchmarks tests")
329        except AttributeError:
330            pass
331        return func(self, *args, **kwargs)
332
333    # Mark this function as such to separate them from the regular tests.
334    wrapper.__benchmarks_test__ = True
335    return wrapper
336
337def dsym_test(func):
338    """Decorate the item as a dsym test."""
339    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
340        raise Exception("@dsym_test can only be used to decorate a test method")
341    @wraps(func)
342    def wrapper(self, *args, **kwargs):
343        try:
344            if lldb.dont_do_dsym_test:
345                self.skipTest("dsym tests")
346        except AttributeError:
347            pass
348        return func(self, *args, **kwargs)
349
350    # Mark this function as such to separate them from the regular tests.
351    wrapper.__dsym_test__ = True
352    return wrapper
353
354def dwarf_test(func):
355    """Decorate the item as a dwarf test."""
356    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
357        raise Exception("@dwarf_test can only be used to decorate a test method")
358    @wraps(func)
359    def wrapper(self, *args, **kwargs):
360        try:
361            if lldb.dont_do_dwarf_test:
362                self.skipTest("dwarf tests")
363        except AttributeError:
364            pass
365        return func(self, *args, **kwargs)
366
367    # Mark this function as such to separate them from the regular tests.
368    wrapper.__dwarf_test__ = True
369    return wrapper
370
371def expectedFailureGcc(bugnumber=None):
372     if callable(bugnumber):
373        @wraps(bugnumber)
374        def expectedFailureGcc_easy_wrapper(*args, **kwargs):
375            from unittest2 import case
376            self = args[0]
377            test_compiler = self.getCompiler()
378            try:
379                bugnumber(*args, **kwargs)
380            except Exception:
381                if "gcc" in test_compiler:
382                    raise case._ExpectedFailure(sys.exc_info(),None)
383                else:
384                    raise
385            if "gcc" in test_compiler:
386                raise case._UnexpectedSuccess(sys.exc_info(),None)
387        return expectedFailureGcc_easy_wrapper
388     else:
389        def expectedFailureGcc_impl(func):
390              @wraps(func)
391              def wrapper(*args, **kwargs):
392                from unittest2 import case
393                self = args[0]
394                test_compiler = self.getCompiler()
395                try:
396                    func(*args, **kwargs)
397                except Exception:
398                    if "gcc" in test_compiler:
399                        raise case._ExpectedFailure(sys.exc_info(),bugnumber)
400                    else:
401                        raise
402                if "gcc" in test_compiler:
403                    raise case._UnexpectedSuccess(sys.exc_info(),bugnumber)
404              return wrapper
405        return expectedFailureGcc_impl
406
407def expectedFailureClang(bugnumber=None):
408     if callable(bugnumber):
409        @wraps(bugnumber)
410        def expectedFailureClang_easy_wrapper(*args, **kwargs):
411            from unittest2 import case
412            self = args[0]
413            test_compiler = self.getCompiler()
414            try:
415                bugnumber(*args, **kwargs)
416            except Exception:
417                if "clang" in test_compiler:
418                    raise case._ExpectedFailure(sys.exc_info(),None)
419                else:
420                    raise
421            if "clang" in test_compiler:
422                raise case._UnexpectedSuccess(sys.exc_info(),None)
423        return expectedFailureClang_easy_wrapper
424     else:
425        def expectedFailureClang_impl(func):
426              @wraps(func)
427              def wrapper(*args, **kwargs):
428                from unittest2 import case
429                self = args[0]
430                test_compiler = self.getCompiler()
431                try:
432                    func(*args, **kwargs)
433                except Exception:
434                    if "clang" in test_compiler:
435                        raise case._ExpectedFailure(sys.exc_info(),bugnumber)
436                    else:
437                        raise
438                if "clang" in test_compiler:
439                    raise case._UnexpectedSuccess(sys.exc_info(),bugnumber)
440              return wrapper
441        return expectedFailureClang_impl
442
443def expectedFailureIcc(bugnumber=None):
444     if callable(bugnumber):
445        @wraps(bugnumber)
446        def expectedFailureIcc_easy_wrapper(*args, **kwargs):
447            from unittest2 import case
448            self = args[0]
449            test_compiler = self.getCompiler()
450            try:
451                bugnumber(*args, **kwargs)
452            except Exception:
453                if "icc" in test_compiler:
454                    raise case._ExpectedFailure(sys.exc_info(),None)
455                else:
456                    raise
457            if "icc" in test_compiler:
458                raise case._UnexpectedSuccess(sys.exc_info(),None)
459        return expectedFailureIcc_easy_wrapper
460     else:
461        def expectedFailureIcc_impl(func):
462              @wraps(func)
463              def wrapper(*args, **kwargs):
464                from unittest2 import case
465                self = args[0]
466                test_compiler = self.getCompiler()
467                try:
468                    func(*args, **kwargs)
469                except Exception:
470                    if "icc" in test_compiler:
471                        raise case._ExpectedFailure(sys.exc_info(),bugnumber)
472                    else:
473                        raise
474                if "icc" in test_compiler:
475                    raise case._UnexpectedSuccess(sys.exc_info(),bugnumber)
476              return wrapper
477        return expectedFailureIcc_impl
478
479
480def expectedFailurei386(bugnumber=None):
481     if callable(bugnumber):
482        @wraps(bugnumber)
483        def expectedFailurei386_easy_wrapper(*args, **kwargs):
484            from unittest2 import case
485            self = args[0]
486            arch = self.getArchitecture()
487            try:
488                bugnumber(*args, **kwargs)
489            except Exception:
490                if "i386" in arch:
491                    raise case._ExpectedFailure(sys.exc_info(),None)
492                else:
493                    raise
494            if "i386" in arch:
495                raise case._UnexpectedSuccess(sys.exc_info(),None)
496        return expectedFailurei386_easy_wrapper
497     else:
498        def expectedFailurei386_impl(func):
499              @wraps(func)
500              def wrapper(*args, **kwargs):
501                from unittest2 import case
502                self = args[0]
503                arch = self.getArchitecture()
504                try:
505                    func(*args, **kwargs)
506                except Exception:
507                    if "i386" in arch:
508                        raise case._ExpectedFailure(sys.exc_info(),bugnumber)
509                    else:
510                        raise
511                if "i386" in arch:
512                    raise case._UnexpectedSuccess(sys.exc_info(),bugnumber)
513              return wrapper
514        return expectedFailurei386_impl
515
516def expectedFailureLinux(bugnumber=None):
517     if callable(bugnumber):
518        @wraps(bugnumber)
519        def expectedFailureLinux_easy_wrapper(*args, **kwargs):
520            from unittest2 import case
521            self = args[0]
522            platform = sys.platform
523            try:
524                bugnumber(*args, **kwargs)
525            except Exception:
526                if "linux" in platform:
527                    raise case._ExpectedFailure(sys.exc_info(),None)
528                else:
529                    raise
530            if "linux" in platform:
531                raise case._UnexpectedSuccess(sys.exc_info(),None)
532        return expectedFailureLinux_easy_wrapper
533     else:
534        def expectedFailureLinux_impl(func):
535              @wraps(func)
536              def wrapper(*args, **kwargs):
537                from unittest2 import case
538                self = args[0]
539                platform = sys.platform
540                try:
541                    func(*args, **kwargs)
542                except Exception:
543                    if "linux" in platform:
544                        raise case._ExpectedFailure(sys.exc_info(),bugnumber)
545                    else:
546                        raise
547                if "linux" in platform:
548                    raise case._UnexpectedSuccess(sys.exc_info(),bugnumber)
549              return wrapper
550        return expectedFailureLinux_impl
551
552def expectedFailureDarwin(bugnumber=None):
553     if callable(bugnumber):
554        @wraps(bugnumber)
555        def expectedFailureDarwin_easy_wrapper(*args, **kwargs):
556            from unittest2 import case
557            self = args[0]
558            platform = sys.platform
559            try:
560                bugnumber(*args, **kwargs)
561            except Exception:
562                if "darwin" in platform:
563                    raise case._ExpectedFailure(sys.exc_info(),None)
564                else:
565                    raise
566            if "darwin" in platform:
567                raise case._UnexpectedSuccess(sys.exc_info(),None)
568        return expectedFailureDarwin_easy_wrapper
569     else:
570        def expectedFailureDarwin_impl(func):
571              @wraps(func)
572              def wrapper(*args, **kwargs):
573                from unittest2 import case
574                self = args[0]
575                platform = sys.platform
576                try:
577                    func(*args, **kwargs)
578                except Exception:
579                    if "darwin" in platform:
580                        raise case._ExpectedFailure(sys.exc_info(),bugnumber)
581                    else:
582                        raise
583                if "darwin" in platform:
584                    raise case._UnexpectedSuccess(sys.exc_info(),bugnumber)
585              return wrapper
586        return expectedFailureDarwin_impl
587
588def skipOnLinux(func):
589    """Decorate the item to skip tests that should be skipped on Linux."""
590    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
591        raise Exception("@skipOnLinux can only be used to decorate a test method")
592    @wraps(func)
593    def wrapper(*args, **kwargs):
594        from unittest2 import case
595        self = args[0]
596        platform = sys.platform
597        if "linux" in platform:
598            self.skipTest("skip on linux")
599        else:
600            func(*args, **kwargs)
601    return wrapper
602
603def skipIfGcc(func):
604    """Decorate the item to skip tests that should be skipped if building with gcc ."""
605    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
606        raise Exception("@skipIfGcc can only be used to decorate a test method")
607    @wraps(func)
608    def wrapper(*args, **kwargs):
609        from unittest2 import case
610        self = args[0]
611        compiler = self.getCompiler()
612        if "gcc" in compiler:
613            self.skipTest("skipping because gcc is the test compiler")
614        else:
615            func(*args, **kwargs)
616    return wrapper
617
618def skipIfIcc(func):
619    """Decorate the item to skip tests that should be skipped if building with icc ."""
620    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
621        raise Exception("@skipIfIcc can only be used to decorate a test method")
622    @wraps(func)
623    def wrapper(*args, **kwargs):
624        from unittest2 import case
625        self = args[0]
626        compiler = self.getCompiler()
627        if "icc" in compiler:
628            self.skipTest("skipping because icc is the test compiler")
629        else:
630            func(*args, **kwargs)
631    return wrapper
632
633def skipIfi386(func):
634    """Decorate the item to skip tests that should be skipped if building 32-bit."""
635    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
636        raise Exception("@skipIfi386 can only be used to decorate a test method")
637    @wraps(func)
638    def wrapper(*args, **kwargs):
639        from unittest2 import case
640        self = args[0]
641        if "i386" == self.getArchitecture():
642            self.skipTest("skipping because i386 is not a supported architecture")
643        else:
644            func(*args, **kwargs)
645    return wrapper
646
647
648class Base(unittest2.TestCase):
649    """
650    Abstract base for performing lldb (see TestBase) or other generic tests (see
651    BenchBase for one example).  lldbtest.Base works with the test driver to
652    accomplish things.
653
654    """
655
656    # The concrete subclass should override this attribute.
657    mydir = None
658
659    # Keep track of the old current working directory.
660    oldcwd = None
661
662    def TraceOn(self):
663        """Returns True if we are in trace mode (tracing detailed test execution)."""
664        return traceAlways
665
666    @classmethod
667    def setUpClass(cls):
668        """
669        Python unittest framework class setup fixture.
670        Do current directory manipulation.
671        """
672
673        # Fail fast if 'mydir' attribute is not overridden.
674        if not cls.mydir or len(cls.mydir) == 0:
675            raise Exception("Subclasses must override the 'mydir' attribute.")
676
677        # Save old working directory.
678        cls.oldcwd = os.getcwd()
679
680        # Change current working directory if ${LLDB_TEST} is defined.
681        # See also dotest.py which sets up ${LLDB_TEST}.
682        if ("LLDB_TEST" in os.environ):
683            if traceAlways:
684                print >> sys.stderr, "Change dir to:", os.path.join(os.environ["LLDB_TEST"], cls.mydir)
685            os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
686
687    @classmethod
688    def tearDownClass(cls):
689        """
690        Python unittest framework class teardown fixture.
691        Do class-wide cleanup.
692        """
693
694        if doCleanup and not lldb.skip_build_and_cleanup:
695            # First, let's do the platform-specific cleanup.
696            module = builder_module()
697            if not module.cleanup():
698                raise Exception("Don't know how to do cleanup")
699
700            # Subclass might have specific cleanup function defined.
701            if getattr(cls, "classCleanup", None):
702                if traceAlways:
703                    print >> sys.stderr, "Call class-specific cleanup function for class:", cls
704                try:
705                    cls.classCleanup()
706                except:
707                    exc_type, exc_value, exc_tb = sys.exc_info()
708                    traceback.print_exception(exc_type, exc_value, exc_tb)
709
710        # Restore old working directory.
711        if traceAlways:
712            print >> sys.stderr, "Restore dir to:", cls.oldcwd
713        os.chdir(cls.oldcwd)
714
715    @classmethod
716    def skipLongRunningTest(cls):
717        """
718        By default, we skip long running test case.
719        This can be overridden by passing '-l' to the test driver (dotest.py).
720        """
721        if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
722            return False
723        else:
724            return True
725
726    def setUp(self):
727        """Fixture for unittest test case setup.
728
729        It works with the test driver to conditionally skip tests and does other
730        initializations."""
731        #import traceback
732        #traceback.print_stack()
733
734        if "LLDB_EXEC" in os.environ:
735            self.lldbExec = os.environ["LLDB_EXEC"]
736        else:
737            self.lldbExec = None
738        if "LLDB_HERE" in os.environ:
739            self.lldbHere = os.environ["LLDB_HERE"]
740        else:
741            self.lldbHere = None
742        # If we spawn an lldb process for test (via pexpect), do not load the
743        # init file unless told otherwise.
744        if "NO_LLDBINIT" in os.environ and "NO" == os.environ["NO_LLDBINIT"]:
745            self.lldbOption = ""
746        else:
747            self.lldbOption = "--no-lldbinit"
748
749        # Assign the test method name to self.testMethodName.
750        #
751        # For an example of the use of this attribute, look at test/types dir.
752        # There are a bunch of test cases under test/types and we don't want the
753        # module cacheing subsystem to be confused with executable name "a.out"
754        # used for all the test cases.
755        self.testMethodName = self._testMethodName
756
757        # Python API only test is decorated with @python_api_test,
758        # which also sets the "__python_api_test__" attribute of the
759        # function object to True.
760        try:
761            if lldb.just_do_python_api_test:
762                testMethod = getattr(self, self._testMethodName)
763                if getattr(testMethod, "__python_api_test__", False):
764                    pass
765                else:
766                    self.skipTest("non python api test")
767        except AttributeError:
768            pass
769
770        # Benchmarks test is decorated with @benchmarks_test,
771        # which also sets the "__benchmarks_test__" attribute of the
772        # function object to True.
773        try:
774            if lldb.just_do_benchmarks_test:
775                testMethod = getattr(self, self._testMethodName)
776                if getattr(testMethod, "__benchmarks_test__", False):
777                    pass
778                else:
779                    self.skipTest("non benchmarks test")
780        except AttributeError:
781            pass
782
783        # This is for the case of directly spawning 'lldb'/'gdb' and interacting
784        # with it using pexpect.
785        self.child = None
786        self.child_prompt = "(lldb) "
787        # If the child is interacting with the embedded script interpreter,
788        # there are two exits required during tear down, first to quit the
789        # embedded script interpreter and second to quit the lldb command
790        # interpreter.
791        self.child_in_script_interpreter = False
792
793        # These are for customized teardown cleanup.
794        self.dict = None
795        self.doTearDownCleanup = False
796        # And in rare cases where there are multiple teardown cleanups.
797        self.dicts = []
798        self.doTearDownCleanups = False
799
800        # List of spawned subproces.Popen objects
801        self.subprocesses = []
802
803        # Create a string buffer to record the session info, to be dumped into a
804        # test case specific file if test failure is encountered.
805        self.session = StringIO.StringIO()
806
807        # Optimistically set __errored__, __failed__, __expected__ to False
808        # initially.  If the test errored/failed, the session info
809        # (self.session) is then dumped into a session specific file for
810        # diagnosis.
811        self.__errored__    = False
812        self.__failed__     = False
813        self.__expected__   = False
814        # We are also interested in unexpected success.
815        self.__unexpected__ = False
816        # And skipped tests.
817        self.__skipped__ = False
818
819        # See addTearDownHook(self, hook) which allows the client to add a hook
820        # function to be run during tearDown() time.
821        self.hooks = []
822
823        # See HideStdout(self).
824        self.sys_stdout_hidden = False
825
826        # set environment variable names for finding shared libraries
827        if sys.platform.startswith("darwin"):
828            self.dylibPath = 'DYLD_LIBRARY_PATH'
829        elif sys.platform.startswith("linux") or sys.platform.startswith("freebsd"):
830            self.dylibPath = 'LD_LIBRARY_PATH'
831
832    def runHooks(self, child=None, child_prompt=None, use_cmd_api=False):
833        """Perform the run hooks to bring lldb debugger to the desired state.
834
835        By default, expect a pexpect spawned child and child prompt to be
836        supplied (use_cmd_api=False).  If use_cmd_api is true, ignore the child
837        and child prompt and use self.runCmd() to run the hooks one by one.
838
839        Note that child is a process spawned by pexpect.spawn().  If not, your
840        test case is mostly likely going to fail.
841
842        See also dotest.py where lldb.runHooks are processed/populated.
843        """
844        if not lldb.runHooks:
845            self.skipTest("No runhooks specified for lldb, skip the test")
846        if use_cmd_api:
847            for hook in lldb.runhooks:
848                self.runCmd(hook)
849        else:
850            if not child or not child_prompt:
851                self.fail("Both child and child_prompt need to be defined.")
852            for hook in lldb.runHooks:
853                child.sendline(hook)
854                child.expect_exact(child_prompt)
855
856    def setAsync(self, value):
857        """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
858        old_async = self.dbg.GetAsync()
859        self.dbg.SetAsync(value)
860        self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
861
862    def cleanupSubprocesses(self):
863        # Ensure any subprocesses are cleaned up
864        for p in self.subprocesses:
865            if p.poll() == None:
866                p.terminate()
867            del p
868        del self.subprocesses[:]
869
870    def spawnSubprocess(self, executable, args=[]):
871        """ Creates a subprocess.Popen object with the specified executable and arguments,
872            saves it in self.subprocesses, and returns the object.
873            NOTE: if using this function, ensure you also call:
874
875              self.addTearDownHook(self.cleanupSubprocesses)
876
877            otherwise the test suite will leak processes.
878        """
879
880        # Don't display the stdout if not in TraceOn() mode.
881        proc = Popen([executable] + args,
882                     stdout = open(os.devnull) if not self.TraceOn() else None,
883                     stdin = PIPE)
884        self.subprocesses.append(proc)
885        return proc
886
887    def HideStdout(self):
888        """Hide output to stdout from the user.
889
890        During test execution, there might be cases where we don't want to show the
891        standard output to the user.  For example,
892
893            self.runCmd(r'''sc print "\n\n\tHello!\n"''')
894
895        tests whether command abbreviation for 'script' works or not.  There is no
896        need to show the 'Hello' output to the user as long as the 'script' command
897        succeeds and we are not in TraceOn() mode (see the '-t' option).
898
899        In this case, the test method calls self.HideStdout(self) to redirect the
900        sys.stdout to a null device, and restores the sys.stdout upon teardown.
901
902        Note that you should only call this method at most once during a test case
903        execution.  Any subsequent call has no effect at all."""
904        if self.sys_stdout_hidden:
905            return
906
907        self.sys_stdout_hidden = True
908        old_stdout = sys.stdout
909        sys.stdout = open(os.devnull, 'w')
910        def restore_stdout():
911            sys.stdout = old_stdout
912        self.addTearDownHook(restore_stdout)
913
914    # =======================================================================
915    # Methods for customized teardown cleanups as well as execution of hooks.
916    # =======================================================================
917
918    def setTearDownCleanup(self, dictionary=None):
919        """Register a cleanup action at tearDown() time with a dictinary"""
920        self.dict = dictionary
921        self.doTearDownCleanup = True
922
923    def addTearDownCleanup(self, dictionary):
924        """Add a cleanup action at tearDown() time with a dictinary"""
925        self.dicts.append(dictionary)
926        self.doTearDownCleanups = True
927
928    def addTearDownHook(self, hook):
929        """
930        Add a function to be run during tearDown() time.
931
932        Hooks are executed in a first come first serve manner.
933        """
934        if callable(hook):
935            with recording(self, traceAlways) as sbuf:
936                print >> sbuf, "Adding tearDown hook:", getsource_if_available(hook)
937            self.hooks.append(hook)
938
939    def tearDown(self):
940        """Fixture for unittest test case teardown."""
941        #import traceback
942        #traceback.print_stack()
943
944        # This is for the case of directly spawning 'lldb' and interacting with it
945        # using pexpect.
946        import pexpect
947        if self.child and self.child.isalive():
948            with recording(self, traceAlways) as sbuf:
949                print >> sbuf, "tearing down the child process...."
950            try:
951                if self.child_in_script_interpreter:
952                    self.child.sendline('quit()')
953                    self.child.expect_exact(self.child_prompt)
954                self.child.sendline('settings set interpreter.prompt-on-quit false')
955                self.child.sendline('quit')
956                self.child.expect(pexpect.EOF)
957            except ValueError, ExceptionPexpect:
958                # child is already terminated
959                pass
960
961            # Give it one final blow to make sure the child is terminated.
962            self.child.close()
963
964        # Check and run any hook functions.
965        for hook in reversed(self.hooks):
966            with recording(self, traceAlways) as sbuf:
967                print >> sbuf, "Executing tearDown hook:", getsource_if_available(hook)
968            hook()
969
970        del self.hooks
971
972        # Perform registered teardown cleanup.
973        if doCleanup and self.doTearDownCleanup:
974            self.cleanup(dictionary=self.dict)
975
976        # In rare cases where there are multiple teardown cleanups added.
977        if doCleanup and self.doTearDownCleanups:
978            if self.dicts:
979                for dict in reversed(self.dicts):
980                    self.cleanup(dictionary=dict)
981
982        # Decide whether to dump the session info.
983        self.dumpSessionInfo()
984
985    # =========================================================
986    # Various callbacks to allow introspection of test progress
987    # =========================================================
988
989    def markError(self):
990        """Callback invoked when an error (unexpected exception) errored."""
991        self.__errored__ = True
992        with recording(self, False) as sbuf:
993            # False because there's no need to write "ERROR" to the stderr twice.
994            # Once by the Python unittest framework, and a second time by us.
995            print >> sbuf, "ERROR"
996
997    def markFailure(self):
998        """Callback invoked when a failure (test assertion failure) occurred."""
999        self.__failed__ = True
1000        with recording(self, False) as sbuf:
1001            # False because there's no need to write "FAIL" to the stderr twice.
1002            # Once by the Python unittest framework, and a second time by us.
1003            print >> sbuf, "FAIL"
1004
1005    def markExpectedFailure(self,err,bugnumber):
1006        """Callback invoked when an expected failure/error occurred."""
1007        self.__expected__ = True
1008        with recording(self, False) as sbuf:
1009            # False because there's no need to write "expected failure" to the
1010            # stderr twice.
1011            # Once by the Python unittest framework, and a second time by us.
1012            if bugnumber == None:
1013                print >> sbuf, "expected failure"
1014            else:
1015                print >> sbuf, "expected failure (problem id:" + str(bugnumber) + ")"
1016
1017    def markSkippedTest(self):
1018        """Callback invoked when a test is skipped."""
1019        self.__skipped__ = True
1020        with recording(self, False) as sbuf:
1021            # False because there's no need to write "skipped test" to the
1022            # stderr twice.
1023            # Once by the Python unittest framework, and a second time by us.
1024            print >> sbuf, "skipped test"
1025
1026    def markUnexpectedSuccess(self, bugnumber):
1027        """Callback invoked when an unexpected success occurred."""
1028        self.__unexpected__ = True
1029        with recording(self, False) as sbuf:
1030            # False because there's no need to write "unexpected success" to the
1031            # stderr twice.
1032            # Once by the Python unittest framework, and a second time by us.
1033            if bugnumber == None:
1034                print >> sbuf, "unexpected success"
1035            else:
1036                print >> sbuf, "unexpected success (problem id:" + str(bugnumber) + ")"
1037
1038    def dumpSessionInfo(self):
1039        """
1040        Dump the debugger interactions leading to a test error/failure.  This
1041        allows for more convenient postmortem analysis.
1042
1043        See also LLDBTestResult (dotest.py) which is a singlton class derived
1044        from TextTestResult and overwrites addError, addFailure, and
1045        addExpectedFailure methods to allow us to to mark the test instance as
1046        such.
1047        """
1048
1049        # We are here because self.tearDown() detected that this test instance
1050        # either errored or failed.  The lldb.test_result singleton contains
1051        # two lists (erros and failures) which get populated by the unittest
1052        # framework.  Look over there for stack trace information.
1053        #
1054        # The lists contain 2-tuples of TestCase instances and strings holding
1055        # formatted tracebacks.
1056        #
1057        # See http://docs.python.org/library/unittest.html#unittest.TestResult.
1058        if self.__errored__:
1059            pairs = lldb.test_result.errors
1060            prefix = 'Error'
1061        elif self.__failed__:
1062            pairs = lldb.test_result.failures
1063            prefix = 'Failure'
1064        elif self.__expected__:
1065            pairs = lldb.test_result.expectedFailures
1066            prefix = 'ExpectedFailure'
1067        elif self.__skipped__:
1068            prefix = 'SkippedTest'
1069        elif self.__unexpected__:
1070            prefix = "UnexpectedSuccess"
1071        else:
1072            # Simply return, there's no session info to dump!
1073            return
1074
1075        if not self.__unexpected__ and not self.__skipped__:
1076            for test, traceback in pairs:
1077                if test is self:
1078                    print >> self.session, traceback
1079
1080        testMethod = getattr(self, self._testMethodName)
1081        if getattr(testMethod, "__benchmarks_test__", False):
1082            benchmarks = True
1083        else:
1084            benchmarks = False
1085
1086        # This records the compiler version used for the test.
1087        system([self.getCompiler(), "-v"], sender=self)
1088
1089        dname = os.path.join(os.environ["LLDB_TEST"],
1090                             os.environ["LLDB_SESSION_DIRNAME"])
1091        if not os.path.isdir(dname):
1092            os.mkdir(dname)
1093        fname = os.path.join(dname, "%s-%s-%s-%s.log" % (prefix, self.getArchitecture(), "_".join(self.getCompiler().split('/')), self.id()))
1094        with open(fname, "w") as f:
1095            import datetime
1096            print >> f, "Session info generated @", datetime.datetime.now().ctime()
1097            print >> f, self.session.getvalue()
1098            print >> f, "To rerun this test, issue the following command from the 'test' directory:\n"
1099            print >> f, "./dotest.py %s -v %s -f %s.%s" % (self.getRunOptions(),
1100                                                           ('+b' if benchmarks else '-t'),
1101                                                           self.__class__.__name__,
1102                                                           self._testMethodName)
1103
1104    # ====================================================
1105    # Config. methods supported through a plugin interface
1106    # (enables reading of the current test configuration)
1107    # ====================================================
1108
1109    def getArchitecture(self):
1110        """Returns the architecture in effect the test suite is running with."""
1111        module = builder_module()
1112        return module.getArchitecture()
1113
1114    def getCompiler(self):
1115        """Returns the compiler in effect the test suite is running with."""
1116        module = builder_module()
1117        return module.getCompiler()
1118
1119    def getCompilerVersion(self):
1120        """ Returns a string that represents the compiler version.
1121            Supports: llvm, clang.
1122        """
1123        from lldbutil import which
1124        version = 'unknown'
1125
1126        compiler = self.getCompiler()
1127        version_output = system([which(compiler), "-v"])[1]
1128        for line in version_output.split(os.linesep):
1129            m = re.search('version ([0-9\.]+)', line)
1130            if m:
1131                version = m.group(1)
1132        return version
1133
1134    def getRunOptions(self):
1135        """Command line option for -A and -C to run this test again, called from
1136        self.dumpSessionInfo()."""
1137        arch = self.getArchitecture()
1138        comp = self.getCompiler()
1139        if arch:
1140            option_str = "-A " + arch
1141        else:
1142            option_str = ""
1143        if comp:
1144            option_str += " -C " + comp
1145        return option_str
1146
1147    # ==================================================
1148    # Build methods supported through a plugin interface
1149    # ==================================================
1150
1151    def buildDriver(self, sources, exe_name):
1152        """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
1153            or LLDB.framework).
1154        """
1155        if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
1156          stdflag = "-std=c++0x"
1157        else:
1158          stdflag = "-std=c++11"
1159
1160        if sys.platform.startswith("darwin"):
1161            dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
1162            d = {'CXX_SOURCES' : sources,
1163                 'EXE' : exe_name,
1164                 'CFLAGS_EXTRAS' : "%s -stdlib=libc++" % stdflag,
1165                 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
1166                 'LD_EXTRAS' : dsym,
1167                }
1168        elif sys.platform.startswith("linux") or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
1169            d = {'CXX_SOURCES' : sources,
1170                 'EXE' : exe_name,
1171                 'CFLAGS_EXTRAS' : "%s -I%s" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
1172                 'LD_EXTRAS' : "-L%s -llldb" % self.lib_dir}
1173        if self.TraceOn():
1174            print "Building LLDB Driver (%s) from sources %s" % (exe_name, sources)
1175
1176        self.buildDefault(dictionary=d)
1177
1178    def buildProgram(self, sources, exe_name):
1179        """ Platform specific way to build an executable from C/C++ sources. """
1180        d = {'CXX_SOURCES' : sources,
1181             'EXE' : exe_name}
1182        self.buildDefault(dictionary=d)
1183
1184    def buildDefault(self, architecture=None, compiler=None, dictionary=None, clean=True):
1185        """Platform specific way to build the default binaries."""
1186        if lldb.skip_build_and_cleanup:
1187            return
1188        module = builder_module()
1189        if not module.buildDefault(self, architecture, compiler, dictionary, clean):
1190            raise Exception("Don't know how to build default binary")
1191
1192    def buildDsym(self, architecture=None, compiler=None, dictionary=None, clean=True):
1193        """Platform specific way to build binaries with dsym info."""
1194        if lldb.skip_build_and_cleanup:
1195            return
1196        module = builder_module()
1197        if not module.buildDsym(self, architecture, compiler, dictionary, clean):
1198            raise Exception("Don't know how to build binary with dsym")
1199
1200    def buildDwarf(self, architecture=None, compiler=None, dictionary=None, clean=True):
1201        """Platform specific way to build binaries with dwarf maps."""
1202        if lldb.skip_build_and_cleanup:
1203            return
1204        module = builder_module()
1205        if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
1206            raise Exception("Don't know how to build binary with dwarf")
1207
1208    def cleanup(self, dictionary=None):
1209        """Platform specific way to do cleanup after build."""
1210        if lldb.skip_build_and_cleanup:
1211            return
1212        module = builder_module()
1213        if not module.cleanup(self, dictionary):
1214            raise Exception("Don't know how to do cleanup with dictionary: "+dictionary)
1215
1216    def getLLDBLibraryEnvVal(self):
1217        """ Returns the path that the OS-specific library search environment variable
1218            (self.dylibPath) should be set to in order for a program to find the LLDB
1219            library. If an environment variable named self.dylibPath is already set,
1220            the new path is appended to it and returned.
1221        """
1222        existing_library_path = os.environ[self.dylibPath] if self.dylibPath in os.environ else None
1223        if existing_library_path:
1224            return "%s:%s" % (existing_library_path, self.lib_dir)
1225        elif sys.platform.startswith("darwin"):
1226            return os.path.join(self.lib_dir, 'LLDB.framework')
1227        else:
1228            return self.lib_dir
1229
1230class TestBase(Base):
1231    """
1232    This abstract base class is meant to be subclassed.  It provides default
1233    implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
1234    among other things.
1235
1236    Important things for test class writers:
1237
1238        - Overwrite the mydir class attribute, otherwise your test class won't
1239          run.  It specifies the relative directory to the top level 'test' so
1240          the test harness can change to the correct working directory before
1241          running your test.
1242
1243        - The setUp method sets up things to facilitate subsequent interactions
1244          with the debugger as part of the test.  These include:
1245              - populate the test method name
1246              - create/get a debugger set with synchronous mode (self.dbg)
1247              - get the command interpreter from with the debugger (self.ci)
1248              - create a result object for use with the command interpreter
1249                (self.res)
1250              - plus other stuffs
1251
1252        - The tearDown method tries to perform some necessary cleanup on behalf
1253          of the test to return the debugger to a good state for the next test.
1254          These include:
1255              - execute any tearDown hooks registered by the test method with
1256                TestBase.addTearDownHook(); examples can be found in
1257                settings/TestSettings.py
1258              - kill the inferior process associated with each target, if any,
1259                and, then delete the target from the debugger's target list
1260              - perform build cleanup before running the next test method in the
1261                same test class; examples of registering for this service can be
1262                found in types/TestIntegerTypes.py with the call:
1263                    - self.setTearDownCleanup(dictionary=d)
1264
1265        - Similarly setUpClass and tearDownClass perform classwise setup and
1266          teardown fixtures.  The tearDownClass method invokes a default build
1267          cleanup for the entire test class;  also, subclasses can implement the
1268          classmethod classCleanup(cls) to perform special class cleanup action.
1269
1270        - The instance methods runCmd and expect are used heavily by existing
1271          test cases to send a command to the command interpreter and to perform
1272          string/pattern matching on the output of such command execution.  The
1273          expect method also provides a mode to peform string/pattern matching
1274          without running a command.
1275
1276        - The build methods buildDefault, buildDsym, and buildDwarf are used to
1277          build the binaries used during a particular test scenario.  A plugin
1278          should be provided for the sys.platform running the test suite.  The
1279          Mac OS X implementation is located in plugins/darwin.py.
1280    """
1281
1282    # Maximum allowed attempts when launching the inferior process.
1283    # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
1284    maxLaunchCount = 3;
1285
1286    # Time to wait before the next launching attempt in second(s).
1287    # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
1288    timeWaitNextLaunch = 1.0;
1289
1290    def doDelay(self):
1291        """See option -w of dotest.py."""
1292        if ("LLDB_WAIT_BETWEEN_TEST_CASES" in os.environ and
1293            os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] == 'YES'):
1294            waitTime = 1.0
1295            if "LLDB_TIME_WAIT_BETWEEN_TEST_CASES" in os.environ:
1296                waitTime = float(os.environ["LLDB_TIME_WAIT_BETWEEN_TEST_CASES"])
1297            time.sleep(waitTime)
1298
1299    # Returns the list of categories to which this test case belongs
1300    # by default, look for a ".categories" file, and read its contents
1301    # if no such file exists, traverse the hierarchy - we guarantee
1302    # a .categories to exist at the top level directory so we do not end up
1303    # looping endlessly - subclasses are free to define their own categories
1304    # in whatever way makes sense to them
1305    def getCategories(self):
1306        import inspect
1307        import os.path
1308        folder = inspect.getfile(self.__class__)
1309        folder = os.path.dirname(folder)
1310        while folder != '/':
1311                categories_file_name = os.path.join(folder,".categories")
1312                if os.path.exists(categories_file_name):
1313                        categories_file = open(categories_file_name,'r')
1314                        categories = categories_file.readline()
1315                        categories_file.close()
1316                        categories = str.replace(categories,'\n','')
1317                        categories = str.replace(categories,'\r','')
1318                        return categories.split(',')
1319                else:
1320                        folder = os.path.dirname(folder)
1321                        continue
1322
1323    def setUp(self):
1324        #import traceback
1325        #traceback.print_stack()
1326
1327        # Works with the test driver to conditionally skip tests via decorators.
1328        Base.setUp(self)
1329
1330        try:
1331            if lldb.blacklist:
1332                className = self.__class__.__name__
1333                classAndMethodName = "%s.%s" % (className, self._testMethodName)
1334                if className in lldb.blacklist:
1335                    self.skipTest(lldb.blacklist.get(className))
1336                elif classAndMethodName in lldb.blacklist:
1337                    self.skipTest(lldb.blacklist.get(classAndMethodName))
1338        except AttributeError:
1339            pass
1340
1341        # Insert some delay between successive test cases if specified.
1342        self.doDelay()
1343
1344        if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
1345            self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
1346
1347        if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
1348            self.timeWaitNextLaunch = float(os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
1349
1350        # Create the debugger instance if necessary.
1351        try:
1352            self.dbg = lldb.DBG
1353        except AttributeError:
1354            self.dbg = lldb.SBDebugger.Create()
1355
1356        if not self.dbg:
1357            raise Exception('Invalid debugger instance')
1358
1359        # We want our debugger to be synchronous.
1360        self.dbg.SetAsync(False)
1361
1362        # Retrieve the associated command interpreter instance.
1363        self.ci = self.dbg.GetCommandInterpreter()
1364        if not self.ci:
1365            raise Exception('Could not get the command interpreter')
1366
1367        # And the result object.
1368        self.res = lldb.SBCommandReturnObject()
1369
1370        # Run global pre-flight code, if defined via the config file.
1371        if lldb.pre_flight:
1372            lldb.pre_flight(self)
1373
1374    # utility methods that tests can use to access the current objects
1375    def target(self):
1376        if not self.dbg:
1377            raise Exception('Invalid debugger instance')
1378        return self.dbg.GetSelectedTarget()
1379
1380    def process(self):
1381        if not self.dbg:
1382            raise Exception('Invalid debugger instance')
1383        return self.dbg.GetSelectedTarget().GetProcess()
1384
1385    def thread(self):
1386        if not self.dbg:
1387            raise Exception('Invalid debugger instance')
1388        return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
1389
1390    def frame(self):
1391        if not self.dbg:
1392            raise Exception('Invalid debugger instance')
1393        return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
1394
1395    def tearDown(self):
1396        #import traceback
1397        #traceback.print_stack()
1398
1399        Base.tearDown(self)
1400
1401        # Delete the target(s) from the debugger as a general cleanup step.
1402        # This includes terminating the process for each target, if any.
1403        # We'd like to reuse the debugger for our next test without incurring
1404        # the initialization overhead.
1405        targets = []
1406        for target in self.dbg:
1407            if target:
1408                targets.append(target)
1409                process = target.GetProcess()
1410                if process:
1411                    rc = self.invoke(process, "Kill")
1412                    self.assertTrue(rc.Success(), PROCESS_KILLED)
1413        for target in targets:
1414            self.dbg.DeleteTarget(target)
1415
1416        # Run global post-flight code, if defined via the config file.
1417        if lldb.post_flight:
1418            lldb.post_flight(self)
1419
1420        del self.dbg
1421
1422    def switch_to_thread_with_stop_reason(self, stop_reason):
1423        """
1424        Run the 'thread list' command, and select the thread with stop reason as
1425        'stop_reason'.  If no such thread exists, no select action is done.
1426        """
1427        from lldbutil import stop_reason_to_str
1428        self.runCmd('thread list')
1429        output = self.res.GetOutput()
1430        thread_line_pattern = re.compile("^[ *] thread #([0-9]+):.*stop reason = %s" %
1431                                         stop_reason_to_str(stop_reason))
1432        for line in output.splitlines():
1433            matched = thread_line_pattern.match(line)
1434            if matched:
1435                self.runCmd('thread select %s' % matched.group(1))
1436
1437    def runCmd(self, cmd, msg=None, check=True, trace=False):
1438        """
1439        Ask the command interpreter to handle the command and then check its
1440        return status.
1441        """
1442        # Fail fast if 'cmd' is not meaningful.
1443        if not cmd or len(cmd) == 0:
1444            raise Exception("Bad 'cmd' parameter encountered")
1445
1446        trace = (True if traceAlways else trace)
1447
1448        running = (cmd.startswith("run") or cmd.startswith("process launch"))
1449
1450        for i in range(self.maxLaunchCount if running else 1):
1451            self.ci.HandleCommand(cmd, self.res)
1452
1453            with recording(self, trace) as sbuf:
1454                print >> sbuf, "runCmd:", cmd
1455                if not check:
1456                    print >> sbuf, "check of return status not required"
1457                if self.res.Succeeded():
1458                    print >> sbuf, "output:", self.res.GetOutput()
1459                else:
1460                    print >> sbuf, "runCmd failed!"
1461                    print >> sbuf, self.res.GetError()
1462
1463            if self.res.Succeeded():
1464                break
1465            elif running:
1466                # For process launch, wait some time before possible next try.
1467                time.sleep(self.timeWaitNextLaunch)
1468                with recording(self, trace) as sbuf:
1469                    print >> sbuf, "Command '" + cmd + "' failed!"
1470
1471        if check:
1472            self.assertTrue(self.res.Succeeded(),
1473                            msg if msg else CMD_MSG(cmd))
1474
1475    def match (self, str, patterns, msg=None, trace=False, error=False, matching=True, exe=True):
1476        """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
1477
1478        Otherwise, all the arguments have the same meanings as for the expect function"""
1479
1480        trace = (True if traceAlways else trace)
1481
1482        if exe:
1483            # First run the command.  If we are expecting error, set check=False.
1484            # Pass the assert message along since it provides more semantic info.
1485            self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error)
1486
1487            # Then compare the output against expected strings.
1488            output = self.res.GetError() if error else self.res.GetOutput()
1489
1490            # If error is True, the API client expects the command to fail!
1491            if error:
1492                self.assertFalse(self.res.Succeeded(),
1493                                 "Command '" + str + "' is expected to fail!")
1494        else:
1495            # No execution required, just compare str against the golden input.
1496            output = str
1497            with recording(self, trace) as sbuf:
1498                print >> sbuf, "looking at:", output
1499
1500        # The heading says either "Expecting" or "Not expecting".
1501        heading = "Expecting" if matching else "Not expecting"
1502
1503        for pattern in patterns:
1504            # Match Objects always have a boolean value of True.
1505            match_object = re.search(pattern, output)
1506            matched = bool(match_object)
1507            with recording(self, trace) as sbuf:
1508                print >> sbuf, "%s pattern: %s" % (heading, pattern)
1509                print >> sbuf, "Matched" if matched else "Not matched"
1510            if matched:
1511                break
1512
1513        self.assertTrue(matched if matching else not matched,
1514                        msg if msg else EXP_MSG(str, exe))
1515
1516        return match_object
1517
1518    def expect(self, str, msg=None, patterns=None, startstr=None, endstr=None, substrs=None, trace=False, error=False, matching=True, exe=True):
1519        """
1520        Similar to runCmd; with additional expect style output matching ability.
1521
1522        Ask the command interpreter to handle the command and then check its
1523        return status.  The 'msg' parameter specifies an informational assert
1524        message.  We expect the output from running the command to start with
1525        'startstr', matches the substrings contained in 'substrs', and regexp
1526        matches the patterns contained in 'patterns'.
1527
1528        If the keyword argument error is set to True, it signifies that the API
1529        client is expecting the command to fail.  In this case, the error stream
1530        from running the command is retrieved and compared against the golden
1531        input, instead.
1532
1533        If the keyword argument matching is set to False, it signifies that the API
1534        client is expecting the output of the command not to match the golden
1535        input.
1536
1537        Finally, the required argument 'str' represents the lldb command to be
1538        sent to the command interpreter.  In case the keyword argument 'exe' is
1539        set to False, the 'str' is treated as a string to be matched/not-matched
1540        against the golden input.
1541        """
1542        trace = (True if traceAlways else trace)
1543
1544        if exe:
1545            # First run the command.  If we are expecting error, set check=False.
1546            # Pass the assert message along since it provides more semantic info.
1547            self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error)
1548
1549            # Then compare the output against expected strings.
1550            output = self.res.GetError() if error else self.res.GetOutput()
1551
1552            # If error is True, the API client expects the command to fail!
1553            if error:
1554                self.assertFalse(self.res.Succeeded(),
1555                                 "Command '" + str + "' is expected to fail!")
1556        else:
1557            # No execution required, just compare str against the golden input.
1558            if isinstance(str,lldb.SBCommandReturnObject):
1559                output = str.GetOutput()
1560            else:
1561                output = str
1562            with recording(self, trace) as sbuf:
1563                print >> sbuf, "looking at:", output
1564
1565        # The heading says either "Expecting" or "Not expecting".
1566        heading = "Expecting" if matching else "Not expecting"
1567
1568        # Start from the startstr, if specified.
1569        # If there's no startstr, set the initial state appropriately.
1570        matched = output.startswith(startstr) if startstr else (True if matching else False)
1571
1572        if startstr:
1573            with recording(self, trace) as sbuf:
1574                print >> sbuf, "%s start string: %s" % (heading, startstr)
1575                print >> sbuf, "Matched" if matched else "Not matched"
1576
1577        # Look for endstr, if specified.
1578        keepgoing = matched if matching else not matched
1579        if endstr:
1580            matched = output.endswith(endstr)
1581            with recording(self, trace) as sbuf:
1582                print >> sbuf, "%s end string: %s" % (heading, endstr)
1583                print >> sbuf, "Matched" if matched else "Not matched"
1584
1585        # Look for sub strings, if specified.
1586        keepgoing = matched if matching else not matched
1587        if substrs and keepgoing:
1588            for str in substrs:
1589                matched = output.find(str) != -1
1590                with recording(self, trace) as sbuf:
1591                    print >> sbuf, "%s sub string: %s" % (heading, str)
1592                    print >> sbuf, "Matched" if matched else "Not matched"
1593                keepgoing = matched if matching else not matched
1594                if not keepgoing:
1595                    break
1596
1597        # Search for regular expression patterns, if specified.
1598        keepgoing = matched if matching else not matched
1599        if patterns and keepgoing:
1600            for pattern in patterns:
1601                # Match Objects always have a boolean value of True.
1602                matched = bool(re.search(pattern, output))
1603                with recording(self, trace) as sbuf:
1604                    print >> sbuf, "%s pattern: %s" % (heading, pattern)
1605                    print >> sbuf, "Matched" if matched else "Not matched"
1606                keepgoing = matched if matching else not matched
1607                if not keepgoing:
1608                    break
1609
1610        self.assertTrue(matched if matching else not matched,
1611                        msg if msg else EXP_MSG(str, exe))
1612
1613    def invoke(self, obj, name, trace=False):
1614        """Use reflection to call a method dynamically with no argument."""
1615        trace = (True if traceAlways else trace)
1616
1617        method = getattr(obj, name)
1618        import inspect
1619        self.assertTrue(inspect.ismethod(method),
1620                        name + "is a method name of object: " + str(obj))
1621        result = method()
1622        with recording(self, trace) as sbuf:
1623            print >> sbuf, str(method) + ":",  result
1624        return result
1625
1626    # =================================================
1627    # Misc. helper methods for debugging test execution
1628    # =================================================
1629
1630    def DebugSBValue(self, val):
1631        """Debug print a SBValue object, if traceAlways is True."""
1632        from lldbutil import value_type_to_str
1633
1634        if not traceAlways:
1635            return
1636
1637        err = sys.stderr
1638        err.write(val.GetName() + ":\n")
1639        err.write('\t' + "TypeName         -> " + val.GetTypeName()            + '\n')
1640        err.write('\t' + "ByteSize         -> " + str(val.GetByteSize())       + '\n')
1641        err.write('\t' + "NumChildren      -> " + str(val.GetNumChildren())    + '\n')
1642        err.write('\t' + "Value            -> " + str(val.GetValue())          + '\n')
1643        err.write('\t' + "ValueAsUnsigned  -> " + str(val.GetValueAsUnsigned())+ '\n')
1644        err.write('\t' + "ValueType        -> " + value_type_to_str(val.GetValueType()) + '\n')
1645        err.write('\t' + "Summary          -> " + str(val.GetSummary())        + '\n')
1646        err.write('\t' + "IsPointerType    -> " + str(val.TypeIsPointerType()) + '\n')
1647        err.write('\t' + "Location         -> " + val.GetLocation()            + '\n')
1648
1649    def DebugSBType(self, type):
1650        """Debug print a SBType object, if traceAlways is True."""
1651        if not traceAlways:
1652            return
1653
1654        err = sys.stderr
1655        err.write(type.GetName() + ":\n")
1656        err.write('\t' + "ByteSize        -> " + str(type.GetByteSize())     + '\n')
1657        err.write('\t' + "IsPointerType   -> " + str(type.IsPointerType())   + '\n')
1658        err.write('\t' + "IsReferenceType -> " + str(type.IsReferenceType()) + '\n')
1659
1660    def DebugPExpect(self, child):
1661        """Debug the spwaned pexpect object."""
1662        if not traceAlways:
1663            return
1664
1665        print child
1666
1667    @classmethod
1668    def RemoveTempFile(cls, file):
1669        if os.path.exists(file):
1670            os.remove(file)
1671