xref: /llvm-project/lldb/packages/Python/lldbsuite/test/lldbgdbclient.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1import os
2import os.path
3import lldb
4from lldbsuite.test.lldbtest import *
5from lldbsuite.test.gdbclientutils import *
6
7
8class GDBRemoteTestBase(TestBase):
9    """
10    Base class for GDB client tests.
11
12    This class will setup and start a mock GDB server for the test to use.
13    It also provides assertPacketLogContains, which simplifies the checking
14    of packets sent by the client.
15    """
16
17    NO_DEBUG_INFO_TESTCASE = True
18    server = None
19    server_socket_class = TCPServerSocket
20
21    def setUp(self):
22        TestBase.setUp(self)
23        self.server = MockGDBServer(self.server_socket_class())
24        self.server.start()
25
26    def tearDown(self):
27        # TestBase.tearDown will kill the process, but we need to kill it early
28        # so its client connection closes and we can stop the server before
29        # finally calling the base tearDown.
30        if self.process() is not None:
31            self.process().Kill()
32        self.server.stop()
33        TestBase.tearDown(self)
34
35    def createTarget(self, yaml_path):
36        """
37        Create a target by auto-generating the object based on the given yaml
38        instructions.
39
40        This will track the generated object so it can be automatically removed
41        during tearDown.
42        """
43        yaml_base, ext = os.path.splitext(yaml_path)
44        obj_path = self.getBuildArtifact(yaml_base)
45        self.yaml2obj(yaml_path, obj_path)
46        return self.dbg.CreateTarget(obj_path)
47
48    def connect(self, target):
49        """
50        Create a process by connecting to the mock GDB server.
51
52        Includes assertions that the process was successfully created.
53        """
54        listener = self.dbg.GetListener()
55        error = lldb.SBError()
56        process = target.ConnectRemote(
57            listener, self.server.get_connect_url(), "gdb-remote", error
58        )
59        self.assertTrue(error.Success(), error.description)
60        self.assertTrue(process, PROCESS_IS_VALID)
61        return process
62
63    def assertPacketLogContains(self, packets, log=None):
64        """
65        Assert that the mock server's packet log contains the given packets.
66
67        The packet log includes all packets sent by the client and received
68        by the server.  This fuction makes it easy to verify that the client
69        sent the expected packets to the server.
70
71        The check does not require that the packets be consecutive, but does
72        require that they are ordered in the log as they ordered in the arg.
73        """
74        if log is None:
75            log = self.server.responder.packetLog
76        i = 0
77        j = 0
78
79        while i < len(packets) and j < len(log):
80            if log[j] == packets[i]:
81                i += 1
82            j += 1
83        if i < len(packets):
84            self.fail(
85                "Did not receive: %s\nLast 10 packets:\n\t%s"
86                % (packets[i], "\n\t".join(log))
87            )
88
89
90class GDBPlatformClientTestBase(GDBRemoteTestBase):
91    """
92    Base class for platform server clients.
93
94    This class extends GDBRemoteTestBase by automatically connecting
95    via "platform connect" in the setUp() method.
96    """
97
98    def setUp(self):
99        super().setUp()
100        self.runCmd("platform select remote-gdb-server")
101        self.runCmd("platform connect " + self.server.get_connect_url())
102        self.assertTrue(self.dbg.GetSelectedPlatform().IsConnected())
103
104    def tearDown(self):
105        self.dbg.GetSelectedPlatform().DisconnectRemote()
106        super().tearDown()
107