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