402 lines · python
1"""2Test some SBStructuredData API.3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10 11import json12 13class TestStructuredDataAPI(TestBase):14 NO_DEBUG_INFO_TESTCASE = True15 16 def test(self):17 self.structured_data_api_test()18 19 def structured_data_api_test(self):20 error = lldb.SBError()21 s = lldb.SBStream()22 23 dict_str = json.dumps(24 {25 "key_dict": {26 "key_string": "STRING",27 "key_uint": 0xFFFFFFFF00000000,28 "key_sint": -42,29 "key_float": 2.99,30 "key_bool": True,31 "key_array": ["23", "arr"],32 }33 }34 )35 s.Print(dict_str)36 example = lldb.SBStructuredData()37 38 # Check SetFromJSON API for dictionaries, integers, floating point39 # values, strings and arrays40 error = example.SetFromJSON(s)41 if not error.Success():42 self.fail("FAILED: " + error.GetCString())43 44 # Tests for invalid data type45 self.invalid_struct_test(example)46 47 # Test that GetDescription works:48 s.Clear()49 error = example.GetDescription(s)50 self.assertSuccess(error, "GetDescription works")51 # Ensure str() doesn't raise an exception.52 self.assertTrue(str(example))53 if not "key_float" in s.GetData():54 self.fail("FAILED: could not find key_float in description output")55 56 dict_struct = example.GetValueForKey("key_dict")57 58 # Tests for dictionary data type59 self.dictionary_struct_test(example)60 61 # Tests for string data type62 self.string_struct_test(dict_struct)63 64 # Tests for integer data type65 self.uint_struct_test(dict_struct)66 67 # Tests for integer data type68 self.sint_struct_test(dict_struct)69 70 # Tests for floating point data type71 self.double_struct_test(dict_struct)72 73 # Tests for boolean data type74 self.bool_struct_test(dict_struct)75 76 # Tests for array data type77 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 self.assertEqual(int(example), 1)118 119 self.assertSuccess(example.SetFromJSON("4.19"))120 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeFloat)121 self.assertEqual(example.GetFloatValue(), 4.19)122 self.assertEqual(float(example), 4.19)123 124 self.assertSuccess(example.SetFromJSON('"Bonjour, 123!"'))125 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeString)126 self.assertEqual(example.GetStringValue(42), "Bonjour, 123!")127 self.assertEqual(str(example), "Bonjour, 123!")128 129 self.assertSuccess(example.SetFromJSON("true"))130 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeBoolean)131 self.assertTrue(example.GetBooleanValue())132 self.assertTrue(example)133 134 self.assertSuccess(example.SetFromJSON("null"))135 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeNull)136 137 example = lldb.SBStructuredData()138 example.SetUnsignedIntegerValue(1)139 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeInteger)140 self.assertEqual(example.GetIntegerValue(), 1)141 142 example.SetSignedIntegerValue(-42)143 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeSignedInteger)144 self.assertEqual(example.GetSignedIntegerValue(), -42)145 146 example.SetFloatValue(4.19)147 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeFloat)148 self.assertEqual(example.GetFloatValue(), 4.19)149 150 example.SetStringValue("Bonjour, 123!")151 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeString)152 self.assertEqual(example.GetStringValue(42), "Bonjour, 123!")153 154 value = lldb.SBStructuredData()155 example.SetValueForKey("Hello", value)156 self.assertEqual(example.GetSize(), 0)157 158 nested_obj = lldb.SBStructuredData()159 nested_obj.SetStringValue("World")160 example.SetValueForKey("Hello", nested_obj)161 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeDictionary)162 nested_obj = None163 nested_obj = example.GetValueForKey("Hello")164 self.assertTrue(nested_obj.IsValid())165 self.assertEqual(nested_obj.GetType(), lldb.eStructuredDataTypeString)166 self.assertEqual(nested_obj.GetStringValue(42), "World")167 168 example.SetBooleanValue(True)169 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeBoolean)170 self.assertTrue(example.GetBooleanValue())171 172 rnd_obj = MyRandomClass()173 stp = lldb.SBScriptObject(rnd_obj, lldb.eScriptLanguagePython)174 self.assertEqual(stp.ptr, rnd_obj)175 176 example.SetGenericValue(stp)177 self.assertEqual(example.GetType(), lldb.eStructuredDataTypeGeneric)178 179 my_random_class = example.GetGenericValue()180 self.assertTrue(my_random_class)181 self.assertEqual(my_random_class.payload, MyRandomClass.payload)182 183 example_arr = [1, 2.3, "4", {"5": False}]184 arr_str = json.dumps(example_arr)185 s.Clear()186 s.Print(arr_str)187 self.assertSuccess(example.SetFromJSON(s))188 189 s.Clear()190 self.assertSuccess(example.GetAsJSON(s))191 sb_data = json.loads(s.GetData())192 self.assertEqual(sb_data, example_arr)193 194 def invalid_struct_test(self, example):195 invalid_struct = example.GetValueForKey("invalid_key")196 if invalid_struct.IsValid():197 self.fail("An invalid object should have been returned")198 199 # Check Type API200 if invalid_struct.GetType() != lldb.eStructuredDataTypeInvalid:201 self.fail("Wrong type returned: " + str(invalid_struct.GetType()))202 203 def dictionary_struct_test(self, example):204 # Check API returning a valid SBStructuredData of 'dictionary' type205 dict_struct = example.GetValueForKey("key_dict")206 if not dict_struct.IsValid():207 self.fail("A valid object should have been returned")208 209 # Check Type API210 if dict_struct.GetType() != lldb.eStructuredDataTypeDictionary:211 self.fail("Wrong type returned: " + str(dict_struct.GetType()))212 213 # Check Size API for 'dictionary' type214 if dict_struct.GetSize() != 6:215 self.fail("Wrong no of elements returned: " + str(dict_struct.GetSize()))216 217 def string_struct_test(self, dict_struct):218 string_struct = dict_struct.GetValueForKey("key_string")219 if not string_struct.IsValid():220 self.fail("A valid object should have been returned")221 222 # Check Type API223 if string_struct.GetType() != lldb.eStructuredDataTypeString:224 self.fail("Wrong type returned: " + str(string_struct.GetType()))225 226 # Check API returning 'string' value227 output = string_struct.GetStringValue(25)228 if not "STRING" in output:229 self.fail("wrong output: " + output)230 231 # Calling wrong API on a SBStructuredData232 # (e.g. getting an integer from a string type structure)233 output = string_struct.GetIntegerValue()234 if output:235 self.fail(236 "Valid integer value " + str(output) + " returned for a string object"237 )238 239 def uint_struct_test(self, dict_struct):240 # Check a valid SBStructuredData containing an unsigned integer.241 # We intentionally make this larger than what an int64_t can hold but242 # still small enough to fit a uint64_t243 uint_struct = dict_struct.GetValueForKey("key_uint")244 if not uint_struct.IsValid():245 self.fail("A valid object should have been returned")246 247 # Check Type API248 if uint_struct.GetType() != lldb.eStructuredDataTypeInteger:249 self.fail("Wrong type returned: " + str(uint_struct.GetType()))250 251 # Check API returning unsigned integer value252 output = uint_struct.GetUnsignedIntegerValue()253 if output != 0xFFFFFFFF00000000:254 self.fail("wrong output: " + str(output))255 256 # Calling wrong API on a SBStructuredData257 # (e.g. getting a string value from an integer type structure)258 output = uint_struct.GetStringValue(25)259 if output:260 self.fail("Valid string " + output + " returned for an integer object")261 262 def sint_struct_test(self, dict_struct):263 # Check a valid SBStructuredData containing an signed integer.264 # We intentionally make this smaller than what an uint64_t can hold but265 # still small enough to fit a int64_t266 sint_struct = dict_struct.GetValueForKey("key_sint")267 if not sint_struct.IsValid():268 self.fail("A valid object should have been returned")269 270 # Check Type API271 if sint_struct.GetType() != lldb.eStructuredDataTypeSignedInteger:272 self.fail("Wrong type returned: " + str(sint_struct.GetType()))273 274 # Check API returning signed integer value275 output = sint_struct.GetSignedIntegerValue()276 if output != -42:277 self.fail("wrong output: " + str(output))278 279 # Calling wrong API on a SBStructuredData280 # (e.g. getting a string value from an integer type structure)281 output = sint_struct.GetStringValue(69)282 if output:283 self.fail("Valid string " + output + " returned for an integer object")284 285 def double_struct_test(self, dict_struct):286 floating_point_struct = dict_struct.GetValueForKey("key_float")287 if not floating_point_struct.IsValid():288 self.fail("A valid object should have been returned")289 290 # Check Type API291 if floating_point_struct.GetType() != lldb.eStructuredDataTypeFloat:292 self.fail("Wrong type returned: " + str(floating_point_struct.GetType()))293 294 # Check API returning 'double' value295 output = floating_point_struct.GetFloatValue()296 if output != 2.99:297 self.fail("wrong output: " + str(output))298 299 def bool_struct_test(self, dict_struct):300 bool_struct = dict_struct.GetValueForKey("key_bool")301 if not bool_struct.IsValid():302 self.fail("A valid object should have been returned")303 304 # Check Type API305 if bool_struct.GetType() != lldb.eStructuredDataTypeBoolean:306 self.fail("Wrong type returned: " + str(bool_struct.GetType()))307 308 # Check API returning 'bool' value309 output = bool_struct.GetBooleanValue()310 if not output:311 self.fail("wrong output: " + str(output))312 313 def array_struct_test(self, dict_struct):314 # Check API returning a valid SBStructuredData of 'array' type315 array_struct = dict_struct.GetValueForKey("key_array")316 if not array_struct.IsValid():317 self.fail("A valid object should have been returned")318 319 # Check Type API320 if array_struct.GetType() != lldb.eStructuredDataTypeArray:321 self.fail("Wrong type returned: " + str(array_struct.GetType()))322 323 # Check Size API for 'array' type324 if array_struct.GetSize() != 2:325 self.fail("Wrong no of elements returned: " + str(array_struct.GetSize()))326 327 # Check API returning a valid SBStructuredData for different 'array'328 # indices329 string_struct = array_struct.GetItemAtIndex(0)330 if not string_struct.IsValid():331 self.fail("A valid object should have been returned")332 if string_struct.GetType() != lldb.eStructuredDataTypeString:333 self.fail("Wrong type returned: " + str(string_struct.GetType()))334 output = string_struct.GetStringValue(5)335 if output != "23":336 self.fail("wrong output: " + str(output))337 338 string_struct = array_struct.GetItemAtIndex(1)339 if not string_struct.IsValid():340 self.fail("A valid object should have been returned")341 if string_struct.GetType() != lldb.eStructuredDataTypeString:342 self.fail("Wrong type returned: " + str(string_struct.GetType()))343 output = string_struct.GetStringValue(5)344 if output != "arr":345 self.fail("wrong output: " + str(output))346 347 def test_round_trip_scalars(self):348 for original in (0, 11, -1, 0.0, 4.5, -0.25):349 constructor = type(original)350 data = lldb.SBStructuredData()351 data.SetFromJSON(json.dumps(original))352 round_tripped = constructor(data)353 self.assertEqual(round_tripped, original)354 355 def test_dynamic(self):356 for original in (0, 11, -1, 0.0, 4.5, -0.25, "", "dirk", True, False):357 data = lldb.SBStructuredData()358 data.SetFromJSON(json.dumps(original))359 self.assertEqual(data.dynamic, original)360 361 def test_round_trip_int(self):362 for original in (0, 11, -1):363 data = lldb.SBStructuredData()364 data.SetFromJSON(json.dumps(original))365 self.assertEqual(int(data), int(original))366 367 def test_round_trip_float(self):368 for original in (0, 11, -1, 0.0, 4.5, -0.25):369 data = lldb.SBStructuredData()370 data.SetFromJSON(json.dumps(original))371 self.assertEqual(float(data), float(original))372 373 def test_iterate_array(self):374 array = [0, 1, 2]375 data = lldb.SBStructuredData()376 data.SetFromJSON(json.dumps(array))377 for value in data:378 self.assertEqual(value, array.pop(0))379 380 def test_iterate_dictionary(self):381 dictionary = {"0": 0, "1": 1, "2": 2}382 keys = set(dictionary.keys())383 data = lldb.SBStructuredData()384 data.SetFromJSON(json.dumps(dictionary))385 for key in data:386 self.assertIn(key, keys)387 keys.remove(key)388 389 def test_getitem_array(self):390 array = [1, 2, 3]391 data = lldb.SBStructuredData()392 data.SetFromJSON(json.dumps(array))393 for i in range(len(array)):394 self.assertEqual(data[i], array[i])395 396 def test_getitem_dictionary(self):397 dictionary = {"one": 1, "two": 2, "three": 3}398 data = lldb.SBStructuredData()399 data.SetFromJSON(json.dumps(dictionary))400 for key in dictionary:401 self.assertEqual(data[key], dictionary[key])402