| """ | |
| Test some SBStructuredData API. | |
| """ | |
| import lldb | |
| from lldbsuite.test.decorators import * | |
| from lldbsuite.test.lldbtest import * | |
| from lldbsuite.test import lldbutil | |
| import json | |
| class TestStructuredDataAPI(TestBase): | |
| NO_DEBUG_INFO_TESTCASE = True | |
| def test(self): | |
| self.structured_data_api_test() | |
| def structured_data_api_test(self): | |
| error = lldb.SBError() | |
| s = lldb.SBStream() | |
| dict_str = json.dumps( | |
| { | |
| "key_dict": { | |
| "key_string": "STRING", | |
| "key_uint": 0xFFFFFFFF00000000, | |
| "key_sint": -42, | |
| "key_float": 2.99, | |
| "key_bool": True, | |
| "key_array": ["23", "arr"], | |
| } | |
| } | |
| ) | |
| s.Print(dict_str) | |
| example = lldb.SBStructuredData() | |
| # Check SetFromJSON API for dictionaries, integers, floating point | |
| # values, strings and arrays | |
| error = example.SetFromJSON(s) | |
| if not error.Success(): | |
| self.fail("FAILED: " + error.GetCString()) | |
| # Tests for invalid data type | |
| self.invalid_struct_test(example) | |
| # Test that GetDescription works: | |
| s.Clear() | |
| error = example.GetDescription(s) | |
| self.assertSuccess(error, "GetDescription works") | |
| # Ensure str() doesn't raise an exception. | |
| self.assertTrue(str(example)) | |
| if not "key_float" in s.GetData(): | |
| self.fail("FAILED: could not find key_float in description output") | |
| dict_struct = example.GetValueForKey("key_dict") | |
| # Tests for dictionary data type | |
| self.dictionary_struct_test(example) | |
| # Tests for string data type | |
| self.string_struct_test(dict_struct) | |
| # Tests for integer data type | |
| self.uint_struct_test(dict_struct) | |
| # Tests for integer data type | |
| self.sint_struct_test(dict_struct) | |
| # Tests for floating point data type | |
| self.double_struct_test(dict_struct) | |
| # Tests for boolean data type | |
| self.bool_struct_test(dict_struct) | |
| # Tests for array data type | |
| self.array_struct_test(dict_struct) | |
| s.Clear() | |
| self.assertSuccess(example.GetAsJSON(s)) | |
| py_obj = json.loads(s.GetData()) | |
| self.assertTrue(py_obj) | |
| self.assertIn("key_dict", py_obj) | |
| py_dict = py_obj["key_dict"] | |
| self.assertEqual(py_dict["key_string"], "STRING") | |
| self.assertEqual(py_dict["key_uint"], 0xFFFFFFFF00000000) | |
| self.assertEqual(py_dict["key_sint"], -42) | |
| self.assertEqual(py_dict["key_float"], 2.99) | |
| self.assertEqual(py_dict["key_bool"], True) | |
| self.assertEqual(py_dict["key_array"], ["23", "arr"]) | |
| class MyRandomClass: | |
| payload = "foo" | |
| py_dict["key_generic"] = MyRandomClass() | |
| stp = lldb.SBScriptObject(py_dict, lldb.eScriptLanguagePython) | |
| self.assertEqual(stp.ptr, py_dict) | |
| sd = lldb.SBStructuredData(stp, self.dbg) | |
| self.assertTrue(sd.IsValid()) | |
| self.assertEqual(sd.GetSize(), len(py_dict)) | |
| generic_sd = sd.GetValueForKey("key_generic") | |
| self.assertTrue(generic_sd.IsValid()) | |
| self.assertEqual(generic_sd.GetType(), lldb.eStructuredDataTypeGeneric) | |
| my_random_class = generic_sd.GetGenericValue() | |
| self.assertTrue(my_random_class) | |
| self.assertEqual(my_random_class.payload, MyRandomClass.payload) | |
| example = lldb.SBStructuredData() | |
| self.assertSuccess(example.SetFromJSON("1")) | |
| self.assertEqual(example.GetType(), lldb.eStructuredDataTypeInteger) | |
| self.assertEqual(example.GetIntegerValue(), 1) | |
| self.assertEqual(int(example), 1) | |
| self.assertSuccess(example.SetFromJSON("4.19")) | |
| self.assertEqual(example.GetType(), lldb.eStructuredDataTypeFloat) | |
| self.assertEqual(example.GetFloatValue(), 4.19) | |
| self.assertEqual(float(example), 4.19) | |
| self.assertSuccess(example.SetFromJSON('"Bonjour, 123!"')) | |
| self.assertEqual(example.GetType(), lldb.eStructuredDataTypeString) | |
| self.assertEqual(example.GetStringValue(42), "Bonjour, 123!") | |
| self.assertEqual(str(example), "Bonjour, 123!") | |
| self.assertSuccess(example.SetFromJSON("true")) | |
| self.assertEqual(example.GetType(), lldb.eStructuredDataTypeBoolean) | |
| self.assertTrue(example.GetBooleanValue()) | |
| self.assertTrue(example) | |
| self.assertSuccess(example.SetFromJSON("null")) | |
| self.assertEqual(example.GetType(), lldb.eStructuredDataTypeNull) | |
| example = lldb.SBStructuredData() | |
| example.SetUnsignedIntegerValue(1) | |
| self.assertEqual(example.GetType(), lldb.eStructuredDataTypeInteger) | |
| self.assertEqual(example.GetIntegerValue(), 1) | |
| example.SetSignedIntegerValue(-42) | |
| self.assertEqual(example.GetType(), lldb.eStructuredDataTypeSignedInteger) | |
| self.assertEqual(example.GetSignedIntegerValue(), -42) | |
| example.SetFloatValue(4.19) | |
| self.assertEqual(example.GetType(), lldb.eStructuredDataTypeFloat) | |
| self.assertEqual(example.GetFloatValue(), 4.19) | |
| example.SetStringValue("Bonjour, 123!") | |
| self.assertEqual(example.GetType(), lldb.eStructuredDataTypeString) | |
| self.assertEqual(example.GetStringValue(42), "Bonjour, 123!") | |
| value = lldb.SBStructuredData() | |
| example.SetValueForKey("Hello", value) | |
| self.assertEqual(example.GetSize(), 0) | |
| nested_obj = lldb.SBStructuredData() | |
| nested_obj.SetStringValue("World") | |
| example.SetValueForKey("Hello", nested_obj) | |
| self.assertEqual(example.GetType(), lldb.eStructuredDataTypeDictionary) | |
| nested_obj = None | |
| nested_obj = example.GetValueForKey("Hello") | |
| self.assertTrue(nested_obj.IsValid()) | |
| self.assertEqual(nested_obj.GetType(), lldb.eStructuredDataTypeString) | |
| self.assertEqual(nested_obj.GetStringValue(42), "World") | |
| example.SetBooleanValue(True) | |
| self.assertEqual(example.GetType(), lldb.eStructuredDataTypeBoolean) | |
| self.assertTrue(example.GetBooleanValue()) | |
| rnd_obj = MyRandomClass() | |
| stp = lldb.SBScriptObject(rnd_obj, lldb.eScriptLanguagePython) | |
| self.assertEqual(stp.ptr, rnd_obj) | |
| example.SetGenericValue(stp) | |
| self.assertEqual(example.GetType(), lldb.eStructuredDataTypeGeneric) | |
| my_random_class = example.GetGenericValue() | |
| self.assertTrue(my_random_class) | |
| self.assertEqual(my_random_class.payload, MyRandomClass.payload) | |
| example_arr = [1, 2.3, "4", {"5": False}] | |
| arr_str = json.dumps(example_arr) | |
| s.Clear() | |
| s.Print(arr_str) | |
| self.assertSuccess(example.SetFromJSON(s)) | |
| s.Clear() | |
| self.assertSuccess(example.GetAsJSON(s)) | |
| sb_data = json.loads(s.GetData()) | |
| self.assertEqual(sb_data, example_arr) | |
| def invalid_struct_test(self, example): | |
| invalid_struct = example.GetValueForKey("invalid_key") | |
| if invalid_struct.IsValid(): | |
| self.fail("An invalid object should have been returned") | |
| # Check Type API | |
| if invalid_struct.GetType() != lldb.eStructuredDataTypeInvalid: | |
| self.fail("Wrong type returned: " + str(invalid_struct.GetType())) | |
| def dictionary_struct_test(self, example): | |
| # Check API returning a valid SBStructuredData of 'dictionary' type | |
| dict_struct = example.GetValueForKey("key_dict") | |
| if not dict_struct.IsValid(): | |
| self.fail("A valid object should have been returned") | |
| # Check Type API | |
| if dict_struct.GetType() != lldb.eStructuredDataTypeDictionary: | |
| self.fail("Wrong type returned: " + str(dict_struct.GetType())) | |
| # Check Size API for 'dictionary' type | |
| if dict_struct.GetSize() != 6: | |
| self.fail("Wrong no of elements returned: " + str(dict_struct.GetSize())) | |
| def string_struct_test(self, dict_struct): | |
| string_struct = dict_struct.GetValueForKey("key_string") | |
| if not string_struct.IsValid(): | |
| self.fail("A valid object should have been returned") | |
| # Check Type API | |
| if string_struct.GetType() != lldb.eStructuredDataTypeString: | |
| self.fail("Wrong type returned: " + str(string_struct.GetType())) | |
| # Check API returning 'string' value | |
| output = string_struct.GetStringValue(25) | |
| if not "STRING" in output: | |
| self.fail("wrong output: " + output) | |
| # Calling wrong API on a SBStructuredData | |
| # (e.g. getting an integer from a string type structure) | |
| output = string_struct.GetIntegerValue() | |
| if output: | |
| self.fail( | |
| "Valid integer value " + str(output) + " returned for a string object" | |
| ) | |
| def uint_struct_test(self, dict_struct): | |
| # Check a valid SBStructuredData containing an unsigned integer. | |
| # We intentionally make this larger than what an int64_t can hold but | |
| # still small enough to fit a uint64_t | |
| uint_struct = dict_struct.GetValueForKey("key_uint") | |
| if not uint_struct.IsValid(): | |
| self.fail("A valid object should have been returned") | |
| # Check Type API | |
| if uint_struct.GetType() != lldb.eStructuredDataTypeInteger: | |
| self.fail("Wrong type returned: " + str(uint_struct.GetType())) | |
| # Check API returning unsigned integer value | |
| output = uint_struct.GetUnsignedIntegerValue() | |
| if output != 0xFFFFFFFF00000000: | |
| self.fail("wrong output: " + str(output)) | |
| # Calling wrong API on a SBStructuredData | |
| # (e.g. getting a string value from an integer type structure) | |
| output = uint_struct.GetStringValue(25) | |
| if output: | |
| self.fail("Valid string " + output + " returned for an integer object") | |
| def sint_struct_test(self, dict_struct): | |
| # Check a valid SBStructuredData containing an signed integer. | |
| # We intentionally make this smaller than what an uint64_t can hold but | |
| # still small enough to fit a int64_t | |
| sint_struct = dict_struct.GetValueForKey("key_sint") | |
| if not sint_struct.IsValid(): | |
| self.fail("A valid object should have been returned") | |
| # Check Type API | |
| if sint_struct.GetType() != lldb.eStructuredDataTypeSignedInteger: | |
| self.fail("Wrong type returned: " + str(sint_struct.GetType())) | |
| # Check API returning signed integer value | |
| output = sint_struct.GetSignedIntegerValue() | |
| if output != -42: | |
| self.fail("wrong output: " + str(output)) | |
| # Calling wrong API on a SBStructuredData | |
| # (e.g. getting a string value from an integer type structure) | |
| output = sint_struct.GetStringValue(69) | |
| if output: | |
| self.fail("Valid string " + output + " returned for an integer object") | |
| def double_struct_test(self, dict_struct): | |
| floating_point_struct = dict_struct.GetValueForKey("key_float") | |
| if not floating_point_struct.IsValid(): | |
| self.fail("A valid object should have been returned") | |
| # Check Type API | |
| if floating_point_struct.GetType() != lldb.eStructuredDataTypeFloat: | |
| self.fail("Wrong type returned: " + str(floating_point_struct.GetType())) | |
| # Check API returning 'double' value | |
| output = floating_point_struct.GetFloatValue() | |
| if output != 2.99: | |
| self.fail("wrong output: " + str(output)) | |
| def bool_struct_test(self, dict_struct): | |
| bool_struct = dict_struct.GetValueForKey("key_bool") | |
| if not bool_struct.IsValid(): | |
| self.fail("A valid object should have been returned") | |
| # Check Type API | |
| if bool_struct.GetType() != lldb.eStructuredDataTypeBoolean: | |
| self.fail("Wrong type returned: " + str(bool_struct.GetType())) | |
| # Check API returning 'bool' value | |
| output = bool_struct.GetBooleanValue() | |
| if not output: | |
| self.fail("wrong output: " + str(output)) | |
| def array_struct_test(self, dict_struct): | |
| # Check API returning a valid SBStructuredData of 'array' type | |
| array_struct = dict_struct.GetValueForKey("key_array") | |
| if not array_struct.IsValid(): | |
| self.fail("A valid object should have been returned") | |
| # Check Type API | |
| if array_struct.GetType() != lldb.eStructuredDataTypeArray: | |
| self.fail("Wrong type returned: " + str(array_struct.GetType())) | |
| # Check Size API for 'array' type | |
| if array_struct.GetSize() != 2: | |
| self.fail("Wrong no of elements returned: " + str(array_struct.GetSize())) | |
| # Check API returning a valid SBStructuredData for different 'array' | |
| # indices | |
| string_struct = array_struct.GetItemAtIndex(0) | |
| if not string_struct.IsValid(): | |
| self.fail("A valid object should have been returned") | |
| if string_struct.GetType() != lldb.eStructuredDataTypeString: | |
| self.fail("Wrong type returned: " + str(string_struct.GetType())) | |
| output = string_struct.GetStringValue(5) | |
| if output != "23": | |
| self.fail("wrong output: " + str(output)) | |
| string_struct = array_struct.GetItemAtIndex(1) | |
| if not string_struct.IsValid(): | |
| self.fail("A valid object should have been returned") | |
| if string_struct.GetType() != lldb.eStructuredDataTypeString: | |
| self.fail("Wrong type returned: " + str(string_struct.GetType())) | |
| output = string_struct.GetStringValue(5) | |
| if output != "arr": | |
| self.fail("wrong output: " + str(output)) | |
| def test_round_trip_scalars(self): | |
| for original in (0, 11, -1, 0.0, 4.5, -0.25): | |
| constructor = type(original) | |
| data = lldb.SBStructuredData() | |
| data.SetFromJSON(json.dumps(original)) | |
| round_tripped = constructor(data) | |
| self.assertEqual(round_tripped, original) | |
| def test_dynamic(self): | |
| for original in (0, 11, -1, 0.0, 4.5, -0.25, "", "dirk", True, False): | |
| data = lldb.SBStructuredData() | |
| data.SetFromJSON(json.dumps(original)) | |
| self.assertEqual(data.dynamic, original) | |
| def test_round_trip_int(self): | |
| for original in (0, 11, -1): | |
| data = lldb.SBStructuredData() | |
| data.SetFromJSON(json.dumps(original)) | |
| self.assertEqual(int(data), int(original)) | |
| def test_round_trip_float(self): | |
| for original in (0, 11, -1, 0.0, 4.5, -0.25): | |
| data = lldb.SBStructuredData() | |
| data.SetFromJSON(json.dumps(original)) | |
| self.assertEqual(float(data), float(original)) | |
| def test_iterate_array(self): | |
| array = [0, 1, 2] | |
| data = lldb.SBStructuredData() | |
| data.SetFromJSON(json.dumps(array)) | |
| for value in data: | |
| self.assertEqual(value, array.pop(0)) | |
| def test_iterate_dictionary(self): | |
| dictionary = {"0": 0, "1": 1, "2": 2} | |
| keys = set(dictionary.keys()) | |
| data = lldb.SBStructuredData() | |
| data.SetFromJSON(json.dumps(dictionary)) | |
| for key in data: | |
| self.assertIn(key, keys) | |
| keys.remove(key) | |
| def test_getitem_array(self): | |
| array = [1, 2, 3] | |
| data = lldb.SBStructuredData() | |
| data.SetFromJSON(json.dumps(array)) | |
| for i in range(len(array)): | |
| self.assertEqual(data[i], array[i]) | |
| def test_getitem_dictionary(self): | |
| dictionary = {"one": 1, "two": 2, "three": 3} | |
| data = lldb.SBStructuredData() | |
| data.SetFromJSON(json.dumps(dictionary)) | |
| for key in dictionary: | |
| self.assertEqual(data[key], dictionary[key]) |