1import gdbremote_testcase
2import lldbgdbserverutils
3from lldbsuite.test.decorators import *
4from lldbsuite.test.lldbtest import *
5from lldbsuite.test import lldbutil
6
7
8class TestGdbRemoteProcessInfo(gdbremote_testcase.GdbRemoteTestCaseBase):
9
10    mydir = TestBase.compute_mydir(__file__)
11
12    def test_qProcessInfo_returns_running_process(self):
13        self.build()
14        procs = self.prep_debug_monitor_and_inferior()
15        self.add_process_info_collection_packets()
16
17        # Run the stream
18        context = self.expect_gdbremote_sequence()
19        self.assertIsNotNone(context)
20
21        # Gather process info response
22        process_info = self.parse_process_info_response(context)
23        self.assertIsNotNone(process_info)
24
25        # Ensure the process id looks reasonable.
26        pid_text = process_info.get("pid")
27        self.assertIsNotNone(pid_text)
28        pid = int(pid_text, base=16)
29        self.assertNotEqual(0, pid)
30
31        # If possible, verify that the process is running.
32        self.assertTrue(lldbgdbserverutils.process_is_running(pid, True))
33
34    def test_attach_commandline_qProcessInfo_reports_correct_pid(self):
35        self.build()
36        self.set_inferior_startup_attach()
37        procs = self.prep_debug_monitor_and_inferior()
38        self.assertIsNotNone(procs)
39        self.add_process_info_collection_packets()
40
41        # Run the stream
42        context = self.expect_gdbremote_sequence()
43        self.assertIsNotNone(context)
44
45        # Gather process info response
46        process_info = self.parse_process_info_response(context)
47        self.assertIsNotNone(process_info)
48
49        # Ensure the process id matches what we expected.
50        pid_text = process_info.get('pid', None)
51        self.assertIsNotNone(pid_text)
52        reported_pid = int(pid_text, base=16)
53        self.assertEqual(reported_pid, procs["inferior"].pid)
54
55    def test_qProcessInfo_reports_valid_endian(self):
56        self.build()
57        procs = self.prep_debug_monitor_and_inferior()
58        self.add_process_info_collection_packets()
59
60        # Run the stream
61        context = self.expect_gdbremote_sequence()
62        self.assertIsNotNone(context)
63
64        # Gather process info response
65        process_info = self.parse_process_info_response(context)
66        self.assertIsNotNone(process_info)
67
68        # Ensure the process id looks reasonable.
69        endian = process_info.get("endian")
70        self.assertIsNotNone(endian)
71        self.assertIn(endian, ["little", "big", "pdp"])
72
73    def qProcessInfo_contains_keys(self, expected_key_set):
74        procs = self.prep_debug_monitor_and_inferior()
75        self.add_process_info_collection_packets()
76
77        # Run the stream
78        context = self.expect_gdbremote_sequence()
79        self.assertIsNotNone(context)
80
81        # Gather process info response
82        process_info = self.parse_process_info_response(context)
83        self.assertIsNotNone(process_info)
84
85        # Ensure the expected keys are present and non-None within the process
86        # info.
87        missing_key_set = set()
88        for expected_key in expected_key_set:
89            if expected_key not in process_info:
90                missing_key_set.add(expected_key)
91
92        self.assertEqual(
93            missing_key_set,
94            set(),
95            "the listed keys are missing in the qProcessInfo result")
96
97    def qProcessInfo_does_not_contain_keys(self, absent_key_set):
98        procs = self.prep_debug_monitor_and_inferior()
99        self.add_process_info_collection_packets()
100
101        # Run the stream
102        context = self.expect_gdbremote_sequence()
103        self.assertIsNotNone(context)
104
105        # Gather process info response
106        process_info = self.parse_process_info_response(context)
107        self.assertIsNotNone(process_info)
108
109        # Ensure the unexpected keys are not present
110        unexpected_key_set = set()
111        for unexpected_key in absent_key_set:
112            if unexpected_key in process_info:
113                unexpected_key_set.add(unexpected_key)
114
115        self.assertEqual(
116            unexpected_key_set,
117            set(),
118            "the listed keys were present but unexpected in qProcessInfo result")
119
120    @add_test_categories(["debugserver"])
121    def test_qProcessInfo_contains_cputype_cpusubtype(self):
122        self.build()
123        self.qProcessInfo_contains_keys(set(['cputype', 'cpusubtype']))
124
125    @add_test_categories(["llgs"])
126    def test_qProcessInfo_contains_triple_ppid(self):
127        self.build()
128        self.qProcessInfo_contains_keys(set(['triple', 'parent-pid']))
129
130    @add_test_categories(["debugserver"])
131    def test_qProcessInfo_does_not_contain_triple(self):
132        self.build()
133        # We don't expect to see triple on darwin.  If we do, we'll prefer triple
134        # to cputype/cpusubtype and skip some darwin-based ProcessGDBRemote ArchSpec setup
135        # for the remote Host and Process.
136        self.qProcessInfo_does_not_contain_keys(set(['triple']))
137
138    @add_test_categories(["llgs"])
139    def test_qProcessInfo_does_not_contain_cputype_cpusubtype(self):
140        self.build()
141        self.qProcessInfo_does_not_contain_keys(set(['cputype', 'cpusubtype']))
142