1""" 2Test lldb-vscode setBreakpoints request 3""" 4 5from __future__ import print_function 6 7import unittest2 8import vscode 9from lldbsuite.test.decorators import * 10from lldbsuite.test.lldbtest import * 11from lldbsuite.test import lldbutil 12import lldbvscode_testcase 13 14 15def make_buffer_verify_dict(start_idx, count, offset=0): 16 verify_dict = {} 17 for i in range(start_idx, start_idx + count): 18 verify_dict['[%i]' % (i)] = {'type': 'int', 'value': str(i+offset)} 19 return verify_dict 20 21 22class TestVSCode_variables(lldbvscode_testcase.VSCodeTestCaseBase): 23 24 mydir = TestBase.compute_mydir(__file__) 25 26 def verify_values(self, verify_dict, actual, varref_dict=None): 27 if 'equals' in verify_dict: 28 verify = verify_dict['equals'] 29 for key in verify: 30 verify_value = verify[key] 31 actual_value = actual[key] 32 self.assertTrue(verify_value == actual_value, 33 '"%s" keys don\'t match (%s != %s)' % ( 34 key, actual_value, verify_value)) 35 if 'startswith' in verify_dict: 36 verify = verify_dict['startswith'] 37 for key in verify: 38 verify_value = verify[key] 39 actual_value = actual[key] 40 startswith = actual_value.startswith(verify_value) 41 self.assertTrue(startswith, 42 ('"%s" value "%s" doesn\'t start with' 43 ' "%s")') % ( 44 key, actual_value, 45 verify_value)) 46 hasVariablesReference = 'variablesReference' in actual 47 varRef = None 48 if hasVariablesReference: 49 # Remember variable references in case we want to test further 50 # by using the evaluate name. 51 varRef = actual['variablesReference'] 52 if varRef != 0 and varref_dict is not None: 53 varref_dict[actual['evaluateName']] = varRef 54 if ('hasVariablesReference' in verify_dict and 55 verify_dict['hasVariablesReference']): 56 self.assertTrue(hasVariablesReference, 57 "verify variable reference") 58 if 'children' in verify_dict: 59 self.assertTrue(hasVariablesReference and varRef is not None and 60 varRef != 0, 61 ("children verify values specified for " 62 "variable without children")) 63 64 response = self.vscode.request_variables(varRef) 65 self.verify_variables(verify_dict['children'], 66 response['body']['variables'], 67 varref_dict) 68 69 def verify_variables(self, verify_dict, variables, varref_dict=None): 70 for variable in variables: 71 name = variable['name'] 72 self.assertTrue(name in verify_dict, 73 'variable "%s" in verify dictionary' % (name)) 74 self.verify_values(verify_dict[name], variable, varref_dict) 75 76 @skipIfWindows 77 def test_scopes_variables_setVariable_evaluate(self): 78 ''' 79 Tests the "scopes", "variables", "setVariable", and "evaluate" 80 packets. 81 ''' 82 program = self.getBuildArtifact("a.out") 83 self.build_and_launch(program) 84 source = 'main.cpp' 85 breakpoint1_line = line_number(source, '// breakpoint 1') 86 lines = [breakpoint1_line] 87 # Set breakpoint in the thread function so we can step the threads 88 breakpoint_ids = self.set_source_breakpoints(source, lines) 89 self.assertTrue(len(breakpoint_ids) == len(lines), 90 "expect correct number of breakpoints") 91 self.continue_to_breakpoints(breakpoint_ids) 92 locals = self.vscode.get_local_variables() 93 globals = self.vscode.get_global_variables() 94 buffer_children = make_buffer_verify_dict(0, 32) 95 verify_locals = { 96 'argc': { 97 'equals': {'type': 'int', 'value': '1'} 98 }, 99 'argv': { 100 'equals': {'type': 'const char **'}, 101 'startswith': {'value': '0x'}, 102 'hasVariablesReference': True 103 }, 104 'pt': { 105 'equals': {'type': 'PointType'}, 106 'hasVariablesReference': True, 107 'children': { 108 'x': {'equals': {'type': 'int', 'value': '11'}}, 109 'y': {'equals': {'type': 'int', 'value': '22'}}, 110 'buffer': {'children': buffer_children} 111 } 112 } 113 } 114 verify_globals = { 115 's_local': { 116 'equals': {'type': 'float', 'value': '2.25'} 117 }, 118 '::g_global': { 119 'equals': {'type': 'int', 'value': '123'} 120 }, 121 's_global': { 122 'equals': {'type': 'int', 'value': '234'} 123 }, 124 } 125 varref_dict = {} 126 self.verify_variables(verify_locals, locals, varref_dict) 127 self.verify_variables(verify_globals, globals, varref_dict) 128 # pprint.PrettyPrinter(indent=4).pprint(varref_dict) 129 # We need to test the functionality of the "variables" request as it 130 # has optional parameters like "start" and "count" to limit the number 131 # of variables that are fetched 132 varRef = varref_dict['pt.buffer'] 133 response = self.vscode.request_variables(varRef) 134 self.verify_variables(buffer_children, response['body']['variables']) 135 # Verify setting start=0 in the arguments still gets all children 136 response = self.vscode.request_variables(varRef, start=0) 137 self.verify_variables(buffer_children, response['body']['variables']) 138 # Verify setting count=0 in the arguments still gets all children. 139 # If count is zero, it means to get all children. 140 response = self.vscode.request_variables(varRef, count=0) 141 self.verify_variables(buffer_children, response['body']['variables']) 142 # Verify setting count to a value that is too large in the arguments 143 # still gets all children, and no more 144 response = self.vscode.request_variables(varRef, count=1000) 145 self.verify_variables(buffer_children, response['body']['variables']) 146 # Verify setting the start index and count gets only the children we 147 # want 148 response = self.vscode.request_variables(varRef, start=5, count=5) 149 self.verify_variables(make_buffer_verify_dict(5, 5), 150 response['body']['variables']) 151 # Verify setting the start index to a value that is out of range 152 # results in an empty list 153 response = self.vscode.request_variables(varRef, start=32, count=1) 154 self.assertTrue(len(response['body']['variables']) == 0, 155 'verify we get no variable back for invalid start') 156 157 # Test evaluate 158 expressions = { 159 'pt.x': { 160 'equals': {'result': '11', 'type': 'int'}, 161 'hasVariablesReference': False 162 }, 163 'pt.buffer[2]': { 164 'equals': {'result': '2', 'type': 'int'}, 165 'hasVariablesReference': False 166 }, 167 'pt': { 168 'equals': {'type': 'PointType'}, 169 'startswith': {'result': 'PointType @ 0x'}, 170 'hasVariablesReference': True 171 }, 172 'pt.buffer': { 173 'equals': {'type': 'int [32]'}, 174 'startswith': {'result': 'int [32] @ 0x'}, 175 'hasVariablesReference': True 176 }, 177 'argv': { 178 'equals': {'type': 'const char **'}, 179 'startswith': {'result': '0x'}, 180 'hasVariablesReference': True 181 }, 182 'argv[0]': { 183 'equals': {'type': 'const char *'}, 184 'startswith': {'result': '0x'}, 185 'hasVariablesReference': True 186 }, 187 '2+3': { 188 'equals': {'result': '5', 'type': 'int'}, 189 'hasVariablesReference': False 190 }, 191 } 192 for expression in expressions: 193 response = self.vscode.request_evaluate(expression) 194 self.verify_values(expressions[expression], response['body']) 195 196 # Test setting variables 197 self.set_local('argc', 123) 198 argc = self.get_local_as_int('argc') 199 self.assertTrue(argc == 123, 200 'verify argc was set to 123 (123 != %i)' % (argc)) 201 202 self.set_local('argv', 0x1234) 203 argv = self.get_local_as_int('argv') 204 self.assertTrue(argv == 0x1234, 205 'verify argv was set to 0x1234 (0x1234 != %#x)' % ( 206 argv)) 207 208 # Set a variable value whose name is synthetic, like a variable index 209 # and verify the value by reading it 210 self.vscode.request_setVariable(varRef, "[0]", 100) 211 response = self.vscode.request_variables(varRef, start=0, count=1) 212 self.verify_variables(make_buffer_verify_dict(0, 1, 100), 213 response['body']['variables']) 214 215 # Set a variable value whose name is a real child value, like "pt.x" 216 # and verify the value by reading it 217 varRef = varref_dict['pt'] 218 self.vscode.request_setVariable(varRef, "x", 111) 219 response = self.vscode.request_variables(varRef, start=0, count=1) 220 value = response['body']['variables'][0]['value'] 221 self.assertTrue(value == '111', 222 'verify pt.x got set to 111 (111 != %s)' % (value)) 223