1"""
2Test lldb data formatter subsystem.
3"""
4
5import os, time
6import unittest2
7import lldb
8from lldbtest import *
9import lldbutil
10
11class NamedSummariesDataFormatterTestCase(TestBase):
12
13    mydir = os.path.join("functionalities", "data-formatter", "data-formatter-named-summaries")
14
15    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
16    @dsym_test
17    def test_with_dsym_and_run_command(self):
18        """Test data formatter commands."""
19        self.buildDsym()
20        self.data_formatter_commands()
21
22    @dwarf_test
23    def test_with_dwarf_and_run_command(self):
24        """Test data formatter commands."""
25        self.buildDwarf()
26        self.data_formatter_commands()
27
28    def setUp(self):
29        # Call super's setUp().
30        TestBase.setUp(self)
31        # Find the line number to break at.
32        self.line = line_number('main.cpp', '// Set break point at this line.')
33
34    def data_formatter_commands(self):
35        """Test that that file and class static variables display correctly."""
36        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
37
38        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
39
40        self.runCmd("run", RUN_SUCCEEDED)
41
42        # The stop reason of the thread should be breakpoint.
43        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
44            substrs = ['stopped',
45                       'stop reason = breakpoint'])
46
47        # This is the function to remove the custom formats in order to have a
48        # clean slate for the next test case.
49        def cleanup():
50            self.runCmd('type format clear', check=False)
51            self.runCmd('type summary clear', check=False)
52
53        # Execute the cleanup function during test case tear down.
54        self.addTearDownHook(cleanup)
55
56        self.runCmd("type summary add --summary-string \"AllUseIt: x=${var.x} {y=${var.y}} {z=${var.z}}\" --name AllUseIt")
57        self.runCmd("type summary add --summary-string \"First: x=${var.x} y=${var.y} dummy=${var.dummy}\" First")
58        self.runCmd("type summary add --summary-string \"Second: x=${var.x} y=${var.y%hex}\" Second")
59        self.runCmd("type summary add --summary-string \"Third: x=${var.x} z=${var.z}\" Third")
60
61        self.expect("frame variable first",
62            substrs = ['First: x=12'])
63
64        self.expect("frame variable first --summary AllUseIt",
65            substrs = ['AllUseIt: x=12'])
66
67        # We *DO NOT* remember the summary choice anymore
68        self.expect("frame variable first", matching=False,
69            substrs = ['AllUseIt: x=12'])
70        self.expect("frame variable first",
71            substrs = ['First: x=12'])
72
73        self.runCmd("thread step-over") # 2
74
75        self.expect("frame variable first",
76            substrs = ['First: x=12'])
77
78        self.expect("frame variable first --summary AllUseIt",
79            substrs = ['AllUseIt: x=12',
80                       'y=34'])
81
82        self.expect("frame variable second --summary AllUseIt",
83            substrs = ['AllUseIt: x=65',
84                       'y=43.25'])
85
86        self.expect("frame variable third --summary AllUseIt",
87            substrs = ['AllUseIt: x=96',
88                       'z=',
89                        'E'])
90
91        self.runCmd("thread step-over") # 3
92
93        self.expect("frame variable second",
94            substrs = ['Second: x=65',
95                        'y=0x'])
96
97        # <rdar://problem/11576143> decided that invalid summaries will raise an error
98        # instead of just defaulting to the base summary
99        self.expect("frame variable second --summary NoSuchSummary",error=True,
100            substrs = ['must specify a valid named summary'])
101
102        self.runCmd("thread step-over")
103
104        self.runCmd("type summary add --summary-string \"FirstAndFriends: x=${var.x} {y=${var.y}} {z=${var.z}}\" First --name FirstAndFriends")
105
106        self.expect("frame variable first",
107            substrs = ['FirstAndFriends: x=12',
108                        'y=34'])
109
110        self.runCmd("type summary delete First")
111
112        self.expect("frame variable first --summary FirstAndFriends",
113            substrs = ['FirstAndFriends: x=12',
114                        'y=34'])
115
116        self.expect("frame variable first", matching=True,
117            substrs = ['x = 12',
118                        'y = 34'])
119
120        self.runCmd("type summary delete FirstAndFriends")
121        self.expect("type summary delete NoSuchSummary", error=True)
122        self.runCmd("type summary delete AllUseIt")
123
124        self.expect("frame variable first", matching=False,
125            substrs = ['FirstAndFriends'])
126
127        self.runCmd("thread step-over") # 4
128
129        self.expect("frame variable first",matching=False,
130            substrs = ['FirstAndFriends: x=12',
131                       'y=34'])
132
133
134if __name__ == '__main__':
135    import atexit
136    lldb.SBDebugger.Initialize()
137    atexit.register(lambda: lldb.SBDebugger.Terminate())
138    unittest2.main()
139