blob: 46f4ae728413f34e061e48abd149f1ee130157ef [file] [log] [blame]
//! Tests for the `posix::TTYPort` struct.
#![cfg(unix)]
extern crate serialport;
use std::io::{Read, Write};
use std::os::unix::prelude::*;
use std::str;
use std::time::Duration;
use serialport::{SerialPort, TTYPort};
#[test]
fn test_ttyport_pair() {
// FIXME: Create a mutex across all tests for using `TTYPort::pair()` as it's not threadsafe
let (mut master, mut slave) = TTYPort::pair().expect("Unable to create ptty pair");
master
.set_timeout(Duration::from_millis(10))
.expect("Unable to set timeout on the master");
slave
.set_timeout(Duration::from_millis(10))
.expect("Unable to set timeout on the slave");
// Test file descriptors.
assert!(
master.as_raw_fd() > 0,
"Invalid file descriptor on master ptty"
);
assert!(
slave.as_raw_fd() > 0,
"Invalid file descriptor on slae ptty"
);
assert_ne!(
master.as_raw_fd(),
slave.as_raw_fd(),
"master and slave ptty's share the same file descriptor."
);
let msg = "Test Message";
let mut buf = [0u8; 128];
// Write the string on the master
let nbytes = master
.write(msg.as_bytes())
.expect("Unable to write bytes.");
assert_eq!(
nbytes,
msg.len(),
"Write message length differs from sent message."
);
// Read it on the slave
let nbytes = slave.read(&mut buf).expect("Unable to read bytes.");
assert_eq!(
nbytes,
msg.len(),
"Read message length differs from sent message."
);
assert_eq!(
str::from_utf8(&buf[..nbytes]).unwrap(),
msg,
"Received message does not match sent"
);
}
#[test]
fn test_ttyport_timeout() {
let result = std::sync::Arc::new(std::sync::Mutex::new(None));
let result_thread = result.clone();
std::thread::spawn(move || {
// FIXME: Create a mutex across all tests for using `TTYPort::pair()` as it's not threadsafe
let (mut master, _slave) = TTYPort::pair().expect("Unable to create ptty pair");
master.set_timeout(Duration::new(1, 0)).unwrap();
let mut buffer = [0u8];
let read_res = master.read(&mut buffer);
*result_thread.lock().unwrap() = Some(read_res);
});
std::thread::sleep(std::time::Duration::new(2, 0));
let read_res = result.lock().unwrap();
match *read_res {
Some(Ok(_)) => panic!("Received data without sending"),
Some(Err(ref e)) => assert_eq!(e.kind(), std::io::ErrorKind::TimedOut),
None => panic!("Read did not time out"),
}
}
#[test]
#[cfg(any(target_os = "ios", target_os = "macos"))]
fn test_osx_pty_pair() {
#![allow(unused_variables)]
let (mut master, slave) = TTYPort::pair().expect("Unable to create ptty pair");
let (output_sink, output_stream) = std::sync::mpsc::sync_channel(1);
let name = slave.name().unwrap();
master.write_all("12".as_bytes()).expect("");
let reader_thread = std::thread::spawn(move || {
let mut port = TTYPort::open(&serialport::new(&name, 0)).expect("unable to open");
let mut buffer = [0u8; 2];
let amount = port.read_exact(&mut buffer);
output_sink
.send(String::from_utf8(buffer.to_vec()).expect("buffer not read as valid utf-8"))
.expect("unable to send from thread");
});
reader_thread.join().expect("unable to join sink thread");
assert_eq!(output_stream.recv().unwrap(), "12");
}
// On Mac this should work (in fact used to in b77768a) but now fails. It's not functionality that
// should be required, and the ptys work otherwise. So going to just disable this test instead.
#[test]
#[cfg_attr(any(target_os = "ios", target_os = "macos"), ignore)]
fn test_ttyport_set_standard_baud() {
// `master` must be used here as Dropping it causes slave to be deleted by the OS.
// TODO: Convert this to a statement-level attribute once
// https://github.com/rust-lang/rust/issues/15701 is on stable.
// FIXME: Create a mutex across all tests for using `TTYPort::pair()` as it's not threadsafe
#![allow(unused_variables)]
let (master, mut slave) = TTYPort::pair().expect("Unable to create ptty pair");
slave.set_baud_rate(9600).unwrap();
assert_eq!(slave.baud_rate().unwrap(), 9600);
slave.set_baud_rate(57600).unwrap();
assert_eq!(slave.baud_rate().unwrap(), 57600);
slave.set_baud_rate(115_200).unwrap();
assert_eq!(slave.baud_rate().unwrap(), 115_200);
}
// On mac this fails because you can't set nonstandard baud rates for these virtual ports
#[test]
#[cfg_attr(
any(
target_os = "ios",
all(target_os = "linux", target_env = "musl"),
target_os = "macos"
),
ignore
)]
fn test_ttyport_set_nonstandard_baud() {
// `master` must be used here as Dropping it causes slave to be deleted by the OS.
// TODO: Convert this to a statement-level attribute once
// https://github.com/rust-lang/rust/issues/15701 is on stable.
// FIXME: Create a mutex across all tests for using `TTYPort::pair()` as it's not threadsafe
#![allow(unused_variables)]
let (master, mut slave) = TTYPort::pair().expect("Unable to create ptty pair");
slave.set_baud_rate(10000).unwrap();
assert_eq!(slave.baud_rate().unwrap(), 10000);
slave.set_baud_rate(60000).unwrap();
assert_eq!(slave.baud_rate().unwrap(), 60000);
slave.set_baud_rate(1_200_000).unwrap();
assert_eq!(slave.baud_rate().unwrap(), 1_200_000);
}