mod common;
use mio::{Interest, Token};
use mio_serial::SerialPortBuilderExt;
use std::io::{Read, Write};
const TOKEN1: Token = Token(0);
const TOKEN2: Token = Token(1);
#[test]
fn test_builder_open_async() {
let fixture = common::setup_virtual_serial_ports();
let baud_rate = 9600;
let builder = mio_serial::new(&*fixture.port_a, baud_rate);
let stream = builder
.open_native_async()
.expect("unable to open serial port");
common::assert_baud_rate(&stream, baud_rate);
}
#[test]
fn test_native_from_blocking() {
use std::convert::TryFrom;
let baud_rate = 9600;
let fixture = common::setup_virtual_serial_ports();
let port = &*fixture.port_a;
let native_blocking = mio_serial::new(port, baud_rate)
.open_native()
.unwrap_or_else(|e| panic!("unable to open serial port {port}: {e}"));
let stream = mio_serial::SerialStream::try_from(native_blocking)
.expect("unable to convert from blocking serial port object");
common::assert_baud_rate(&stream, baud_rate);
}
#[test]
fn test_stream_open() {
let baud_rate = 9600;
let fixture = common::setup_virtual_serial_ports();
let port = &*fixture.port_a;
let builder = mio_serial::new(port, baud_rate);
let stream = mio_serial::SerialStream::open(&builder).expect("unable to open serial port");
common::assert_baud_rate(&stream, baud_rate);
}
#[test]
#[ignore = "Port enumeration test does not seem to work with com0com virtual ports"]
fn test_port_enumeration() {
let fixture = common::setup_virtual_serial_ports();
let ports = mio_serial::available_ports().expect("unable to enumerate serial ports");
for name in [&*fixture.port_a, &*fixture.port_b] {
ports
.iter()
.find(|&info| info.port_name == *name)
.unwrap_or_else(|| {
panic!("unable to find serial port named {name} in enumerated ports")
});
}
}
#[test]
fn test_read_write_pair() {
const DATA1: &[u8] = b"Here is an example string";
const DATA2: &[u8] = b"And here is a reply to the example string";
const DEFAULT_BUF_SIZE: usize = 64;
let baud_rate = 38400;
let fixture = common::setup_virtual_serial_ports();
let (port_a, port_b) = (&*fixture.port_a, &*fixture.port_b);
let (mut poll, mut events) = common::init_with_poll();
let mut port_1 = mio_serial::new(port_a, baud_rate)
.open_native_async()
.unwrap_or_else(|e| panic!("unable to open serial port {port_a}: {e}"));
let mut port_2 = mio_serial::new(port_b, baud_rate)
.open_native_async()
.unwrap_or_else(|e| panic!("unable to open serial port {port_b}: {e}"));
poll.registry()
.register(&mut port_1, TOKEN1, Interest::WRITABLE | Interest::READABLE)
.unwrap_or_else(|e| {
panic!("unable to register port {port_a} as readable and writable: {e}")
});
poll.registry()
.register(&mut port_2, TOKEN2, Interest::READABLE | Interest::WRITABLE)
.unwrap_or_else(|e| {
panic!("unable to register port {port_b} as readable and writable: {e}")
});
let mut buf = [0u8; DEFAULT_BUF_SIZE];
common::expect_events(
&mut poll,
&mut events,
vec![common::ExpectEvent::new(TOKEN1, Interest::WRITABLE)],
);
common::assert_would_block(port_2.read(&mut buf));
common::checked_write(&mut port_1, DATA1);
port_1
.flush()
.unwrap_or_else(|e| panic!("unable to flush serial port {port_a}: {e}"));
common::expect_events(
&mut poll,
&mut events,
vec![common::ExpectEvent::new(TOKEN2, Interest::READABLE)],
);
common::checked_read(&mut port_2, &mut buf, DATA1);
common::assert_would_block(port_2.read(&mut buf));
common::assert_would_block(port_1.read(&mut buf));
common::checked_write(&mut port_2, DATA2);
port_2
.flush()
.unwrap_or_else(|e| panic!("unable to flush serial port {port_b}: {e}"));
common::expect_events(
&mut poll,
&mut events,
vec![common::ExpectEvent::new(TOKEN1, Interest::READABLE)],
);
common::checked_read(&mut port_1, &mut buf, DATA2);
common::assert_would_block(port_1.read(&mut buf));
}
#[cfg(any())]
#[test]
fn test_try_clone_native() {
const DATA1: &[u8] = b"Here is an example string";
const DEFAULT_BUF_SIZE: usize = 64;
let baud_rate = 9600;
let fixture = common::setup_virtual_serial_ports();
let (mut poll, mut events) = common::init_with_poll();
let builder_a = mio_serial::new(fixture.port_a, baud_rate);
let builder_b = mio_serial::new(fixture.port_b, baud_rate);
let mut sender =
mio_serial::SerialStream::open(&builder_a).expect("unable to open serial port");
let mut receiver =
mio_serial::SerialStream::open(&builder_b).expect("unable to open serial port");
poll.registry()
.register(&mut sender, TOKEN1, Interest::WRITABLE | Interest::READABLE)
.expect("unable to register port as readable and writable");
poll.registry()
.register(
&mut receiver,
TOKEN2,
Interest::READABLE | Interest::WRITABLE,
)
.expect("unable to register port as readable and writable");
let mut cloned_receiver = receiver
.try_clone_native()
.expect("unable to clone serial port");
std::mem::drop(receiver);
let mut buf = [0u8; DEFAULT_BUF_SIZE];
common::expect_events(
&mut poll,
&mut events,
vec![common::ExpectEvent::new(TOKEN1, Interest::WRITABLE)],
);
common::assert_would_block(cloned_receiver.read(&mut buf).into());
common::checked_write(&mut sender, DATA1);
sender.flush().expect("unable to flush serial port");
common::expect_events(
&mut poll,
&mut events,
vec![common::ExpectEvent::new(TOKEN2, Interest::READABLE)],
);
common::checked_read(&mut cloned_receiver, &mut buf, DATA1);
common::assert_would_block(cloned_receiver.read(&mut buf));
common::assert_would_block(sender.read(&mut buf));
common::checked_write(&mut sender, DATA1);
sender.flush().expect("unable to flush serial port");
common::expect_events(
&mut poll,
&mut events,
vec![common::ExpectEvent::new(TOKEN2, Interest::READABLE)],
);
common::checked_read(&mut cloned_receiver, &mut buf, DATA1);
common::assert_would_block(cloned_receiver.read(&mut buf));
common::assert_would_block(sender.read(&mut buf));
}