1# lldb test suite imports 2from lldbsuite.test.decorators import * 3from lldbsuite.test.lldbtest import TestBase 4 5# gdb-remote-specific imports 6import lldbgdbserverutils 7from gdbremote_testcase import GdbRemoteTestCaseBase 8 9 10class TestGdbRemoteHostInfo(GdbRemoteTestCaseBase): 11 KNOWN_HOST_INFO_KEYS = set( 12 [ 13 "addressing_bits", 14 "arch", 15 "cpusubtype", 16 "cputype", 17 "default_packet_timeout", 18 "distribution_id", 19 "endian", 20 "hostname", 21 "maccatalyst_version", 22 "os_build", 23 "os_kernel", 24 "os_version", 25 "ostype", 26 "ptrsize", 27 "triple", 28 "vendor", 29 "vm-page-size", 30 "watchpoint_exceptions_received", 31 ] 32 ) 33 34 DARWIN_REQUIRED_HOST_INFO_KEYS = set( 35 [ 36 "cputype", 37 "cpusubtype", 38 "endian", 39 "ostype", 40 "ptrsize", 41 "vendor", 42 "watchpoint_exceptions_received", 43 ] 44 ) 45 46 def add_host_info_collection_packets(self): 47 self.test_sequence.add_log_lines( 48 [ 49 "read packet: $qHostInfo#9b", 50 { 51 "direction": "send", 52 "regex": r"^\$(.+)#[0-9a-fA-F]{2}$", 53 "capture": {1: "host_info_raw"}, 54 }, 55 ], 56 True, 57 ) 58 59 def parse_host_info_response(self, context): 60 # Ensure we have a host info response. 61 self.assertIsNotNone(context) 62 host_info_raw = context.get("host_info_raw") 63 self.assertIsNotNone(host_info_raw) 64 65 # Pull out key:value; pairs. 66 host_info_dict = { 67 match.group(1): match.group(2) 68 for match in re.finditer(r"([^:]+):([^;]+);", host_info_raw) 69 } 70 71 import pprint 72 73 print("\nqHostInfo response:") 74 pprint.pprint(host_info_dict) 75 76 # Validate keys are known. 77 for key, val in list(host_info_dict.items()): 78 self.assertIn( 79 key, self.KNOWN_HOST_INFO_KEYS, "unknown qHostInfo key: " + key 80 ) 81 self.assertIsNotNone(val) 82 83 # Return the key:val pairs. 84 return host_info_dict 85 86 def get_qHostInfo_response(self): 87 # Launch the debug monitor stub, attaching to the inferior. 88 server = self.connect_to_debug_monitor() 89 self.assertIsNotNone(server) 90 self.do_handshake() 91 92 # Request qHostInfo and get response 93 self.add_host_info_collection_packets() 94 context = self.expect_gdbremote_sequence() 95 self.assertIsNotNone(context) 96 97 # Parse qHostInfo response. 98 host_info = self.parse_host_info_response(context) 99 self.assertIsNotNone(host_info) 100 self.assertGreater( 101 len(host_info), 102 0, 103 "qHostInfo should have returned " "at least one key:val pair.", 104 ) 105 return host_info 106 107 def validate_darwin_minimum_host_info_keys(self, host_info_dict): 108 self.assertIsNotNone(host_info_dict) 109 missing_keys = [ 110 key 111 for key in self.DARWIN_REQUIRED_HOST_INFO_KEYS 112 if key not in host_info_dict 113 ] 114 self.assertEqual( 115 0, 116 len(missing_keys), 117 "qHostInfo is missing the following required " "keys: " + str(missing_keys), 118 ) 119 120 def test_qHostInfo_returns_at_least_one_key_val_pair(self): 121 self.build() 122 self.get_qHostInfo_response() 123 124 @skipUnlessDarwin 125 def test_qHostInfo_contains_darwin_required_keys(self): 126 self.build() 127 host_info_dict = self.get_qHostInfo_response() 128 self.validate_darwin_minimum_host_info_keys(host_info_dict) 129