xref: /llvm-project/lldb/test/API/tools/lldb-server/TestGdbRemoteHostInfo.py (revision 80fcecb13c388ff087a27a4b0e7ca3dd8c98eaa4)
199451b44SJordan Rupprecht# lldb test suite imports
299451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
399451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import TestBase
499451b44SJordan Rupprecht
599451b44SJordan Rupprecht# gdb-remote-specific imports
699451b44SJordan Rupprechtimport lldbgdbserverutils
799451b44SJordan Rupprechtfrom gdbremote_testcase import GdbRemoteTestCaseBase
899451b44SJordan Rupprecht
999451b44SJordan Rupprecht
1099451b44SJordan Rupprechtclass TestGdbRemoteHostInfo(GdbRemoteTestCaseBase):
112238dcc3SJonas Devlieghere    KNOWN_HOST_INFO_KEYS = set(
122238dcc3SJonas Devlieghere        [
13a749bd76SJonas Devlieghere            "addressing_bits",
1499451b44SJordan Rupprecht            "arch",
1599451b44SJordan Rupprecht            "cpusubtype",
16a749bd76SJonas Devlieghere            "cputype",
17a749bd76SJonas Devlieghere            "default_packet_timeout",
1899451b44SJordan Rupprecht            "distribution_id",
1999451b44SJordan Rupprecht            "endian",
2099451b44SJordan Rupprecht            "hostname",
21a749bd76SJonas Devlieghere            "maccatalyst_version",
2299451b44SJordan Rupprecht            "os_build",
2399451b44SJordan Rupprecht            "os_kernel",
2499451b44SJordan Rupprecht            "os_version",
25a749bd76SJonas Devlieghere            "ostype",
2699451b44SJordan Rupprecht            "ptrsize",
2799451b44SJordan Rupprecht            "triple",
2899451b44SJordan Rupprecht            "vendor",
299ea6dd5cSJason Molenda            "vm-page-size",
3099451b44SJordan Rupprecht            "watchpoint_exceptions_received",
312238dcc3SJonas Devlieghere        ]
322238dcc3SJonas Devlieghere    )
3399451b44SJordan Rupprecht
342238dcc3SJonas Devlieghere    DARWIN_REQUIRED_HOST_INFO_KEYS = set(
352238dcc3SJonas Devlieghere        [
3699451b44SJordan Rupprecht            "cputype",
3799451b44SJordan Rupprecht            "cpusubtype",
3899451b44SJordan Rupprecht            "endian",
3999451b44SJordan Rupprecht            "ostype",
4099451b44SJordan Rupprecht            "ptrsize",
4199451b44SJordan Rupprecht            "vendor",
422238dcc3SJonas Devlieghere            "watchpoint_exceptions_received",
432238dcc3SJonas Devlieghere        ]
442238dcc3SJonas Devlieghere    )
4599451b44SJordan Rupprecht
4699451b44SJordan Rupprecht    def add_host_info_collection_packets(self):
4799451b44SJordan Rupprecht        self.test_sequence.add_log_lines(
482238dcc3SJonas Devlieghere            [
492238dcc3SJonas Devlieghere                "read packet: $qHostInfo#9b",
502238dcc3SJonas Devlieghere                {
512238dcc3SJonas Devlieghere                    "direction": "send",
522238dcc3SJonas Devlieghere                    "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
532238dcc3SJonas Devlieghere                    "capture": {1: "host_info_raw"},
542238dcc3SJonas Devlieghere                },
552238dcc3SJonas Devlieghere            ],
562238dcc3SJonas Devlieghere            True,
572238dcc3SJonas Devlieghere        )
5899451b44SJordan Rupprecht
5999451b44SJordan Rupprecht    def parse_host_info_response(self, context):
6099451b44SJordan Rupprecht        # Ensure we have a host info response.
6199451b44SJordan Rupprecht        self.assertIsNotNone(context)
6299451b44SJordan Rupprecht        host_info_raw = context.get("host_info_raw")
6399451b44SJordan Rupprecht        self.assertIsNotNone(host_info_raw)
6499451b44SJordan Rupprecht
6599451b44SJordan Rupprecht        # Pull out key:value; pairs.
662238dcc3SJonas Devlieghere        host_info_dict = {
672238dcc3SJonas Devlieghere            match.group(1): match.group(2)
682238dcc3SJonas Devlieghere            for match in re.finditer(r"([^:]+):([^;]+);", host_info_raw)
692238dcc3SJonas Devlieghere        }
7099451b44SJordan Rupprecht
7199451b44SJordan Rupprecht        import pprint
722238dcc3SJonas Devlieghere
7399451b44SJordan Rupprecht        print("\nqHostInfo response:")
7499451b44SJordan Rupprecht        pprint.pprint(host_info_dict)
7599451b44SJordan Rupprecht
7699451b44SJordan Rupprecht        # Validate keys are known.
772238dcc3SJonas Devlieghere        for key, val in list(host_info_dict.items()):
782238dcc3SJonas Devlieghere            self.assertIn(
792238dcc3SJonas Devlieghere                key, self.KNOWN_HOST_INFO_KEYS, "unknown qHostInfo key: " + key
802238dcc3SJonas Devlieghere            )
8199451b44SJordan Rupprecht            self.assertIsNotNone(val)
8299451b44SJordan Rupprecht
8399451b44SJordan Rupprecht        # Return the key:val pairs.
8499451b44SJordan Rupprecht        return host_info_dict
8599451b44SJordan Rupprecht
8699451b44SJordan Rupprecht    def get_qHostInfo_response(self):
8799451b44SJordan Rupprecht        # Launch the debug monitor stub, attaching to the inferior.
8899451b44SJordan Rupprecht        server = self.connect_to_debug_monitor()
8999451b44SJordan Rupprecht        self.assertIsNotNone(server)
90872b1da6SPavel Labath        self.do_handshake()
9199451b44SJordan Rupprecht
9299451b44SJordan Rupprecht        # Request qHostInfo and get response
9399451b44SJordan Rupprecht        self.add_host_info_collection_packets()
9499451b44SJordan Rupprecht        context = self.expect_gdbremote_sequence()
9599451b44SJordan Rupprecht        self.assertIsNotNone(context)
9699451b44SJordan Rupprecht
9799451b44SJordan Rupprecht        # Parse qHostInfo response.
9899451b44SJordan Rupprecht        host_info = self.parse_host_info_response(context)
9999451b44SJordan Rupprecht        self.assertIsNotNone(host_info)
1002238dcc3SJonas Devlieghere        self.assertGreater(
1012238dcc3SJonas Devlieghere            len(host_info),
1022238dcc3SJonas Devlieghere            0,
1032238dcc3SJonas Devlieghere            "qHostInfo should have returned " "at least one key:val pair.",
1042238dcc3SJonas Devlieghere        )
10599451b44SJordan Rupprecht        return host_info
10699451b44SJordan Rupprecht
10799451b44SJordan Rupprecht    def validate_darwin_minimum_host_info_keys(self, host_info_dict):
10899451b44SJordan Rupprecht        self.assertIsNotNone(host_info_dict)
1092238dcc3SJonas Devlieghere        missing_keys = [
1102238dcc3SJonas Devlieghere            key
1112238dcc3SJonas Devlieghere            for key in self.DARWIN_REQUIRED_HOST_INFO_KEYS
1122238dcc3SJonas Devlieghere            if key not in host_info_dict
1132238dcc3SJonas Devlieghere        ]
114*80fcecb1SJonas Devlieghere        self.assertEqual(
1152238dcc3SJonas Devlieghere            0,
1162238dcc3SJonas Devlieghere            len(missing_keys),
1172238dcc3SJonas Devlieghere            "qHostInfo is missing the following required " "keys: " + str(missing_keys),
1182238dcc3SJonas Devlieghere        )
11999451b44SJordan Rupprecht
12076a718eeSPavel Labath    def test_qHostInfo_returns_at_least_one_key_val_pair(self):
12199451b44SJordan Rupprecht        self.build()
12299451b44SJordan Rupprecht        self.get_qHostInfo_response()
12399451b44SJordan Rupprecht
12499451b44SJordan Rupprecht    @skipUnlessDarwin
12576a718eeSPavel Labath    def test_qHostInfo_contains_darwin_required_keys(self):
12699451b44SJordan Rupprecht        self.build()
12799451b44SJordan Rupprecht        host_info_dict = self.get_qHostInfo_response()
12899451b44SJordan Rupprecht        self.validate_darwin_minimum_host_info_keys(host_info_dict)
129