158d28b93SMichał Górnyimport gdbremote_testcase 258d28b93SMichał Górnyimport lldbgdbserverutils 358d28b93SMichał Górnyfrom lldbsuite.test.decorators import * 458d28b93SMichał Górnyfrom lldbsuite.test.lldbtest import * 558d28b93SMichał Górnyfrom lldbgdbserverutils import * 658d28b93SMichał Górny 758d28b93SMichał Górnyimport xml.etree.ElementTree as ET 858d28b93SMichał Górny 958d28b93SMichał Górny 10*a6cc363bSDmitry Vasilyev@skipIfRemote 11eacefba9SDmitry Vasilyev@skipIf(hostoslist=["windows"]) 1258d28b93SMichał Górnyclass PtyServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase): 1358d28b93SMichał Górny def setUp(self): 1458d28b93SMichał Górny super().setUp() 1558d28b93SMichał Górny import pty 1658d28b93SMichał Górny import tty 172238dcc3SJonas Devlieghere 1852a3ed5bSQuinn Pham primary, secondary = pty.openpty() 1952a3ed5bSQuinn Pham tty.setraw(primary) 202238dcc3SJonas Devlieghere self._primary = io.FileIO(primary, "r+b") 212238dcc3SJonas Devlieghere self._secondary = io.FileIO(secondary, "r+b") 2258d28b93SMichał Górny 2358d28b93SMichał Górny def get_debug_monitor_command_line_args(self, attach_pid=None): 2458d28b93SMichał Górny commandline_args = self.debug_monitor_extra_args 2558d28b93SMichał Górny if attach_pid: 2658d28b93SMichał Górny commandline_args += ["--attach=%d" % attach_pid] 2758d28b93SMichał Górny 2858d28b93SMichał Górny libc = ctypes.CDLL(None) 2958d28b93SMichał Górny libc.ptsname.argtypes = (ctypes.c_int,) 3058d28b93SMichał Górny libc.ptsname.restype = ctypes.c_char_p 3152a3ed5bSQuinn Pham pty_path = libc.ptsname(self._primary.fileno()).decode() 3258d28b93SMichał Górny commandline_args += ["serial://%s" % (pty_path,)] 3358d28b93SMichał Górny return commandline_args 3458d28b93SMichał Górny 3558d28b93SMichał Górny def connect_to_debug_monitor(self, attach_pid=None): 3658d28b93SMichał Górny self.reverse_connect = False 3758d28b93SMichał Górny server = self.launch_debug_monitor(attach_pid=attach_pid) 3858d28b93SMichał Górny self.assertIsNotNone(server) 3958d28b93SMichał Górny 4058d28b93SMichał Górny # TODO: make it into proper abstraction 4158d28b93SMichał Górny class FakeSocket: 4258d28b93SMichał Górny def __init__(self, fd): 4358d28b93SMichał Górny self.fd = fd 4458d28b93SMichał Górny 4558d28b93SMichał Górny def sendall(self, frame): 4658d28b93SMichał Górny self.fd.write(frame) 4758d28b93SMichał Górny 4858d28b93SMichał Górny def recv(self, count): 4958d28b93SMichał Górny return self.fd.read(count) 5058d28b93SMichał Górny 5152a3ed5bSQuinn Pham self.sock = FakeSocket(self._primary) 5258d28b93SMichał Górny self._server = Server(self.sock, server) 5358d28b93SMichał Górny return server 5458d28b93SMichał Górny 5558d28b93SMichał Górny @add_test_categories(["llgs"]) 5658d28b93SMichał Górny def test_pty_server(self): 5758d28b93SMichał Górny self.build() 5858d28b93SMichał Górny self.set_inferior_startup_launch() 5958d28b93SMichał Górny self.prep_debug_monitor_and_inferior() 6058d28b93SMichał Górny 6158d28b93SMichał Górny # target.xml transfer should trigger a large enough packet to check 6258d28b93SMichał Górny # for partial write regression 632238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 642238dcc3SJonas Devlieghere [ 6558d28b93SMichał Górny "read packet: $qXfer:features:read:target.xml:0,200000#00", 6658d28b93SMichał Górny { 6758d28b93SMichał Górny "direction": "send", 68ba822e24SDavid Spickett "regex": re.compile("^\$l(.+)#[0-9a-fA-F]{2}$", flags=re.DOTALL), 6958d28b93SMichał Górny "capture": {1: "target_xml"}, 702238dcc3SJonas Devlieghere }, 712238dcc3SJonas Devlieghere ], 722238dcc3SJonas Devlieghere True, 732238dcc3SJonas Devlieghere ) 7458d28b93SMichał Górny context = self.expect_gdbremote_sequence() 7558d28b93SMichał Górny # verify that we have received a complete, non-malformed XML 7658d28b93SMichał Górny self.assertIsNotNone(ET.fromstring(context.get("target_xml"))) 77