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 @skipIfRemote 78 def test_scopes_variables_setVariable_evaluate(self): 79 ''' 80 Tests the "scopes", "variables", "setVariable", and "evaluate" 81 packets. 82 ''' 83 program = self.getBuildArtifact("a.out") 84 self.build_and_launch(program) 85 source = 'main.cpp' 86 breakpoint1_line = line_number(source, '// breakpoint 1') 87 lines = [breakpoint1_line] 88 # Set breakpoint in the thread function so we can step the threads 89 breakpoint_ids = self.set_source_breakpoints(source, lines) 90 self.assertTrue(len(breakpoint_ids) == len(lines), 91 "expect correct number of breakpoints") 92 self.continue_to_breakpoints(breakpoint_ids) 93 locals = self.vscode.get_local_variables() 94 globals = self.vscode.get_global_variables() 95 buffer_children = make_buffer_verify_dict(0, 32) 96 verify_locals = { 97 'argc': { 98 'equals': {'type': 'int', 'value': '1'} 99 }, 100 'argv': { 101 'equals': {'type': 'const char **'}, 102 'startswith': {'value': '0x'}, 103 'hasVariablesReference': True 104 }, 105 'pt': { 106 'equals': {'type': 'PointType'}, 107 'hasVariablesReference': True, 108 'children': { 109 'x': {'equals': {'type': 'int', 'value': '11'}}, 110 'y': {'equals': {'type': 'int', 'value': '22'}}, 111 'buffer': {'children': buffer_children} 112 } 113 } 114 } 115 verify_globals = { 116 's_local': { 117 'equals': {'type': 'float', 'value': '2.25'} 118 }, 119 '::g_global': { 120 'equals': {'type': 'int', 'value': '123'} 121 }, 122 's_global': { 123 'equals': {'type': 'int', 'value': '234'} 124 }, 125 } 126 varref_dict = {} 127 self.verify_variables(verify_locals, locals, varref_dict) 128 self.verify_variables(verify_globals, globals, varref_dict) 129 # pprint.PrettyPrinter(indent=4).pprint(varref_dict) 130 # We need to test the functionality of the "variables" request as it 131 # has optional parameters like "start" and "count" to limit the number 132 # of variables that are fetched 133 varRef = varref_dict['pt.buffer'] 134 response = self.vscode.request_variables(varRef) 135 self.verify_variables(buffer_children, response['body']['variables']) 136 # Verify setting start=0 in the arguments still gets all children 137 response = self.vscode.request_variables(varRef, start=0) 138 self.verify_variables(buffer_children, response['body']['variables']) 139 # Verify setting count=0 in the arguments still gets all children. 140 # If count is zero, it means to get all children. 141 response = self.vscode.request_variables(varRef, count=0) 142 self.verify_variables(buffer_children, response['body']['variables']) 143 # Verify setting count to a value that is too large in the arguments 144 # still gets all children, and no more 145 response = self.vscode.request_variables(varRef, count=1000) 146 self.verify_variables(buffer_children, response['body']['variables']) 147 # Verify setting the start index and count gets only the children we 148 # want 149 response = self.vscode.request_variables(varRef, start=5, count=5) 150 self.verify_variables(make_buffer_verify_dict(5, 5), 151 response['body']['variables']) 152 # Verify setting the start index to a value that is out of range 153 # results in an empty list 154 response = self.vscode.request_variables(varRef, start=32, count=1) 155 self.assertTrue(len(response['body']['variables']) == 0, 156 'verify we get no variable back for invalid start') 157 158 # Test evaluate 159 expressions = { 160 'pt.x': { 161 'equals': {'result': '11', 'type': 'int'}, 162 'hasVariablesReference': False 163 }, 164 'pt.buffer[2]': { 165 'equals': {'result': '2', 'type': 'int'}, 166 'hasVariablesReference': False 167 }, 168 'pt': { 169 'equals': {'type': 'PointType'}, 170 'startswith': {'result': 'PointType @ 0x'}, 171 'hasVariablesReference': True 172 }, 173 'pt.buffer': { 174 'equals': {'type': 'int [32]'}, 175 'startswith': {'result': 'int [32] @ 0x'}, 176 'hasVariablesReference': True 177 }, 178 'argv': { 179 'equals': {'type': 'const char **'}, 180 'startswith': {'result': '0x'}, 181 'hasVariablesReference': True 182 }, 183 'argv[0]': { 184 'equals': {'type': 'const char *'}, 185 'startswith': {'result': '0x'}, 186 'hasVariablesReference': True 187 }, 188 '2+3': { 189 'equals': {'result': '5', 'type': 'int'}, 190 'hasVariablesReference': False 191 }, 192 } 193 for expression in expressions: 194 response = self.vscode.request_evaluate(expression) 195 self.verify_values(expressions[expression], response['body']) 196 197 # Test setting variables 198 self.set_local('argc', 123) 199 argc = self.get_local_as_int('argc') 200 self.assertTrue(argc == 123, 201 'verify argc was set to 123 (123 != %i)' % (argc)) 202 203 self.set_local('argv', 0x1234) 204 argv = self.get_local_as_int('argv') 205 self.assertTrue(argv == 0x1234, 206 'verify argv was set to 0x1234 (0x1234 != %#x)' % ( 207 argv)) 208 209 # Set a variable value whose name is synthetic, like a variable index 210 # and verify the value by reading it 211 self.vscode.request_setVariable(varRef, "[0]", 100) 212 response = self.vscode.request_variables(varRef, start=0, count=1) 213 self.verify_variables(make_buffer_verify_dict(0, 1, 100), 214 response['body']['variables']) 215 216 # Set a variable value whose name is a real child value, like "pt.x" 217 # and verify the value by reading it 218 varRef = varref_dict['pt'] 219 self.vscode.request_setVariable(varRef, "x", 111) 220 response = self.vscode.request_variables(varRef, start=0, count=1) 221 value = response['body']['variables'][0]['value'] 222 self.assertTrue(value == '111', 223 'verify pt.x got set to 111 (111 != %s)' % (value)) 224