1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
//! 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_arch="powerpc",
target_arch="powerpc64",
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);
}
|