1import gdbremote_testcase 2import lldbgdbserverutils 3from lldbsuite.test.decorators import * 4from lldbsuite.test.lldbtest import * 5from lldbgdbserverutils import * 6 7import xml.etree.ElementTree as ET 8 9 10@skipIfRemote 11@skipIf(hostoslist=["windows"]) 12class PtyServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase): 13 def setUp(self): 14 super().setUp() 15 import pty 16 import tty 17 18 primary, secondary = pty.openpty() 19 tty.setraw(primary) 20 self._primary = io.FileIO(primary, "r+b") 21 self._secondary = io.FileIO(secondary, "r+b") 22 23 def get_debug_monitor_command_line_args(self, attach_pid=None): 24 commandline_args = self.debug_monitor_extra_args 25 if attach_pid: 26 commandline_args += ["--attach=%d" % attach_pid] 27 28 libc = ctypes.CDLL(None) 29 libc.ptsname.argtypes = (ctypes.c_int,) 30 libc.ptsname.restype = ctypes.c_char_p 31 pty_path = libc.ptsname(self._primary.fileno()).decode() 32 commandline_args += ["serial://%s" % (pty_path,)] 33 return commandline_args 34 35 def connect_to_debug_monitor(self, attach_pid=None): 36 self.reverse_connect = False 37 server = self.launch_debug_monitor(attach_pid=attach_pid) 38 self.assertIsNotNone(server) 39 40 # TODO: make it into proper abstraction 41 class FakeSocket: 42 def __init__(self, fd): 43 self.fd = fd 44 45 def sendall(self, frame): 46 self.fd.write(frame) 47 48 def recv(self, count): 49 return self.fd.read(count) 50 51 self.sock = FakeSocket(self._primary) 52 self._server = Server(self.sock, server) 53 return server 54 55 @add_test_categories(["llgs"]) 56 def test_pty_server(self): 57 self.build() 58 self.set_inferior_startup_launch() 59 self.prep_debug_monitor_and_inferior() 60 61 # target.xml transfer should trigger a large enough packet to check 62 # for partial write regression 63 self.test_sequence.add_log_lines( 64 [ 65 "read packet: $qXfer:features:read:target.xml:0,200000#00", 66 { 67 "direction": "send", 68 "regex": re.compile("^\$l(.+)#[0-9a-fA-F]{2}$", flags=re.DOTALL), 69 "capture": {1: "target_xml"}, 70 }, 71 ], 72 True, 73 ) 74 context = self.expect_gdbremote_sequence() 75 # verify that we have received a complete, non-malformed XML 76 self.assertIsNotNone(ET.fromstring(context.get("target_xml"))) 77