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