1""" 2Test some SBStructuredData API. 3""" 4 5 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 11import json 12 13 14class TestStructuredDataAPI(TestBase): 15 NO_DEBUG_INFO_TESTCASE = True 16 17 def test(self): 18 self.structured_data_api_test() 19 20 def structured_data_api_test(self): 21 error = lldb.SBError() 22 s = lldb.SBStream() 23 24 dict_str = json.dumps( 25 { 26 "key_dict": { 27 "key_string": "STRING", 28 "key_uint": 0xFFFFFFFF00000000, 29 "key_sint": -42, 30 "key_float": 2.99, 31 "key_bool": True, 32 "key_array": ["23", "arr"], 33 } 34 } 35 ) 36 s.Print(dict_str) 37 example = lldb.SBStructuredData() 38 39 # Check SetFromJSON API for dictionaries, integers, floating point 40 # values, strings and arrays 41 error = example.SetFromJSON(s) 42 if not error.Success(): 43 self.fail("FAILED: " + error.GetCString()) 44 45 # Tests for invalid data type 46 self.invalid_struct_test(example) 47 48 # Test that GetDescription works: 49 s.Clear() 50 error = example.GetDescription(s) 51 self.assertSuccess(error, "GetDescription works") 52 if not "key_float" in s.GetData(): 53 self.fail("FAILED: could not find key_float in description output") 54 55 dict_struct = lldb.SBStructuredData() 56 dict_struct = example.GetValueForKey("key_dict") 57 58 # Tests for dictionary data type 59 self.dictionary_struct_test(example) 60 61 # Tests for string data type 62 self.string_struct_test(dict_struct) 63 64 # Tests for integer data type 65 self.uint_struct_test(dict_struct) 66 67 # Tests for integer data type 68 self.sint_struct_test(dict_struct) 69 70 # Tests for floating point data type 71 self.double_struct_test(dict_struct) 72 73 # Tests for boolean data type 74 self.bool_struct_test(dict_struct) 75 76 # Tests for array data type 77 self.array_struct_test(dict_struct) 78 79 s.Clear() 80 self.assertSuccess(example.GetAsJSON(s)) 81 py_obj = json.loads(s.GetData()) 82 self.assertTrue(py_obj) 83 self.assertIn("key_dict", py_obj) 84 85 py_dict = py_obj["key_dict"] 86 self.assertEqual(py_dict["key_string"], "STRING") 87 self.assertEqual(py_dict["key_uint"], 0xFFFFFFFF00000000) 88 self.assertEqual(py_dict["key_sint"], -42) 89 self.assertEqual(py_dict["key_float"], 2.99) 90 self.assertEqual(py_dict["key_bool"], True) 91 self.assertEqual(py_dict["key_array"], ["23", "arr"]) 92 93 class MyRandomClass: 94 payload = "foo" 95 96 py_dict["key_generic"] = MyRandomClass() 97 98 stp = lldb.SBScriptObject(py_dict, lldb.eScriptLanguagePython) 99 self.assertEqual(stp.ptr, py_dict) 100 101 sd = lldb.SBStructuredData(stp, self.dbg) 102 self.assertTrue(sd.IsValid()) 103 self.assertEqual(sd.GetSize(), len(py_dict)) 104 105 generic_sd = sd.GetValueForKey("key_generic") 106 self.assertTrue(generic_sd.IsValid()) 107 self.assertEqual(generic_sd.GetType(), lldb.eStructuredDataTypeGeneric) 108 109 my_random_class = generic_sd.GetGenericValue() 110 self.assertTrue(my_random_class) 111 self.assertEqual(my_random_class.payload, MyRandomClass.payload) 112 113 example = lldb.SBStructuredData() 114 self.assertSuccess(example.SetFromJSON("1")) 115 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeInteger) 116 self.assertEqual(example.GetIntegerValue(), 1) 117 118 self.assertSuccess(example.SetFromJSON("4.19")) 119 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeFloat) 120 self.assertEqual(example.GetFloatValue(), 4.19) 121 122 self.assertSuccess(example.SetFromJSON('"Bonjour, 123!"')) 123 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeString) 124 self.assertEqual(example.GetStringValue(42), "Bonjour, 123!") 125 126 self.assertSuccess(example.SetFromJSON("true")) 127 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeBoolean) 128 self.assertTrue(example.GetBooleanValue()) 129 130 self.assertSuccess(example.SetFromJSON("null")) 131 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeNull) 132 133 example_arr = [1, 2.3, "4", {"5": False}] 134 arr_str = json.dumps(example_arr) 135 s.Clear() 136 s.Print(arr_str) 137 self.assertSuccess(example.SetFromJSON(s)) 138 139 s.Clear() 140 self.assertSuccess(example.GetAsJSON(s)) 141 sb_data = json.loads(s.GetData()) 142 self.assertEqual(sb_data, example_arr) 143 144 def invalid_struct_test(self, example): 145 invalid_struct = lldb.SBStructuredData() 146 invalid_struct = example.GetValueForKey("invalid_key") 147 if invalid_struct.IsValid(): 148 self.fail("An invalid object should have been returned") 149 150 # Check Type API 151 if not invalid_struct.GetType() == lldb.eStructuredDataTypeInvalid: 152 self.fail("Wrong type returned: " + str(invalid_struct.GetType())) 153 154 def dictionary_struct_test(self, example): 155 # Check API returning a valid SBStructuredData of 'dictionary' type 156 dict_struct = lldb.SBStructuredData() 157 dict_struct = example.GetValueForKey("key_dict") 158 if not dict_struct.IsValid(): 159 self.fail("A valid object should have been returned") 160 161 # Check Type API 162 if not dict_struct.GetType() == lldb.eStructuredDataTypeDictionary: 163 self.fail("Wrong type returned: " + str(dict_struct.GetType())) 164 165 # Check Size API for 'dictionary' type 166 if not dict_struct.GetSize() == 6: 167 self.fail("Wrong no of elements returned: " + str(dict_struct.GetSize())) 168 169 def string_struct_test(self, dict_struct): 170 string_struct = lldb.SBStructuredData() 171 string_struct = dict_struct.GetValueForKey("key_string") 172 if not string_struct.IsValid(): 173 self.fail("A valid object should have been returned") 174 175 # Check Type API 176 if not string_struct.GetType() == lldb.eStructuredDataTypeString: 177 self.fail("Wrong type returned: " + str(string_struct.GetType())) 178 179 # Check API returning 'string' value 180 output = string_struct.GetStringValue(25) 181 if not "STRING" in output: 182 self.fail("wrong output: " + output) 183 184 # Calling wrong API on a SBStructuredData 185 # (e.g. getting an integer from a string type structure) 186 output = string_struct.GetIntegerValue() 187 if output: 188 self.fail( 189 "Valid integer value " + str(output) + " returned for a string object" 190 ) 191 192 def uint_struct_test(self, dict_struct): 193 # Check a valid SBStructuredData containing an unsigned integer. 194 # We intentionally make this larger than what an int64_t can hold but 195 # still small enough to fit a uint64_t 196 uint_struct = lldb.SBStructuredData() 197 uint_struct = dict_struct.GetValueForKey("key_uint") 198 if not uint_struct.IsValid(): 199 self.fail("A valid object should have been returned") 200 201 # Check Type API 202 if not uint_struct.GetType() == lldb.eStructuredDataTypeInteger: 203 self.fail("Wrong type returned: " + str(uint_struct.GetType())) 204 205 # Check API returning unsigned integer value 206 output = uint_struct.GetUnsignedIntegerValue() 207 if not output == 0xFFFFFFFF00000000: 208 self.fail("wrong output: " + str(output)) 209 210 # Calling wrong API on a SBStructuredData 211 # (e.g. getting a string value from an integer type structure) 212 output = uint_struct.GetStringValue(25) 213 if output: 214 self.fail("Valid string " + output + " returned for an integer object") 215 216 def sint_struct_test(self, dict_struct): 217 # Check a valid SBStructuredData containing an signed integer. 218 # We intentionally make this smaller than what an uint64_t can hold but 219 # still small enough to fit a int64_t 220 sint_struct = lldb.SBStructuredData() 221 sint_struct = dict_struct.GetValueForKey("key_sint") 222 if not sint_struct.IsValid(): 223 self.fail("A valid object should have been returned") 224 225 # Check Type API 226 if not sint_struct.GetType() == lldb.eStructuredDataTypeSignedInteger: 227 self.fail("Wrong type returned: " + str(sint_struct.GetType())) 228 229 # Check API returning signed integer value 230 output = sint_struct.GetSignedIntegerValue() 231 if not output == -42: 232 self.fail("wrong output: " + str(output)) 233 234 # Calling wrong API on a SBStructuredData 235 # (e.g. getting a string value from an integer type structure) 236 output = sint_struct.GetStringValue(69) 237 if output: 238 self.fail("Valid string " + output + " returned for an integer object") 239 240 def double_struct_test(self, dict_struct): 241 floating_point_struct = lldb.SBStructuredData() 242 floating_point_struct = dict_struct.GetValueForKey("key_float") 243 if not floating_point_struct.IsValid(): 244 self.fail("A valid object should have been returned") 245 246 # Check Type API 247 if not floating_point_struct.GetType() == lldb.eStructuredDataTypeFloat: 248 self.fail("Wrong type returned: " + str(floating_point_struct.GetType())) 249 250 # Check API returning 'double' value 251 output = floating_point_struct.GetFloatValue() 252 if not output == 2.99: 253 self.fail("wrong output: " + str(output)) 254 255 def bool_struct_test(self, dict_struct): 256 bool_struct = lldb.SBStructuredData() 257 bool_struct = dict_struct.GetValueForKey("key_bool") 258 if not bool_struct.IsValid(): 259 self.fail("A valid object should have been returned") 260 261 # Check Type API 262 if not bool_struct.GetType() == lldb.eStructuredDataTypeBoolean: 263 self.fail("Wrong type returned: " + str(bool_struct.GetType())) 264 265 # Check API returning 'bool' value 266 output = bool_struct.GetBooleanValue() 267 if not output: 268 self.fail("wrong output: " + str(output)) 269 270 def array_struct_test(self, dict_struct): 271 # Check API returning a valid SBStructuredData of 'array' type 272 array_struct = lldb.SBStructuredData() 273 array_struct = dict_struct.GetValueForKey("key_array") 274 if not array_struct.IsValid(): 275 self.fail("A valid object should have been returned") 276 277 # Check Type API 278 if not array_struct.GetType() == lldb.eStructuredDataTypeArray: 279 self.fail("Wrong type returned: " + str(array_struct.GetType())) 280 281 # Check Size API for 'array' type 282 if not array_struct.GetSize() == 2: 283 self.fail("Wrong no of elements returned: " + str(array_struct.GetSize())) 284 285 # Check API returning a valid SBStructuredData for different 'array' 286 # indices 287 string_struct = array_struct.GetItemAtIndex(0) 288 if not string_struct.IsValid(): 289 self.fail("A valid object should have been returned") 290 if not string_struct.GetType() == lldb.eStructuredDataTypeString: 291 self.fail("Wrong type returned: " + str(string_struct.GetType())) 292 output = string_struct.GetStringValue(5) 293 if not output == "23": 294 self.fail("wrong output: " + str(output)) 295 296 string_struct = array_struct.GetItemAtIndex(1) 297 if not string_struct.IsValid(): 298 self.fail("A valid object should have been returned") 299 if not string_struct.GetType() == lldb.eStructuredDataTypeString: 300 self.fail("Wrong type returned: " + str(string_struct.GetType())) 301 output = string_struct.GetStringValue(5) 302 if not output == "arr": 303 self.fail("wrong output: " + str(output)) 304