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