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