AbstractBase.py revision d062ee862396d29b8c06c60b9e2c38330cf42665
10b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen"""
27c52ff1d83ec262f35c9a825af107735913e7225Johnny ChenAbstract base class of basic types provides a generic type tester method.
30b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen"""
40b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen
50b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chenimport os, time
6091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chenimport re
70b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chenimport lldb
80b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chenfrom lldbtest import *
90b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen
1066a03531e5199f13482e46777f350312a2b950c1Johnny Chendef Msg(var, val, using_frame_variable):
1166a03531e5199f13482e46777f350312a2b950c1Johnny Chen    return "'%s %s' matches the output (from compiled code): %s" % (
1210de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham        'frame variable -T' if using_frame_variable else 'expression' ,var, val)
13091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen
1451a9e00e10d29ba01af7bc2d5efbcf31ec1f76a4Johnny Chenclass GenericTester(TestBase):
150b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen
16091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen    # This is the pattern by design to match the " var = 'value'" output from
17091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen    # printf() stmts (see basic_type.cpp).
18091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen    pattern = re.compile(" (\*?a[^=]*) = '([^=]*)'$")
19091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen
20cdf15137e61a3302c038ee92211cb6ec77a5b04eJohnny Chen    # Assert message.
21cdf15137e61a3302c038ee92211cb6ec77a5b04eJohnny Chen    DATA_TYPE_GROKKED = "Data type from expr parser output is parsed correctly"
22cdf15137e61a3302c038ee92211cb6ec77a5b04eJohnny Chen
23d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen    def setUp(self):
24d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen        # Call super's setUp().
25d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen        TestBase.setUp(self)
26d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen        # We'll use the test method name as the exe_name.
27d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen        # There are a bunch of test cases under test/types and we don't want the
28d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen        # module cacheing subsystem to be confused with executable name "a.out"
29d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen        # used for all the test cases.
30d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen        self.exe_name = self._testMethodName
31d062ee862396d29b8c06c60b9e2c38330cf42665Johnny Chen
322c41e14fd22c79ec2eb0f77dc314e118f04ca232Johnny Chen    def generic_type_tester(self, exe_name, atoms, quotedDisplay=False):
33091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        """Test that variables with basic types are displayed correctly."""
34091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen
35091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        # First, capture the golden output emitted by the oracle, i.e., the
36091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        # series of printf statements.
372c41e14fd22c79ec2eb0f77dc314e118f04ca232Johnny Chen        go = system("./%s" % exe_name, sender=self)[0]
38091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        # This golden list contains a list of (variable, value) pairs extracted
39091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        # from the golden output.
40091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        gl = []
410b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen
42091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        # Scan the golden output line by line, looking for the pattern:
43091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        #
44091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        #     variable = 'value'
45091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        #
46091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        for line in go.split(os.linesep):
47091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen            match = self.pattern.search(line)
48091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen            if match:
49091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen                var, val = match.group(1), match.group(2)
50091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen                gl.append((var, val))
51091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        #print "golden list:", gl
52091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen
53091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        # Bring the program to the point where we can issue a series of
5410de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham        # 'frame variable -T' command.
552c41e14fd22c79ec2eb0f77dc314e118f04ca232Johnny Chen        self.runCmd("file %s" % exe_name, CURRENT_EXECUTABLE_SET)
56c9aabf097245642531d74410ff1371a97991af64Johnny Chen        puts_line = line_number ("basic_type.cpp", "// Here is the line we will break on to check variables")
57e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham        self.expect("breakpoint set -f basic_type.cpp -l %d" % puts_line,
58e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham                    BREAKPOINT_CREATED,
59e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham            startstr = "Breakpoint created: 1: file ='basic_type.cpp', line = %d, locations = 1" %
60e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham                        puts_line)
61e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham
62c9aabf097245642531d74410ff1371a97991af64Johnny Chen        self.runCmd("run", RUN_SUCCEEDED)
63c9aabf097245642531d74410ff1371a97991af64Johnny Chen        self.expect("process status", STOPPED_DUE_TO_BREAKPOINT,
64c9aabf097245642531d74410ff1371a97991af64Johnny Chen            substrs = [" at basic_type.cpp:%d" % puts_line,
65c9aabf097245642531d74410ff1371a97991af64Johnny Chen                       "stop reason = breakpoint"])
660b3ee55c77954ce4359499af2a0c27f1f75c10f1Johnny Chen
6710de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham        #self.runCmd("frame variable -T")
684ec97859ca68e299b5b2beb0313fffeea9d0119eJohnny Chen
69091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        # Now iterate through the golden list, comparing against the output from
7010de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham        # 'frame variable -T var'.
71091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen        for var, val in gl:
7210de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham            self.runCmd("frame variable -T %s" % var)
73091bb1de9d5cd0f974b91da621e638a22f5b03b5Johnny Chen            output = self.res.GetOutput()
74757396a950315670e3400b97b51a081a8dcb4fc3Johnny Chen
7551287a1b5f1524f2e6b14254b41a80908b060668Johnny Chen            # The input type is in a canonical form as a set of named atoms.
768ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen            # The display type string must conatin each and every element.
775a3a3d968116e73a80b917a8d9c54ccdd92e2a8cJohnny Chen            #
785a3a3d968116e73a80b917a8d9c54ccdd92e2a8cJohnny Chen            # Example:
7910de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham            #     runCmd: frame variable -T a_array_bounded[0]
805a3a3d968116e73a80b917a8d9c54ccdd92e2a8cJohnny Chen            #     output: (char) a_array_bounded[0] = 'a'
815a3a3d968116e73a80b917a8d9c54ccdd92e2a8cJohnny Chen            #
825fed90a7c7f5b496bc6e7453b7aaec2ff8e6399dJohnny Chen            try:
835fed90a7c7f5b496bc6e7453b7aaec2ff8e6399dJohnny Chen                dt = re.match("^\((.*)\)", output).group(1)
845fed90a7c7f5b496bc6e7453b7aaec2ff8e6399dJohnny Chen            except:
85cdf15137e61a3302c038ee92211cb6ec77a5b04eJohnny Chen                self.fail(self.DATA_TYPE_GROKKED)
86757396a950315670e3400b97b51a081a8dcb4fc3Johnny Chen
878ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen            # Expect the display type string to contain each and every atoms.
888ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen            self.expect(dt,
898ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen                        "Display type: '%s' must contain the type atoms: '%s'" %
908ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen                        (dt, atoms),
918ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen                        exe=False,
928ba13e6dda85f15dcd83f14d32edbbd99eed2405Johnny Chen                substrs = list(atoms))
93757396a950315670e3400b97b51a081a8dcb4fc3Johnny Chen
94757396a950315670e3400b97b51a081a8dcb4fc3Johnny Chen            # The (var, val) pair must match, too.
9519edbc5223c7ace86c983c3cc6bd9e610cd329c8Johnny Chen            nv = ("%s = '%s'" if quotedDisplay else "%s = %s") % (var, val)
9666a03531e5199f13482e46777f350312a2b950c1Johnny Chen            self.expect(output, Msg(var, val, True), exe=False,
974ec97859ca68e299b5b2beb0313fffeea9d0119eJohnny Chen                substrs = [nv])
98b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen
992c41e14fd22c79ec2eb0f77dc314e118f04ca232Johnny Chen    def generic_type_expr_tester(self, exe_name, atoms, quotedDisplay=False):
100b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        """Test that variable expressions with basic types are evaluated correctly."""
101b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen
102b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        # First, capture the golden output emitted by the oracle, i.e., the
103b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        # series of printf statements.
1042c41e14fd22c79ec2eb0f77dc314e118f04ca232Johnny Chen        go = system("./%s" % exe_name, sender=self)[0]
105b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        # This golden list contains a list of (variable, value) pairs extracted
106b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        # from the golden output.
107b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        gl = []
108b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen
109b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        # Scan the golden output line by line, looking for the pattern:
110b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        #
111b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        #     variable = 'value'
112b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        #
113b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        for line in go.split(os.linesep):
114b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen            match = self.pattern.search(line)
115b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen            if match:
116b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen                var, val = match.group(1), match.group(2)
117b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen                gl.append((var, val))
118b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        #print "golden list:", gl
119b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen
120b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        # Bring the program to the point where we can issue a series of
12134f99221dcb055d3a35b6174e0d818fdb73da878Johnny Chen        # 'expr' command.
1222c41e14fd22c79ec2eb0f77dc314e118f04ca232Johnny Chen        self.runCmd("file %s" % exe_name, CURRENT_EXECUTABLE_SET)
123c9aabf097245642531d74410ff1371a97991af64Johnny Chen        puts_line = line_number ("basic_type.cpp", "// Here is the line we will break on to check variables.")
124e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham        self.expect("breakpoint set -f basic_type.cpp -l %d" % puts_line,
125e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham                    BREAKPOINT_CREATED,
126e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham            startstr = "Breakpoint created: 1: file ='basic_type.cpp', line = %d, locations = 1" %
127e6bd142d9fa7ed149bd37efd8a75637375f165b7Jim Ingham                        puts_line)
128c9aabf097245642531d74410ff1371a97991af64Johnny Chen        self.runCmd("run", RUN_SUCCEEDED)
129c9aabf097245642531d74410ff1371a97991af64Johnny Chen        self.expect("process status", STOPPED_DUE_TO_BREAKPOINT,
130c9aabf097245642531d74410ff1371a97991af64Johnny Chen            substrs = [" at basic_type.cpp:%d" % puts_line,
131c9aabf097245642531d74410ff1371a97991af64Johnny Chen                       "stop reason = breakpoint"])
132b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen
13310de7d1db3ec782ea2ccda1f39c0a40b9c301594Jim Ingham        #self.runCmd("frame variable -T")
134b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen
135b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        # Now iterate through the golden list, comparing against the output from
136c401e37b99cca3482bacb7bc98cc09d69a1cd2acJohnny Chen        # 'expr var'.
137b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen        for var, val in gl:
138118d742036e0a8b04c5efb65a39fa6bbf461aa2fJohnny Chen            # Don't overwhelm the expression mechanism.
13921c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen            # This slows down the test suite quite a bit, to enable it, define
14021c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen            # the environment variable LLDB_TYPES_EXPR_TIME_WAIT.  For example:
14121c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen            #
14221c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen            #     export LLDB_TYPES_EXPR_TIME_WAIT=0.5
14321c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen            #
14421c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen            # causes a 0.5 second delay between 'expression' commands.
14521c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen            if "LLDB_TYPES_EXPR_TIME_WAIT" in os.environ:
14621c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen                time.sleep(float(os.environ["LLDB_TYPES_EXPR_TIME_WAIT"]))
14721c7c21234079dbd52ed25e9a121212663ba242dJohnny Chen
14866a03531e5199f13482e46777f350312a2b950c1Johnny Chen            self.runCmd("expression %s" % var)
149b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen            output = self.res.GetOutput()
150b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen
151b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen            # The input type is in a canonical form as a set named atoms.
152b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen            # The display type string must conatin each and every element.
153bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen            #
154bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen            # Example:
155bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen            #     runCmd: expr a
1566e81fa35eae0a3c6ca8aee19c4bb2f231b6ab912Johnny Chen            #     output: (double) $0 = 1100.12
157bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen            #
158bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen            try:
1596e81fa35eae0a3c6ca8aee19c4bb2f231b6ab912Johnny Chen                dt = re.match("^\((.*)\) \$[0-9]+ = ", output).group(1)
160bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen            except:
161cdf15137e61a3302c038ee92211cb6ec77a5b04eJohnny Chen                self.fail(self.DATA_TYPE_GROKKED)
162b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen
163b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen            # Expect the display type string to contain each and every atoms.
164bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen            self.expect(dt,
165bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen                        "Display type: '%s' must contain the type atoms: '%s'" %
166bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen                        (dt, atoms),
167bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen                        exe=False,
168bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen                substrs = list(atoms))
169b6c15f5bcdf67d4912a29623f1a24fb0316de69fJohnny Chen
170bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen            # The val part must match, too.
171bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen            valPart = ("'%s'" if quotedDisplay else "%s") % val
17266a03531e5199f13482e46777f350312a2b950c1Johnny Chen            self.expect(output, Msg(var, val, False), exe=False,
173bbeb60e635279b68aa70c512cac5127d4c1f1348Johnny Chen                substrs = [valPart])
174