1*99451b44SJordan Rupprecht"""
2*99451b44SJordan RupprechtTest lldb data formatter subsystem.
3*99451b44SJordan Rupprecht"""
4*99451b44SJordan Rupprecht
5*99451b44SJordan Rupprecht
6*99451b44SJordan Rupprecht
7*99451b44SJordan Rupprechtimport lldb
8*99451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
9*99451b44SJordan Rupprechtimport lldbsuite.test.lldbutil as lldbutil
10*99451b44SJordan Rupprecht
11*99451b44SJordan Rupprecht
12*99451b44SJordan Rupprechtclass ScriptDataFormatterTestCase(TestBase):
13*99451b44SJordan Rupprecht
14*99451b44SJordan Rupprecht    def test_with_run_command(self):
15*99451b44SJordan Rupprecht        """Test data formatter commands."""
16*99451b44SJordan Rupprecht        self.build()
17*99451b44SJordan Rupprecht        self.data_formatter_commands()
18*99451b44SJordan Rupprecht
19*99451b44SJordan Rupprecht    def setUp(self):
20*99451b44SJordan Rupprecht        # Call super's setUp().
21*99451b44SJordan Rupprecht        TestBase.setUp(self)
22*99451b44SJordan Rupprecht        # Find the line number to break at.
23*99451b44SJordan Rupprecht        self.line = line_number('main.cpp', '// Set break point at this line.')
24*99451b44SJordan Rupprecht
25*99451b44SJordan Rupprecht    def data_formatter_commands(self):
26*99451b44SJordan Rupprecht        """Test that that file and class static variables display correctly."""
27*99451b44SJordan Rupprecht        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
28*99451b44SJordan Rupprecht
29*99451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
30*99451b44SJordan Rupprecht            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
31*99451b44SJordan Rupprecht
32*99451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
33*99451b44SJordan Rupprecht
34*99451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint.
35*99451b44SJordan Rupprecht        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
36*99451b44SJordan Rupprecht                    substrs=['stopped',
37*99451b44SJordan Rupprecht                             'stop reason = breakpoint'])
38*99451b44SJordan Rupprecht
39*99451b44SJordan Rupprecht        # This is the function to remove the custom formats in order to have a
40*99451b44SJordan Rupprecht        # clean slate for the next test case.
41*99451b44SJordan Rupprecht        def cleanup():
42*99451b44SJordan Rupprecht            self.runCmd('type format clear', check=False)
43*99451b44SJordan Rupprecht            self.runCmd('type summary clear', check=False)
44*99451b44SJordan Rupprecht
45*99451b44SJordan Rupprecht        # Execute the cleanup function during test case tear down.
46*99451b44SJordan Rupprecht        self.addTearDownHook(cleanup)
47*99451b44SJordan Rupprecht
48*99451b44SJordan Rupprecht        # Set the script here to ease the formatting
49*99451b44SJordan Rupprecht        script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'Hello from Python, \' + a_val + \' time\'; return str + (\'!\' if a_val == \'1\' else \'s!\');'
50*99451b44SJordan Rupprecht
51*99451b44SJordan Rupprecht        self.runCmd(
52*99451b44SJordan Rupprecht            "type summary add i_am_cool --python-script \"%s\"" %
53*99451b44SJordan Rupprecht            script)
54*99451b44SJordan Rupprecht        self.expect('type summary list i_am_cool', substrs=[script])
55*99451b44SJordan Rupprecht
56*99451b44SJordan Rupprecht        self.expect("frame variable one",
57*99451b44SJordan Rupprecht                    substrs=['Hello from Python',
58*99451b44SJordan Rupprecht                             '1 time!'])
59*99451b44SJordan Rupprecht
60*99451b44SJordan Rupprecht        self.expect("frame variable two",
61*99451b44SJordan Rupprecht                    substrs=['Hello from Python',
62*99451b44SJordan Rupprecht                             '4 times!'])
63*99451b44SJordan Rupprecht
64*99451b44SJordan Rupprecht        self.runCmd("n")  # skip ahead to make values change
65*99451b44SJordan Rupprecht
66*99451b44SJordan Rupprecht        self.expect("frame variable three",
67*99451b44SJordan Rupprecht                    substrs=['Hello from Python, 10 times!',
68*99451b44SJordan Rupprecht                             'Hello from Python, 4 times!'])
69*99451b44SJordan Rupprecht
70*99451b44SJordan Rupprecht        self.runCmd("n")  # skip ahead to make values change
71*99451b44SJordan Rupprecht
72*99451b44SJordan Rupprecht        self.expect("frame variable two",
73*99451b44SJordan Rupprecht                    substrs=['Hello from Python',
74*99451b44SJordan Rupprecht                             '1 time!'])
75*99451b44SJordan Rupprecht
76*99451b44SJordan Rupprecht        script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'int says \' + a_val; return str;'
77*99451b44SJordan Rupprecht
78*99451b44SJordan Rupprecht        # Check that changes in the script are immediately reflected
79*99451b44SJordan Rupprecht        self.runCmd(
80*99451b44SJordan Rupprecht            "type summary add i_am_cool --python-script \"%s\"" %
81*99451b44SJordan Rupprecht            script)
82*99451b44SJordan Rupprecht
83*99451b44SJordan Rupprecht        self.expect("frame variable two",
84*99451b44SJordan Rupprecht                    substrs=['int says 1'])
85*99451b44SJordan Rupprecht
86*99451b44SJordan Rupprecht        self.expect("frame variable twoptr",
87*99451b44SJordan Rupprecht                    substrs=['int says 1'])
88*99451b44SJordan Rupprecht
89*99451b44SJordan Rupprecht        # Change the summary
90*99451b44SJordan Rupprecht        self.runCmd(
91*99451b44SJordan Rupprecht            "type summary add --summary-string \"int says ${var.integer}, and float says ${var.floating}\" i_am_cool")
92*99451b44SJordan Rupprecht
93*99451b44SJordan Rupprecht        self.expect("frame variable two",
94*99451b44SJordan Rupprecht                    substrs=['int says 1',
95*99451b44SJordan Rupprecht                             'and float says 2.71'])
96*99451b44SJordan Rupprecht        # Try it for pointers
97*99451b44SJordan Rupprecht        self.expect("frame variable twoptr",
98*99451b44SJordan Rupprecht                    substrs=['int says 1',
99*99451b44SJordan Rupprecht                             'and float says 2.71'])
100*99451b44SJordan Rupprecht
101*99451b44SJordan Rupprecht        # Force a failure for pointers
102*99451b44SJordan Rupprecht        self.runCmd(
103*99451b44SJordan Rupprecht            "type summary add i_am_cool -p --python-script \"%s\"" %
104*99451b44SJordan Rupprecht            script)
105*99451b44SJordan Rupprecht
106*99451b44SJordan Rupprecht        self.expect("frame variable twoptr", matching=False,
107*99451b44SJordan Rupprecht                    substrs=['and float says 2.71'])
108*99451b44SJordan Rupprecht
109*99451b44SJordan Rupprecht        script = 'return \'Python summary\''
110*99451b44SJordan Rupprecht
111*99451b44SJordan Rupprecht        self.runCmd(
112*99451b44SJordan Rupprecht            "type summary add --name test_summary --python-script \"%s\"" %
113*99451b44SJordan Rupprecht            script)
114*99451b44SJordan Rupprecht
115*99451b44SJordan Rupprecht        # attach the Python named summary to someone
116*99451b44SJordan Rupprecht        self.expect("frame variable one --summary test_summary",
117*99451b44SJordan Rupprecht                    substrs=['Python summary'])
118*99451b44SJordan Rupprecht
119*99451b44SJordan Rupprecht        # should not bind to the type
120*99451b44SJordan Rupprecht        self.expect("frame variable two", matching=False,
121*99451b44SJordan Rupprecht                    substrs=['Python summary'])
122*99451b44SJordan Rupprecht
123*99451b44SJordan Rupprecht        # and should not stick to the variable
124*99451b44SJordan Rupprecht        self.expect("frame variable one", matching=False,
125*99451b44SJordan Rupprecht                    substrs=['Python summary'])
126*99451b44SJordan Rupprecht
127*99451b44SJordan Rupprecht        self.runCmd(
128*99451b44SJordan Rupprecht            "type summary add i_am_cool --summary-string \"Text summary\"")
129*99451b44SJordan Rupprecht
130*99451b44SJordan Rupprecht        # should be temporary only
131*99451b44SJordan Rupprecht        self.expect("frame variable one", matching=False,
132*99451b44SJordan Rupprecht                    substrs=['Python summary'])
133*99451b44SJordan Rupprecht
134*99451b44SJordan Rupprecht        # use the type summary
135*99451b44SJordan Rupprecht        self.expect("frame variable two",
136*99451b44SJordan Rupprecht                    substrs=['Text summary'])
137*99451b44SJordan Rupprecht
138*99451b44SJordan Rupprecht        self.runCmd("n")  # skip ahead to make values change
139*99451b44SJordan Rupprecht
140*99451b44SJordan Rupprecht        # both should use the type summary now
141*99451b44SJordan Rupprecht        self.expect("frame variable one",
142*99451b44SJordan Rupprecht                    substrs=['Text summary'])
143*99451b44SJordan Rupprecht
144*99451b44SJordan Rupprecht        self.expect("frame variable two",
145*99451b44SJordan Rupprecht                    substrs=['Text summary'])
146*99451b44SJordan Rupprecht
147*99451b44SJordan Rupprecht        # disable type summary for pointers, and make a Python regex summary
148*99451b44SJordan Rupprecht        self.runCmd(
149*99451b44SJordan Rupprecht            "type summary add i_am_cool -p --summary-string \"Text summary\"")
150*99451b44SJordan Rupprecht        self.runCmd("type summary add -x cool --python-script \"%s\"" % script)
151*99451b44SJordan Rupprecht
152*99451b44SJordan Rupprecht        # variables should stick to the type summary
153*99451b44SJordan Rupprecht        self.expect("frame variable one",
154*99451b44SJordan Rupprecht                    substrs=['Text summary'])
155*99451b44SJordan Rupprecht
156*99451b44SJordan Rupprecht        self.expect("frame variable two",
157*99451b44SJordan Rupprecht                    substrs=['Text summary'])
158*99451b44SJordan Rupprecht
159*99451b44SJordan Rupprecht        # array and pointer should match the Python one
160*99451b44SJordan Rupprecht        self.expect("frame variable twoptr",
161*99451b44SJordan Rupprecht                    substrs=['Python summary'])
162*99451b44SJordan Rupprecht
163*99451b44SJordan Rupprecht        self.expect("frame variable array",
164*99451b44SJordan Rupprecht                    substrs=['Python summary'])
165*99451b44SJordan Rupprecht
166*99451b44SJordan Rupprecht        # return pointers to the type summary
167*99451b44SJordan Rupprecht        self.runCmd(
168*99451b44SJordan Rupprecht            "type summary add i_am_cool --summary-string \"Text summary\"")
169*99451b44SJordan Rupprecht
170*99451b44SJordan Rupprecht        self.expect("frame variable one",
171*99451b44SJordan Rupprecht                    substrs=['Text summary'])
172*99451b44SJordan Rupprecht
173*99451b44SJordan Rupprecht        self.expect("frame variable two",
174*99451b44SJordan Rupprecht                    substrs=['Text summary'])
175*99451b44SJordan Rupprecht
176*99451b44SJordan Rupprecht        self.expect("frame variable twoptr",
177*99451b44SJordan Rupprecht                    substrs=['Text summary'])
178*99451b44SJordan Rupprecht
179*99451b44SJordan Rupprecht        self.expect("frame variable array",
180*99451b44SJordan Rupprecht                    substrs=['Python summary'])
181