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