18fa2394bSMichał Górnyimport lldb 28fa2394bSMichał Górnyfrom lldbsuite.test.lldbtest import * 38fa2394bSMichał Górnyfrom lldbsuite.test.decorators import * 4*33c0f93fSPavel Labathfrom lldbsuite.test.gdbclientutils import * 5*33c0f93fSPavel 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 1552a3ed5bSQuinn Pham return termios.tcgetattr(self.server._socket._secondary) 164a7b4beaSMichał Górny 174a7b4beaSMichał Górny def setUp(self): 184a7b4beaSMichał Górny super().setUp() 194a7b4beaSMichał Górny self.orig_attr = self.get_term_attrs() 204a7b4beaSMichał Górny 214a7b4beaSMichał Górny def assert_raw_mode(self, current_attr): 224a7b4beaSMichał Górny import termios 234a7b4beaSMichał Górny self.assertEqual(current_attr[0] & (termios.BRKINT | 244a7b4beaSMichał Górny termios.PARMRK | 254a7b4beaSMichał Górny termios.ISTRIP | termios.INLCR | 264a7b4beaSMichał Górny termios.IGNCR | termios.ICRNL | 274a7b4beaSMichał Górny termios.IXON), 284a7b4beaSMichał Górny 0) 294a7b4beaSMichał Górny self.assertEqual(current_attr[1] & termios.OPOST, 0) 304a7b4beaSMichał Górny self.assertEqual(current_attr[2] & termios.CSIZE, termios.CS8) 314a7b4beaSMichał Górny self.assertEqual(current_attr[3] & (termios.ICANON | termios.ECHO | 324a7b4beaSMichał Górny termios.ISIG | termios.IEXTEN), 334a7b4beaSMichał Górny 0) 344a7b4beaSMichał Górny self.assertEqual(current_attr[6][termios.VMIN], 1) 354a7b4beaSMichał Górny self.assertEqual(current_attr[6][termios.VTIME], 0) 364a7b4beaSMichał Górny 374a7b4beaSMichał Górny def get_parity_flags(self, attr): 384a7b4beaSMichał Górny import termios 394a7b4beaSMichał Górny return attr[2] & (termios.PARENB | termios.PARODD) 404a7b4beaSMichał Górny 414a7b4beaSMichał Górny def get_stop_bit_flags(self, attr): 424a7b4beaSMichał Górny import termios 434a7b4beaSMichał Górny return attr[2] & termios.CSTOPB 444a7b4beaSMichał Górny 458fa2394bSMichał Górny def test_process_connect_sync(self): 468fa2394bSMichał Górny """Test the process connect command in synchronous mode""" 478fa2394bSMichał Górny try: 488fa2394bSMichał Górny self.dbg.SetAsync(False) 498fa2394bSMichał Górny self.expect("platform select remote-gdb-server", 508fa2394bSMichał Górny substrs=['Platform: remote-gdb-server', 'Connected: no']) 518fa2394bSMichał Górny self.expect("process connect " + self.server.get_connect_url(), 528fa2394bSMichał Górny substrs=['Process', 'stopped']) 534a7b4beaSMichał Górny 544a7b4beaSMichał Górny current_attr = self.get_term_attrs() 554a7b4beaSMichał Górny # serial:// should set raw mode 564a7b4beaSMichał Górny self.assert_raw_mode(current_attr) 574a7b4beaSMichał Górny # other parameters should be unmodified 584a7b4beaSMichał Górny self.assertEqual(current_attr[4:6], self.orig_attr[4:6]) 594a7b4beaSMichał Górny self.assertEqual(self.get_parity_flags(current_attr), 604a7b4beaSMichał Górny self.get_parity_flags(self.orig_attr)) 614a7b4beaSMichał Górny self.assertEqual(self.get_stop_bit_flags(current_attr), 624a7b4beaSMichał Górny self.get_stop_bit_flags(self.orig_attr)) 638fa2394bSMichał Górny finally: 6445f97950SMichał Górny self.dbg.GetSelectedTarget().GetProcess().Kill() 654a7b4beaSMichał Górny # original mode should be restored on exit 664a7b4beaSMichał Górny self.assertEqual(self.get_term_attrs(), self.orig_attr) 678fa2394bSMichał Górny 688fa2394bSMichał Górny def test_process_connect_async(self): 698fa2394bSMichał Górny """Test the process connect command in asynchronous mode""" 708fa2394bSMichał Górny try: 718fa2394bSMichał Górny self.dbg.SetAsync(True) 728fa2394bSMichał Górny self.expect("platform select remote-gdb-server", 738fa2394bSMichał Górny substrs=['Platform: remote-gdb-server', 'Connected: no']) 748fa2394bSMichał Górny self.expect("process connect " + self.server.get_connect_url(), 758fa2394bSMichał Górny matching=False, 768fa2394bSMichał Górny substrs=['Process', 'stopped']) 778fa2394bSMichał Górny lldbutil.expect_state_changes(self, self.dbg.GetListener(), 788fa2394bSMichał Górny self.process(), [lldb.eStateStopped]) 794a7b4beaSMichał Górny 804a7b4beaSMichał Górny current_attr = self.get_term_attrs() 814a7b4beaSMichał Górny # serial:// should set raw mode 824a7b4beaSMichał Górny self.assert_raw_mode(current_attr) 834a7b4beaSMichał Górny # other parameters should be unmodified 844a7b4beaSMichał Górny self.assertEqual(current_attr[4:6], self.orig_attr[4:6]) 854a7b4beaSMichał Górny self.assertEqual(self.get_parity_flags(current_attr), 864a7b4beaSMichał Górny self.get_parity_flags(self.orig_attr)) 874a7b4beaSMichał Górny self.assertEqual(self.get_stop_bit_flags(current_attr), 884a7b4beaSMichał Górny self.get_stop_bit_flags(self.orig_attr)) 898fa2394bSMichał Górny finally: 9045f97950SMichał Górny self.dbg.GetSelectedTarget().GetProcess().Kill() 9145f97950SMichał Górny lldbutil.expect_state_changes(self, self.dbg.GetListener(), 9245f97950SMichał Górny self.process(), [lldb.eStateExited]) 934a7b4beaSMichał Górny # original mode should be restored on exit 944a7b4beaSMichał Górny self.assertEqual(self.get_term_attrs(), self.orig_attr) 954a7b4beaSMichał Górny 964a7b4beaSMichał Górny def test_connect_via_file(self): 974a7b4beaSMichał Górny """Test connecting via the legacy file:// URL""" 984a7b4beaSMichał Górny import termios 994a7b4beaSMichał Górny try: 1004a7b4beaSMichał Górny self.expect("platform select remote-gdb-server", 1014a7b4beaSMichał Górny substrs=['Platform: remote-gdb-server', 'Connected: no']) 1024a7b4beaSMichał Górny self.expect("process connect file://" + 1034a7b4beaSMichał Górny self.server.get_connect_address(), 1044a7b4beaSMichał Górny substrs=['Process', 'stopped']) 1054a7b4beaSMichał Górny 1064a7b4beaSMichał Górny # file:// sets baud rate and some raw-related flags 1074a7b4beaSMichał Górny current_attr = self.get_term_attrs() 1084a7b4beaSMichał Górny self.assertEqual(current_attr[3] & (termios.ICANON | termios.ECHO | 1094a7b4beaSMichał Górny termios.ECHOE | termios.ISIG), 1104a7b4beaSMichał Górny 0) 1114a7b4beaSMichał Górny self.assertEqual(current_attr[4], termios.B115200) 1124a7b4beaSMichał Górny self.assertEqual(current_attr[5], termios.B115200) 1134a7b4beaSMichał Górny self.assertEqual(current_attr[6][termios.VMIN], 1) 1144a7b4beaSMichał Górny self.assertEqual(current_attr[6][termios.VTIME], 0) 1154a7b4beaSMichał Górny finally: 1164a7b4beaSMichał Górny self.dbg.GetSelectedTarget().GetProcess().Kill() 1174a7b4beaSMichał Górny 1184a7b4beaSMichał Górny def test_process_connect_params(self): 1194a7b4beaSMichał Górny """Test serial:// URL with parameters""" 1204a7b4beaSMichał Górny import termios 1214a7b4beaSMichał Górny try: 1224a7b4beaSMichał Górny self.expect("platform select remote-gdb-server", 1234a7b4beaSMichał Górny substrs=['Platform: remote-gdb-server', 'Connected: no']) 1244a7b4beaSMichał Górny self.expect("process connect " + self.server.get_connect_url() + 1254a7b4beaSMichał Górny "?baud=115200&stop-bits=2", 1264a7b4beaSMichał Górny substrs=['Process', 'stopped']) 1274a7b4beaSMichał Górny 1284a7b4beaSMichał Górny current_attr = self.get_term_attrs() 1294a7b4beaSMichał Górny self.assert_raw_mode(current_attr) 1304a7b4beaSMichał Górny self.assertEqual(current_attr[4:6], 2 * [termios.B115200]) 1314a7b4beaSMichał Górny self.assertEqual(self.get_parity_flags(current_attr), 1324a7b4beaSMichał Górny self.get_parity_flags(self.orig_attr)) 1334a7b4beaSMichał Górny self.assertEqual(self.get_stop_bit_flags(current_attr), 1344a7b4beaSMichał Górny termios.CSTOPB) 1354a7b4beaSMichał Górny finally: 1364a7b4beaSMichał Górny self.dbg.GetSelectedTarget().GetProcess().Kill() 1374a7b4beaSMichał Górny # original mode should be restored on exit 1384a7b4beaSMichał Górny self.assertEqual(self.get_term_attrs(), self.orig_attr) 139