18fa2394bSMichał Górnyimport lldb 28fa2394bSMichał Górnyfrom lldbsuite.test.lldbtest import * 38fa2394bSMichał Górnyfrom lldbsuite.test.decorators import * 433c0f93fSPavel Labathfrom lldbsuite.test.gdbclientutils import * 533c0f93fSPavel Labathfrom lldbsuite.test.lldbgdbclient import GDBRemoteTestBase 68fa2394bSMichał Górny 78fa2394bSMichał Górny 88fa2394bSMichał Górny@skipIfWindows 98fa2394bSMichał Górnyclass TestPty(GDBRemoteTestBase): 108fa2394bSMichał Górny mydir = TestBase.compute_mydir(__file__) 118fa2394bSMichał Górny server_socket_class = PtyServerSocket 128fa2394bSMichał Górny 134a7b4beaSMichał Górny def get_term_attrs(self): 144a7b4beaSMichał Górny import termios 15*f3b7cc8bSPavel Labath return termios.tcgetattr(self._secondary_socket) 164a7b4beaSMichał Górny 174a7b4beaSMichał Górny def setUp(self): 184a7b4beaSMichał Górny super().setUp() 19*f3b7cc8bSPavel Labath # Duplicate the pty descriptors so we can inspect the pty state after 20*f3b7cc8bSPavel Labath # they are closed 21*f3b7cc8bSPavel Labath self._primary_socket = os.dup(self.server._socket._primary.name) 22*f3b7cc8bSPavel Labath self._secondary_socket = os.dup(self.server._socket._secondary.name) 234a7b4beaSMichał Górny self.orig_attr = self.get_term_attrs() 244a7b4beaSMichał Górny 254a7b4beaSMichał Górny def assert_raw_mode(self, current_attr): 264a7b4beaSMichał Górny import termios 274a7b4beaSMichał Górny self.assertEqual(current_attr[0] & (termios.BRKINT | 284a7b4beaSMichał Górny termios.PARMRK | 294a7b4beaSMichał Górny termios.ISTRIP | termios.INLCR | 304a7b4beaSMichał Górny termios.IGNCR | termios.ICRNL | 314a7b4beaSMichał Górny termios.IXON), 324a7b4beaSMichał Górny 0) 334a7b4beaSMichał Górny self.assertEqual(current_attr[1] & termios.OPOST, 0) 344a7b4beaSMichał Górny self.assertEqual(current_attr[2] & termios.CSIZE, termios.CS8) 354a7b4beaSMichał Górny self.assertEqual(current_attr[3] & (termios.ICANON | termios.ECHO | 364a7b4beaSMichał Górny termios.ISIG | termios.IEXTEN), 374a7b4beaSMichał Górny 0) 384a7b4beaSMichał Górny self.assertEqual(current_attr[6][termios.VMIN], 1) 394a7b4beaSMichał Górny self.assertEqual(current_attr[6][termios.VTIME], 0) 404a7b4beaSMichał Górny 414a7b4beaSMichał Górny def get_parity_flags(self, attr): 424a7b4beaSMichał Górny import termios 434a7b4beaSMichał Górny return attr[2] & (termios.PARENB | termios.PARODD) 444a7b4beaSMichał Górny 454a7b4beaSMichał Górny def get_stop_bit_flags(self, attr): 464a7b4beaSMichał Górny import termios 474a7b4beaSMichał Górny return attr[2] & termios.CSTOPB 484a7b4beaSMichał Górny 498fa2394bSMichał Górny def test_process_connect_sync(self): 508fa2394bSMichał Górny """Test the process connect command in synchronous mode""" 518fa2394bSMichał Górny try: 528fa2394bSMichał Górny self.dbg.SetAsync(False) 538fa2394bSMichał Górny self.expect("platform select remote-gdb-server", 548fa2394bSMichał Górny substrs=['Platform: remote-gdb-server', 'Connected: no']) 558fa2394bSMichał Górny self.expect("process connect " + self.server.get_connect_url(), 568fa2394bSMichał Górny substrs=['Process', 'stopped']) 574a7b4beaSMichał Górny 584a7b4beaSMichał Górny current_attr = self.get_term_attrs() 594a7b4beaSMichał Górny # serial:// should set raw mode 604a7b4beaSMichał Górny self.assert_raw_mode(current_attr) 614a7b4beaSMichał Górny # other parameters should be unmodified 624a7b4beaSMichał Górny self.assertEqual(current_attr[4:6], self.orig_attr[4:6]) 634a7b4beaSMichał Górny self.assertEqual(self.get_parity_flags(current_attr), 644a7b4beaSMichał Górny self.get_parity_flags(self.orig_attr)) 654a7b4beaSMichał Górny self.assertEqual(self.get_stop_bit_flags(current_attr), 664a7b4beaSMichał Górny self.get_stop_bit_flags(self.orig_attr)) 678fa2394bSMichał Górny finally: 6845f97950SMichał Górny self.dbg.GetSelectedTarget().GetProcess().Kill() 694a7b4beaSMichał Górny # original mode should be restored on exit 704a7b4beaSMichał Górny self.assertEqual(self.get_term_attrs(), self.orig_attr) 718fa2394bSMichał Górny 728fa2394bSMichał Górny def test_process_connect_async(self): 738fa2394bSMichał Górny """Test the process connect command in asynchronous mode""" 748fa2394bSMichał Górny try: 758fa2394bSMichał Górny self.dbg.SetAsync(True) 768fa2394bSMichał Górny self.expect("platform select remote-gdb-server", 778fa2394bSMichał Górny substrs=['Platform: remote-gdb-server', 'Connected: no']) 788fa2394bSMichał Górny self.expect("process connect " + self.server.get_connect_url(), 798fa2394bSMichał Górny matching=False, 808fa2394bSMichał Górny substrs=['Process', 'stopped']) 818fa2394bSMichał Górny lldbutil.expect_state_changes(self, self.dbg.GetListener(), 828fa2394bSMichał Górny self.process(), [lldb.eStateStopped]) 834a7b4beaSMichał Górny 844a7b4beaSMichał Górny current_attr = self.get_term_attrs() 854a7b4beaSMichał Górny # serial:// should set raw mode 864a7b4beaSMichał Górny self.assert_raw_mode(current_attr) 874a7b4beaSMichał Górny # other parameters should be unmodified 884a7b4beaSMichał Górny self.assertEqual(current_attr[4:6], self.orig_attr[4:6]) 894a7b4beaSMichał Górny self.assertEqual(self.get_parity_flags(current_attr), 904a7b4beaSMichał Górny self.get_parity_flags(self.orig_attr)) 914a7b4beaSMichał Górny self.assertEqual(self.get_stop_bit_flags(current_attr), 924a7b4beaSMichał Górny self.get_stop_bit_flags(self.orig_attr)) 938fa2394bSMichał Górny finally: 9445f97950SMichał Górny self.dbg.GetSelectedTarget().GetProcess().Kill() 9545f97950SMichał Górny lldbutil.expect_state_changes(self, self.dbg.GetListener(), 9645f97950SMichał Górny self.process(), [lldb.eStateExited]) 974a7b4beaSMichał Górny # original mode should be restored on exit 984a7b4beaSMichał Górny self.assertEqual(self.get_term_attrs(), self.orig_attr) 994a7b4beaSMichał Górny 1004a7b4beaSMichał Górny def test_connect_via_file(self): 1014a7b4beaSMichał Górny """Test connecting via the legacy file:// URL""" 1024a7b4beaSMichał Górny import termios 1034a7b4beaSMichał Górny try: 1044a7b4beaSMichał Górny self.expect("platform select remote-gdb-server", 1054a7b4beaSMichał Górny substrs=['Platform: remote-gdb-server', 'Connected: no']) 1064a7b4beaSMichał Górny self.expect("process connect file://" + 1074a7b4beaSMichał Górny self.server.get_connect_address(), 1084a7b4beaSMichał Górny substrs=['Process', 'stopped']) 1094a7b4beaSMichał Górny 1104a7b4beaSMichał Górny # file:// sets baud rate and some raw-related flags 1114a7b4beaSMichał Górny current_attr = self.get_term_attrs() 1124a7b4beaSMichał Górny self.assertEqual(current_attr[3] & (termios.ICANON | termios.ECHO | 1134a7b4beaSMichał Górny termios.ECHOE | termios.ISIG), 1144a7b4beaSMichał Górny 0) 1154a7b4beaSMichał Górny self.assertEqual(current_attr[4], termios.B115200) 1164a7b4beaSMichał Górny self.assertEqual(current_attr[5], termios.B115200) 1174a7b4beaSMichał Górny self.assertEqual(current_attr[6][termios.VMIN], 1) 1184a7b4beaSMichał Górny self.assertEqual(current_attr[6][termios.VTIME], 0) 1194a7b4beaSMichał Górny finally: 1204a7b4beaSMichał Górny self.dbg.GetSelectedTarget().GetProcess().Kill() 1214a7b4beaSMichał Górny 1224a7b4beaSMichał Górny def test_process_connect_params(self): 1234a7b4beaSMichał Górny """Test serial:// URL with parameters""" 1244a7b4beaSMichał Górny import termios 1254a7b4beaSMichał Górny try: 1264a7b4beaSMichał Górny self.expect("platform select remote-gdb-server", 1274a7b4beaSMichał Górny substrs=['Platform: remote-gdb-server', 'Connected: no']) 1284a7b4beaSMichał Górny self.expect("process connect " + self.server.get_connect_url() + 1294a7b4beaSMichał Górny "?baud=115200&stop-bits=2", 1304a7b4beaSMichał Górny substrs=['Process', 'stopped']) 1314a7b4beaSMichał Górny 1324a7b4beaSMichał Górny current_attr = self.get_term_attrs() 1334a7b4beaSMichał Górny self.assert_raw_mode(current_attr) 1344a7b4beaSMichał Górny self.assertEqual(current_attr[4:6], 2 * [termios.B115200]) 1354a7b4beaSMichał Górny self.assertEqual(self.get_parity_flags(current_attr), 1364a7b4beaSMichał Górny self.get_parity_flags(self.orig_attr)) 1374a7b4beaSMichał Górny self.assertEqual(self.get_stop_bit_flags(current_attr), 1384a7b4beaSMichał Górny termios.CSTOPB) 1394a7b4beaSMichał Górny finally: 1404a7b4beaSMichał Górny self.dbg.GetSelectedTarget().GetProcess().Kill() 1414a7b4beaSMichał Górny # original mode should be restored on exit 1424a7b4beaSMichał Górny self.assertEqual(self.get_term_attrs(), self.orig_attr) 143