AbstractBase.py revision 0bfa859ea49d27efd89d5f152b8371b39919d92d
1"""
2Abstract base class of basic types provides a generic type tester method.
3"""
4
5import os, time
6import re
7import lldb
8from lldbtest import *
9
10def Msg(var, val, using_frame_variable):
11    return "'%s %s' matches the output (from compiled code): %s" % (
12        'frame variable -t' if using_frame_variable else 'expression' ,var, val)
13
14class GenericTester(TestBase):
15
16    # This is the pattern by design to match the " var = 'value'" output from
17    # printf() stmts (see basic_type.cpp).
18    pattern = re.compile(" (\*?a[^=]*) = '([^=]*)'$")
19
20    # Assert message.
21    DATA_TYPE_GROKKED = "Data type from expr parser output is parsed correctly"
22
23    def generic_type_tester(self, atoms, quotedDisplay=False):
24        """Test that variables with basic types are displayed correctly."""
25
26        # First, capture the golden output emitted by the oracle, i.e., the
27        # series of printf statements.
28        go = system("./a.out", sender=self)[0]
29        # This golden list contains a list of (variable, value) pairs extracted
30        # from the golden output.
31        gl = []
32
33        # Scan the golden output line by line, looking for the pattern:
34        #
35        #     variable = 'value'
36        #
37        for line in go.split(os.linesep):
38            match = self.pattern.search(line)
39            if match:
40                var, val = match.group(1), match.group(2)
41                gl.append((var, val))
42        #print "golden list:", gl
43
44        # Bring the program to the point where we can issue a series of
45        # 'frame variable -t' command.
46        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
47        self.runCmd("breakpoint set --name Puts")
48        self.runCmd("run", RUN_SUCCEEDED)
49        self.runCmd("thread step-out", STEP_OUT_SUCCEEDED)
50
51        #self.runCmd("frame variable -t")
52
53        # Now iterate through the golden list, comparing against the output from
54        # 'frame variable -t var'.
55        for var, val in gl:
56            self.runCmd("frame variable -t %s" % var)
57            output = self.res.GetOutput()
58
59            # The input type is in a canonical form as a set of named atoms.
60            # The display type string must conatin each and every element.
61            #
62            # Example:
63            #     runCmd: frame variable -t a_array_bounded[0]
64            #     output: (char) a_array_bounded[0] = 'a'
65            #
66            try:
67                dt = re.match("^\((.*)\)", output).group(1)
68            except:
69                self.fail(self.DATA_TYPE_GROKKED)
70
71            # Expect the display type string to contain each and every atoms.
72            self.expect(dt,
73                        "Display type: '%s' must contain the type atoms: '%s'" %
74                        (dt, atoms),
75                        exe=False,
76                substrs = list(atoms))
77
78            # The (var, val) pair must match, too.
79            nv = ("%s = '%s'" if quotedDisplay else "%s = %s") % (var, val)
80            self.expect(output, Msg(var, val, True), exe=False,
81                substrs = [nv])
82
83    def generic_type_expr_tester(self, atoms, quotedDisplay=False):
84        """Test that variable expressions with basic types are evaluated correctly."""
85
86        # First, capture the golden output emitted by the oracle, i.e., the
87        # series of printf statements.
88        go = system("./a.out", sender=self)[0]
89        # This golden list contains a list of (variable, value) pairs extracted
90        # from the golden output.
91        gl = []
92
93        # Scan the golden output line by line, looking for the pattern:
94        #
95        #     variable = 'value'
96        #
97        for line in go.split(os.linesep):
98            match = self.pattern.search(line)
99            if match:
100                var, val = match.group(1), match.group(2)
101                gl.append((var, val))
102        #print "golden list:", gl
103
104        # Bring the program to the point where we can issue a series of
105        # 'expr' command.
106        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
107        self.runCmd("breakpoint set --name Puts")
108        self.runCmd("run", RUN_SUCCEEDED)
109        self.runCmd("thread step-out", STEP_OUT_SUCCEEDED)
110
111        #self.runCmd("frame variable -t")
112
113        # Now iterate through the golden list, comparing against the output from
114        # 'expr var'.
115        for var, val in gl:
116            # Don't overwhelm the expression mechanism.
117            # This slows down the test suite quite a bit, to enable it, define
118            # the environment variable LLDB_TYPES_EXPR_TIME_WAIT.  For example:
119            #
120            #     export LLDB_TYPES_EXPR_TIME_WAIT=0.5
121            #
122            # causes a 0.5 second delay between 'expression' commands.
123            if "LLDB_TYPES_EXPR_TIME_WAIT" in os.environ:
124                time.sleep(float(os.environ["LLDB_TYPES_EXPR_TIME_WAIT"]))
125
126            self.runCmd("expression %s" % var)
127            output = self.res.GetOutput()
128
129            # The input type is in a canonical form as a set named atoms.
130            # The display type string must conatin each and every element.
131            #
132            # Example:
133            #     runCmd: expr a
134            #     output: (double) $0 = 1100.12
135            #
136            try:
137                dt = re.match("^\((.*)\) \$[0-9]+ = ", output).group(1)
138            except:
139                self.fail(self.DATA_TYPE_GROKKED)
140
141            # Expect the display type string to contain each and every atoms.
142            self.expect(dt,
143                        "Display type: '%s' must contain the type atoms: '%s'" %
144                        (dt, atoms),
145                        exe=False,
146                substrs = list(atoms))
147
148            # The val part must match, too.
149            valPart = ("'%s'" if quotedDisplay else "%s") % val
150            self.expect(output, Msg(var, val, False), exe=False,
151                substrs = [valPart])
152