Add a new serial:// protocol along with SerialPort that provides a new
API to open serial ports. The URL consists of serial device path
followed by URL-style options, e.g.:
serial:///dev/ttyS0?baud=115200&parity=even
If no options are provided, the serial port is only set to raw mode
and the other attributes remain unchanged. Attributes provided via
options are modified to the specified values. Upon closing the serial
port, its original attributes are restored.
Differential Revision: https://reviews.llvm.org/D111355
138 lines
6.2 KiB
Python
138 lines
6.2 KiB
Python
import lldb
|
|
from lldbsuite.test.lldbtest import *
|
|
from lldbsuite.test.decorators import *
|
|
from gdbclientutils import *
|
|
|
|
|
|
@skipIfWindows
|
|
class TestPty(GDBRemoteTestBase):
|
|
mydir = TestBase.compute_mydir(__file__)
|
|
server_socket_class = PtyServerSocket
|
|
|
|
def get_term_attrs(self):
|
|
import termios
|
|
return termios.tcgetattr(self.server._socket._slave)
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.orig_attr = self.get_term_attrs()
|
|
|
|
def assert_raw_mode(self, current_attr):
|
|
import termios
|
|
self.assertEqual(current_attr[0] & (termios.BRKINT |
|
|
termios.PARMRK |
|
|
termios.ISTRIP | termios.INLCR |
|
|
termios.IGNCR | termios.ICRNL |
|
|
termios.IXON),
|
|
0)
|
|
self.assertEqual(current_attr[1] & termios.OPOST, 0)
|
|
self.assertEqual(current_attr[2] & termios.CSIZE, termios.CS8)
|
|
self.assertEqual(current_attr[3] & (termios.ICANON | termios.ECHO |
|
|
termios.ISIG | termios.IEXTEN),
|
|
0)
|
|
self.assertEqual(current_attr[6][termios.VMIN], 1)
|
|
self.assertEqual(current_attr[6][termios.VTIME], 0)
|
|
|
|
def get_parity_flags(self, attr):
|
|
import termios
|
|
return attr[2] & (termios.PARENB | termios.PARODD)
|
|
|
|
def get_stop_bit_flags(self, attr):
|
|
import termios
|
|
return attr[2] & termios.CSTOPB
|
|
|
|
def test_process_connect_sync(self):
|
|
"""Test the process connect command in synchronous mode"""
|
|
try:
|
|
self.dbg.SetAsync(False)
|
|
self.expect("platform select remote-gdb-server",
|
|
substrs=['Platform: remote-gdb-server', 'Connected: no'])
|
|
self.expect("process connect " + self.server.get_connect_url(),
|
|
substrs=['Process', 'stopped'])
|
|
|
|
current_attr = self.get_term_attrs()
|
|
# serial:// should set raw mode
|
|
self.assert_raw_mode(current_attr)
|
|
# other parameters should be unmodified
|
|
self.assertEqual(current_attr[4:6], self.orig_attr[4:6])
|
|
self.assertEqual(self.get_parity_flags(current_attr),
|
|
self.get_parity_flags(self.orig_attr))
|
|
self.assertEqual(self.get_stop_bit_flags(current_attr),
|
|
self.get_stop_bit_flags(self.orig_attr))
|
|
finally:
|
|
self.dbg.GetSelectedTarget().GetProcess().Kill()
|
|
# original mode should be restored on exit
|
|
self.assertEqual(self.get_term_attrs(), self.orig_attr)
|
|
|
|
def test_process_connect_async(self):
|
|
"""Test the process connect command in asynchronous mode"""
|
|
try:
|
|
self.dbg.SetAsync(True)
|
|
self.expect("platform select remote-gdb-server",
|
|
substrs=['Platform: remote-gdb-server', 'Connected: no'])
|
|
self.expect("process connect " + self.server.get_connect_url(),
|
|
matching=False,
|
|
substrs=['Process', 'stopped'])
|
|
lldbutil.expect_state_changes(self, self.dbg.GetListener(),
|
|
self.process(), [lldb.eStateStopped])
|
|
|
|
current_attr = self.get_term_attrs()
|
|
# serial:// should set raw mode
|
|
self.assert_raw_mode(current_attr)
|
|
# other parameters should be unmodified
|
|
self.assertEqual(current_attr[4:6], self.orig_attr[4:6])
|
|
self.assertEqual(self.get_parity_flags(current_attr),
|
|
self.get_parity_flags(self.orig_attr))
|
|
self.assertEqual(self.get_stop_bit_flags(current_attr),
|
|
self.get_stop_bit_flags(self.orig_attr))
|
|
finally:
|
|
self.dbg.GetSelectedTarget().GetProcess().Kill()
|
|
lldbutil.expect_state_changes(self, self.dbg.GetListener(),
|
|
self.process(), [lldb.eStateExited])
|
|
# original mode should be restored on exit
|
|
self.assertEqual(self.get_term_attrs(), self.orig_attr)
|
|
|
|
def test_connect_via_file(self):
|
|
"""Test connecting via the legacy file:// URL"""
|
|
import termios
|
|
try:
|
|
self.expect("platform select remote-gdb-server",
|
|
substrs=['Platform: remote-gdb-server', 'Connected: no'])
|
|
self.expect("process connect file://" +
|
|
self.server.get_connect_address(),
|
|
substrs=['Process', 'stopped'])
|
|
|
|
# file:// sets baud rate and some raw-related flags
|
|
current_attr = self.get_term_attrs()
|
|
self.assertEqual(current_attr[3] & (termios.ICANON | termios.ECHO |
|
|
termios.ECHOE | termios.ISIG),
|
|
0)
|
|
self.assertEqual(current_attr[4], termios.B115200)
|
|
self.assertEqual(current_attr[5], termios.B115200)
|
|
self.assertEqual(current_attr[6][termios.VMIN], 1)
|
|
self.assertEqual(current_attr[6][termios.VTIME], 0)
|
|
finally:
|
|
self.dbg.GetSelectedTarget().GetProcess().Kill()
|
|
|
|
def test_process_connect_params(self):
|
|
"""Test serial:// URL with parameters"""
|
|
import termios
|
|
try:
|
|
self.expect("platform select remote-gdb-server",
|
|
substrs=['Platform: remote-gdb-server', 'Connected: no'])
|
|
self.expect("process connect " + self.server.get_connect_url() +
|
|
"?baud=115200&stop-bits=2",
|
|
substrs=['Process', 'stopped'])
|
|
|
|
current_attr = self.get_term_attrs()
|
|
self.assert_raw_mode(current_attr)
|
|
self.assertEqual(current_attr[4:6], 2 * [termios.B115200])
|
|
self.assertEqual(self.get_parity_flags(current_attr),
|
|
self.get_parity_flags(self.orig_attr))
|
|
self.assertEqual(self.get_stop_bit_flags(current_attr),
|
|
termios.CSTOPB)
|
|
finally:
|
|
self.dbg.GetSelectedTarget().GetProcess().Kill()
|
|
# original mode should be restored on exit
|
|
self.assertEqual(self.get_term_attrs(), self.orig_attr)
|