| # lldb test suite imports | |
| from lldbsuite.test.decorators import * | |
| from lldbsuite.test.lldbtest import TestBase | |
| # gdb-remote-specific imports | |
| import lldbgdbserverutils | |
| from gdbremote_testcase import GdbRemoteTestCaseBase | |
| class TestGdbRemoteHostInfo(GdbRemoteTestCaseBase): | |
| KNOWN_HOST_INFO_KEYS = set( | |
| [ | |
| "addressing_bits", | |
| "arch", | |
| "cpusubtype", | |
| "cputype", | |
| "default_packet_timeout", | |
| "distribution_id", | |
| "endian", | |
| "hostname", | |
| "maccatalyst_version", | |
| "os_build", | |
| "os_kernel", | |
| "os_version", | |
| "ostype", | |
| "ptrsize", | |
| "triple", | |
| "vendor", | |
| "vm-page-size", | |
| "watchpoint_exceptions_received", | |
| ] | |
| ) | |
| DARWIN_REQUIRED_HOST_INFO_KEYS = set( | |
| [ | |
| "cputype", | |
| "cpusubtype", | |
| "endian", | |
| "ostype", | |
| "ptrsize", | |
| "vendor", | |
| "watchpoint_exceptions_received", | |
| ] | |
| ) | |
| def add_host_info_collection_packets(self): | |
| self.test_sequence.add_log_lines( | |
| [ | |
| "read packet: $qHostInfo#9b", | |
| { | |
| "direction": "send", | |
| "regex": r"^\$(.+)#[0-9a-fA-F]{2}$", | |
| "capture": {1: "host_info_raw"}, | |
| }, | |
| ], | |
| True, | |
| ) | |
| def parse_host_info_response(self, context): | |
| # Ensure we have a host info response. | |
| self.assertIsNotNone(context) | |
| host_info_raw = context.get("host_info_raw") | |
| self.assertIsNotNone(host_info_raw) | |
| # Pull out key:value; pairs. | |
| host_info_dict = { | |
| match.group(1): match.group(2) | |
| for match in re.finditer(r"([^:]+):([^;]+);", host_info_raw) | |
| } | |
| # Validate keys are known. | |
| for key, val in list(host_info_dict.items()): | |
| self.assertIn( | |
| key, self.KNOWN_HOST_INFO_KEYS, "unknown qHostInfo key: " + key | |
| ) | |
| self.assertIsNotNone(val) | |
| # Return the key:val pairs. | |
| return host_info_dict | |
| def get_qHostInfo_response(self): | |
| # Launch the debug monitor stub, attaching to the inferior. | |
| server = self.connect_to_debug_monitor() | |
| self.assertIsNotNone(server) | |
| self.do_handshake() | |
| # Request qHostInfo and get response | |
| self.add_host_info_collection_packets() | |
| context = self.expect_gdbremote_sequence() | |
| self.assertIsNotNone(context) | |
| # Parse qHostInfo response. | |
| host_info = self.parse_host_info_response(context) | |
| self.assertIsNotNone(host_info) | |
| self.assertGreater( | |
| len(host_info), | |
| 0, | |
| "qHostInfo should have returned " "at least one key:val pair.", | |
| ) | |
| return host_info | |
| def validate_darwin_minimum_host_info_keys(self, host_info_dict): | |
| self.assertIsNotNone(host_info_dict) | |
| missing_keys = [ | |
| key | |
| for key in self.DARWIN_REQUIRED_HOST_INFO_KEYS | |
| if key not in host_info_dict | |
| ] | |
| self.assertEqual( | |
| 0, | |
| len(missing_keys), | |
| "qHostInfo is missing the following required " "keys: " + str(missing_keys), | |
| ) | |
| def test_qHostInfo_returns_at_least_one_key_val_pair(self): | |
| self.build() | |
| self.get_qHostInfo_response() | |
| @requireDarwin | |
| def test_qHostInfo_contains_darwin_required_keys(self): | |
| self.build() | |
| host_info_dict = self.get_qHostInfo_response() | |
| self.validate_darwin_minimum_host_info_keys(host_info_dict) |