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