diff options
| author | Daniel Sanders <daniel_l_sanders@apple.com> | 2025-10-21 01:38:24 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-21 09:38:24 +0100 |
| commit | f188c97cc193773071b0b61ebf214705fb84189e (patch) | |
| tree | 8d3c609a03c13e281933368b82f5a6ac8a30ad31 /lldb/packages/Python/lldbsuite/test | |
| parent | 8da0df49568206544f64eea890e51354d04187cd (diff) | |
| download | llvm-f188c97cc193773071b0b61ebf214705fb84189e.zip llvm-f188c97cc193773071b0b61ebf214705fb84189e.tar.gz llvm-f188c97cc193773071b0b61ebf214705fb84189e.tar.bz2 | |
[lldb] Add bidirectional packetLog to gdbclientutils.py (#162176)
While debugging the tests for #155000 I found it helpful to have both
sides
of the simulated gdb-rsp traffic rather than just the responses so I've
extended
the packetLog in MockGDBServerResponder to record traffic in both
directions.
Tests have been updated accordingly
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test')
| -rw-r--r-- | lldb/packages/Python/lldbsuite/test/gdbclientutils.py | 66 | ||||
| -rw-r--r-- | lldb/packages/Python/lldbsuite/test/lldbgdbclient.py | 18 |
2 files changed, 66 insertions, 18 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py index 1a2860a..bd2fdc0 100644 --- a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py +++ b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py @@ -5,8 +5,9 @@ import io import threading import socket import traceback +from enum import Enum from lldbsuite.support import seven -from typing import Optional, List, Tuple +from typing import Optional, List, Tuple, Union, Sequence def checksum(message): @@ -76,6 +77,35 @@ def hex_decode_bytes(hex_bytes): return out +class PacketDirection(Enum): + RECV = "recv" + SEND = "send" + + +class PacketLog: + def __init__(self): + self._packets: list[tuple[PacketDirection, str]] = [] + + def add_sent(self, packet: str): + self._packets.append((PacketDirection.SEND, packet)) + + def add_received(self, packet: str): + self._packets.append((PacketDirection.RECV, packet)) + + def get_sent(self): + return [ + pkt for direction, pkt in self._packets if direction == PacketDirection.SEND + ] + + def get_received(self): + return [ + pkt for direction, pkt in self._packets if direction == PacketDirection.RECV + ] + + def __iter__(self): + return iter(self._packets) + + class MockGDBServerResponder: """ A base class for handling client packets and issuing server responses for @@ -90,21 +120,33 @@ class MockGDBServerResponder: registerCount: int = 40 - class RESPONSE_DISCONNECT: - pass + class SpecialResponse(Enum): + RESPONSE_DISCONNECT = 0 + RESPONSE_NONE = 1 - class RESPONSE_NONE: - pass + RESPONSE_DISCONNECT = SpecialResponse.RESPONSE_DISCONNECT + RESPONSE_NONE = SpecialResponse.RESPONSE_NONE + Response = Union[str, SpecialResponse] def __init__(self): - self.packetLog: List[str] = [] + self.packetLog = PacketLog() - def respond(self, packet): + def respond(self, packet: str) -> Sequence[Response]: """ Return the unframed packet data that the server should issue in response to the given packet received from the client. """ - self.packetLog.append(packet) + self.packetLog.add_received(packet) + response = self._respond_impl(packet) + if not isinstance(response, list): + response = [response] + for part in response: + if isinstance(part, self.SpecialResponse): + continue + self.packetLog.add_sent(part) + return response + + def _respond_impl(self, packet) -> Union[Response, List[Response]]: if packet is MockGDBServer.PACKET_INTERRUPT: return self.interrupt() if packet == "c": @@ -664,17 +706,19 @@ class MockGDBServer: # adding validation code to make sure the client only sends ACKs # when it's supposed to. return - response = "" + response = [""] # We'll handle the ack stuff here since it's not something any of the # tests will be concerned about, and it'll get turned off quickly anyway. if self._shouldSendAck: self._socket.sendall(seven.bitcast_to_bytes("+")) if packet == "QStartNoAckMode": self._shouldSendAck = False - response = "OK" + response = ["OK"] elif self.responder is not None: # Delegate everything else to our responder response = self.responder.respond(packet) + # MockGDBServerResponder no longer returns non-lists but others like + # ReverseTestBase still do if not isinstance(response, list): response = [response] for part in response: @@ -682,6 +726,8 @@ class MockGDBServer: continue if part is MockGDBServerResponder.RESPONSE_DISCONNECT: raise self.TerminateConnectionException() + # Should have handled the non-str's above + assert isinstance(part, str) self._sendPacket(part) PACKET_ACK = object() diff --git a/lldb/packages/Python/lldbsuite/test/lldbgdbclient.py b/lldb/packages/Python/lldbsuite/test/lldbgdbclient.py index 599f787..9b2a89e 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbgdbclient.py +++ b/lldb/packages/Python/lldbsuite/test/lldbgdbclient.py @@ -10,7 +10,7 @@ class GDBRemoteTestBase(TestBase): Base class for GDB client tests. This class will setup and start a mock GDB server for the test to use. - It also provides assertPacketLogContains, which simplifies the checking + It also provides assertPacketLogReceived, which simplifies the checking of packets sent by the client. """ @@ -60,30 +60,32 @@ class GDBRemoteTestBase(TestBase): self.assertTrue(process, PROCESS_IS_VALID) return process - def assertPacketLogContains(self, packets, log=None): + def assertPacketLogReceived(self, packets, log: PacketLog = None): """ - Assert that the mock server's packet log contains the given packets. + Assert that the mock server's packet log received the given packets. The packet log includes all packets sent by the client and received - by the server. This fuction makes it easy to verify that the client + by the server. This function makes it easy to verify that the client sent the expected packets to the server. The check does not require that the packets be consecutive, but does require that they are ordered in the log as they ordered in the arg. """ if log is None: - log = self.server.responder.packetLog + received = self.server.responder.packetLog.get_received() + else: + received = log.get_received() i = 0 j = 0 - while i < len(packets) and j < len(log): - if log[j] == packets[i]: + while i < len(packets) and j < len(received): + if received[j] == packets[i]: i += 1 j += 1 if i < len(packets): self.fail( "Did not receive: %s\nLast 10 packets:\n\t%s" - % (packets[i], "\n\t".join(log)) + % (packets[i], "\n\t".join(received)) ) |
