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 def invalid_struct_test(self, example): 114 invalid_struct = lldb.SBStructuredData() 115 invalid_struct = example.GetValueForKey("invalid_key") 116 if invalid_struct.IsValid(): 117 self.fail("An invalid object should have been returned") 118 119 # Check Type API 120 if not invalid_struct.GetType() == lldb.eStructuredDataTypeInvalid: 121 self.fail("Wrong type returned: " + str(invalid_struct.GetType())) 122 123 def dictionary_struct_test(self, example): 124 # Check API returning a valid SBStructuredData of 'dictionary' type 125 dict_struct = lldb.SBStructuredData() 126 dict_struct = example.GetValueForKey("key_dict") 127 if not dict_struct.IsValid(): 128 self.fail("A valid object should have been returned") 129 130 # Check Type API 131 if not dict_struct.GetType() == lldb.eStructuredDataTypeDictionary: 132 self.fail("Wrong type returned: " + str(dict_struct.GetType())) 133 134 # Check Size API for 'dictionary' type 135 if not dict_struct.GetSize() == 6: 136 self.fail("Wrong no of elements returned: " + str(dict_struct.GetSize())) 137 138 def string_struct_test(self, dict_struct): 139 string_struct = lldb.SBStructuredData() 140 string_struct = dict_struct.GetValueForKey("key_string") 141 if not string_struct.IsValid(): 142 self.fail("A valid object should have been returned") 143 144 # Check Type API 145 if not string_struct.GetType() == lldb.eStructuredDataTypeString: 146 self.fail("Wrong type returned: " + str(string_struct.GetType())) 147 148 # Check API returning 'string' value 149 output = string_struct.GetStringValue(25) 150 if not "STRING" in output: 151 self.fail("wrong output: " + output) 152 153 # Calling wrong API on a SBStructuredData 154 # (e.g. getting an integer from a string type structure) 155 output = string_struct.GetIntegerValue() 156 if output: 157 self.fail( 158 "Valid integer value " + str(output) + " returned for a string object" 159 ) 160 161 def uint_struct_test(self, dict_struct): 162 # Check a valid SBStructuredData containing an unsigned integer. 163 # We intentionally make this larger than what an int64_t can hold but 164 # still small enough to fit a uint64_t 165 uint_struct = lldb.SBStructuredData() 166 uint_struct = dict_struct.GetValueForKey("key_uint") 167 if not uint_struct.IsValid(): 168 self.fail("A valid object should have been returned") 169 170 # Check Type API 171 if not uint_struct.GetType() == lldb.eStructuredDataTypeInteger: 172 self.fail("Wrong type returned: " + str(uint_struct.GetType())) 173 174 # Check API returning unsigned integer value 175 output = uint_struct.GetUnsignedIntegerValue() 176 if not output == 0xFFFFFFFF00000000: 177 self.fail("wrong output: " + str(output)) 178 179 # Calling wrong API on a SBStructuredData 180 # (e.g. getting a string value from an integer type structure) 181 output = uint_struct.GetStringValue(25) 182 if output: 183 self.fail("Valid string " + output + " returned for an integer object") 184 185 def sint_struct_test(self, dict_struct): 186 # Check a valid SBStructuredData containing an signed integer. 187 # We intentionally make this smaller than what an uint64_t can hold but 188 # still small enough to fit a int64_t 189 sint_struct = lldb.SBStructuredData() 190 sint_struct = dict_struct.GetValueForKey("key_sint") 191 if not sint_struct.IsValid(): 192 self.fail("A valid object should have been returned") 193 194 # Check Type API 195 if not sint_struct.GetType() == lldb.eStructuredDataTypeSignedInteger: 196 self.fail("Wrong type returned: " + str(sint_struct.GetType())) 197 198 # Check API returning signed integer value 199 output = sint_struct.GetSignedIntegerValue() 200 if not output == -42: 201 self.fail("wrong output: " + str(output)) 202 203 # Calling wrong API on a SBStructuredData 204 # (e.g. getting a string value from an integer type structure) 205 output = sint_struct.GetStringValue(69) 206 if output: 207 self.fail("Valid string " + output + " returned for an integer object") 208 209 def double_struct_test(self, dict_struct): 210 floating_point_struct = lldb.SBStructuredData() 211 floating_point_struct = dict_struct.GetValueForKey("key_float") 212 if not floating_point_struct.IsValid(): 213 self.fail("A valid object should have been returned") 214 215 # Check Type API 216 if not floating_point_struct.GetType() == lldb.eStructuredDataTypeFloat: 217 self.fail("Wrong type returned: " + str(floating_point_struct.GetType())) 218 219 # Check API returning 'double' value 220 output = floating_point_struct.GetFloatValue() 221 if not output == 2.99: 222 self.fail("wrong output: " + str(output)) 223 224 def bool_struct_test(self, dict_struct): 225 bool_struct = lldb.SBStructuredData() 226 bool_struct = dict_struct.GetValueForKey("key_bool") 227 if not bool_struct.IsValid(): 228 self.fail("A valid object should have been returned") 229 230 # Check Type API 231 if not bool_struct.GetType() == lldb.eStructuredDataTypeBoolean: 232 self.fail("Wrong type returned: " + str(bool_struct.GetType())) 233 234 # Check API returning 'bool' value 235 output = bool_struct.GetBooleanValue() 236 if not output: 237 self.fail("wrong output: " + str(output)) 238 239 def array_struct_test(self, dict_struct): 240 # Check API returning a valid SBStructuredData of 'array' type 241 array_struct = lldb.SBStructuredData() 242 array_struct = dict_struct.GetValueForKey("key_array") 243 if not array_struct.IsValid(): 244 self.fail("A valid object should have been returned") 245 246 # Check Type API 247 if not array_struct.GetType() == lldb.eStructuredDataTypeArray: 248 self.fail("Wrong type returned: " + str(array_struct.GetType())) 249 250 # Check Size API for 'array' type 251 if not array_struct.GetSize() == 2: 252 self.fail("Wrong no of elements returned: " + str(array_struct.GetSize())) 253 254 # Check API returning a valid SBStructuredData for different 'array' 255 # indices 256 string_struct = array_struct.GetItemAtIndex(0) 257 if not string_struct.IsValid(): 258 self.fail("A valid object should have been returned") 259 if not string_struct.GetType() == lldb.eStructuredDataTypeString: 260 self.fail("Wrong type returned: " + str(string_struct.GetType())) 261 output = string_struct.GetStringValue(5) 262 if not output == "23": 263 self.fail("wrong output: " + str(output)) 264 265 string_struct = array_struct.GetItemAtIndex(1) 266 if not string_struct.IsValid(): 267 self.fail("A valid object should have been returned") 268 if not string_struct.GetType() == lldb.eStructuredDataTypeString: 269 self.fail("Wrong type returned: " + str(string_struct.GetType())) 270 output = string_struct.GetStringValue(5) 271 if not output == "arr": 272 self.fail("wrong output: " + str(output)) 273