• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Tests for the `posix::TTYPort` struct.
2 #![cfg(unix)]
3 
4 extern crate serialport;
5 
6 use std::io::{Read, Write};
7 use std::os::unix::prelude::*;
8 use std::str;
9 use std::time::Duration;
10 
11 use serialport::{SerialPort, TTYPort};
12 
13 #[test]
test_ttyport_pair()14 fn test_ttyport_pair() {
15     // FIXME: Create a mutex across all tests for using `TTYPort::pair()` as it's not threadsafe
16     let (mut master, mut slave) = TTYPort::pair().expect("Unable to create ptty pair");
17     master
18         .set_timeout(Duration::from_millis(10))
19         .expect("Unable to set timeout on the master");
20     slave
21         .set_timeout(Duration::from_millis(10))
22         .expect("Unable to set timeout on the slave");
23 
24     // Test file descriptors.
25     assert!(
26         master.as_raw_fd() > 0,
27         "Invalid file descriptor on master ptty"
28     );
29     assert!(
30         slave.as_raw_fd() > 0,
31         "Invalid file descriptor on slae ptty"
32     );
33     assert_ne!(
34         master.as_raw_fd(),
35         slave.as_raw_fd(),
36         "master and slave ptty's share the same file descriptor."
37     );
38 
39     let msg = "Test Message";
40     let mut buf = [0u8; 128];
41 
42     // Write the string on the master
43     let nbytes = master
44         .write(msg.as_bytes())
45         .expect("Unable to write bytes.");
46     assert_eq!(
47         nbytes,
48         msg.len(),
49         "Write message length differs from sent message."
50     );
51 
52     // Read it on the slave
53     let nbytes = slave.read(&mut buf).expect("Unable to read bytes.");
54     assert_eq!(
55         nbytes,
56         msg.len(),
57         "Read message length differs from sent message."
58     );
59 
60     assert_eq!(
61         str::from_utf8(&buf[..nbytes]).unwrap(),
62         msg,
63         "Received message does not match sent"
64     );
65 }
66 
67 #[test]
test_ttyport_timeout()68 fn test_ttyport_timeout() {
69     let result = std::sync::Arc::new(std::sync::Mutex::new(None));
70     let result_thread = result.clone();
71 
72     std::thread::spawn(move || {
73         // FIXME: Create a mutex across all tests for using `TTYPort::pair()` as it's not threadsafe
74         let (mut master, _slave) = TTYPort::pair().expect("Unable to create ptty pair");
75         master.set_timeout(Duration::new(1, 0)).unwrap();
76 
77         let mut buffer = [0u8];
78         let read_res = master.read(&mut buffer);
79 
80         *result_thread.lock().unwrap() = Some(read_res);
81     });
82 
83     std::thread::sleep(std::time::Duration::new(2, 0));
84 
85     let read_res = result.lock().unwrap();
86     match *read_res {
87         Some(Ok(_)) => panic!("Received data without sending"),
88         Some(Err(ref e)) => assert_eq!(e.kind(), std::io::ErrorKind::TimedOut),
89         None => panic!("Read did not time out"),
90     }
91 }
92 
93 #[test]
94 #[cfg(any(target_os = "ios", target_os = "macos"))]
test_osx_pty_pair()95 fn test_osx_pty_pair() {
96     #![allow(unused_variables)]
97     let (mut master, slave) = TTYPort::pair().expect("Unable to create ptty pair");
98     let (output_sink, output_stream) = std::sync::mpsc::sync_channel(1);
99     let name = slave.name().unwrap();
100 
101     master.write_all("12".as_bytes()).expect("");
102 
103     let reader_thread = std::thread::spawn(move || {
104         let mut port = TTYPort::open(&serialport::new(&name, 0)).expect("unable to open");
105         let mut buffer = [0u8; 2];
106         let amount = port.read_exact(&mut buffer);
107         output_sink
108             .send(String::from_utf8(buffer.to_vec()).expect("buffer not read as valid utf-8"))
109             .expect("unable to send from thread");
110     });
111 
112     reader_thread.join().expect("unable to join sink thread");
113     assert_eq!(output_stream.recv().unwrap(), "12");
114 }
115 
116 // On Mac this should work (in fact used to in b77768a) but now fails. It's not functionality that
117 // should be required, and the ptys work otherwise. So going to just disable this test instead.
118 #[test]
119 #[cfg_attr(any(target_os = "ios", target_os = "macos"), ignore)]
test_ttyport_set_standard_baud()120 fn test_ttyport_set_standard_baud() {
121     // `master` must be used here as Dropping it causes slave to be deleted by the OS.
122     // TODO: Convert this to a statement-level attribute once
123     //       https://github.com/rust-lang/rust/issues/15701 is on stable.
124     // FIXME: Create a mutex across all tests for using `TTYPort::pair()` as it's not threadsafe
125     #![allow(unused_variables)]
126     let (master, mut slave) = TTYPort::pair().expect("Unable to create ptty pair");
127 
128     slave.set_baud_rate(9600).unwrap();
129     assert_eq!(slave.baud_rate().unwrap(), 9600);
130     slave.set_baud_rate(57600).unwrap();
131     assert_eq!(slave.baud_rate().unwrap(), 57600);
132     slave.set_baud_rate(115_200).unwrap();
133     assert_eq!(slave.baud_rate().unwrap(), 115_200);
134 }
135 
136 // On mac this fails because you can't set nonstandard baud rates for these virtual ports
137 #[test]
138 #[cfg_attr(
139     any(
140         target_os = "ios",
141         all(target_os = "linux", target_env = "musl"),
142         target_os = "macos"
143     ),
144     ignore
145 )]
test_ttyport_set_nonstandard_baud()146 fn test_ttyport_set_nonstandard_baud() {
147     // `master` must be used here as Dropping it causes slave to be deleted by the OS.
148     // TODO: Convert this to a statement-level attribute once
149     //       https://github.com/rust-lang/rust/issues/15701 is on stable.
150     // FIXME: Create a mutex across all tests for using `TTYPort::pair()` as it's not threadsafe
151     #![allow(unused_variables)]
152     let (master, mut slave) = TTYPort::pair().expect("Unable to create ptty pair");
153 
154     slave.set_baud_rate(10000).unwrap();
155     assert_eq!(slave.baud_rate().unwrap(), 10000);
156     slave.set_baud_rate(60000).unwrap();
157     assert_eq!(slave.baud_rate().unwrap(), 60000);
158     slave.set_baud_rate(1_200_000).unwrap();
159     assert_eq!(slave.baud_rate().unwrap(), 1_200_000);
160 }
161