1 mod config;
2
3 use config::{hw_config, HardwareConfig};
4 use rstest::rstest;
5 use serialport::*;
6 use std::io::Read;
7 use std::thread;
8 use std::time::{Duration, Instant};
9
10 #[rstest]
11 #[case(1, Vec::from(b"abcdef"))]
12 #[case(
13 20,
14 Vec::from(b"0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")
15 )]
16 #[cfg_attr(feature = "ignore-hardware-tests", ignore)]
test_read_returns_available_data_before_timeout( hw_config: HardwareConfig, #[case] chunk_size: usize, #[case] message: Vec<u8>, )17 fn test_read_returns_available_data_before_timeout(
18 hw_config: HardwareConfig,
19 #[case] chunk_size: usize,
20 #[case] message: Vec<u8>,
21 ) {
22 let send_period = Duration::from_millis(500);
23 let receive_timeout = Duration::from_millis(3000);
24 let marign = Duration::from_millis(100);
25
26 let mut sender = serialport::new(hw_config.port_1, 115200).open().unwrap();
27 let mut receiver = serialport::new(hw_config.port_2, 115200)
28 .timeout(receive_timeout)
29 .open()
30 .unwrap();
31
32 sender.clear(ClearBuffer::All).unwrap();
33 receiver.clear(ClearBuffer::All).unwrap();
34
35 let expected_message = message.clone();
36 let receiver_thread = thread::spawn(move || {
37 let chunk_timeout = send_period + marign;
38 assert!(receiver.timeout() > 3 * chunk_timeout);
39
40 let mut received_message = Vec::with_capacity(expected_message.len());
41
42 loop {
43 let chunk_start = Instant::now();
44 let expected_chunk_until = chunk_start + chunk_timeout;
45
46 let mut buffer = [0u8; 1024];
47 assert!(buffer.len() > expected_message.len());
48
49 // Try to read more data than we are expecting and expect some data to be available
50 // after the send period (plus some margin).
51 match receiver.read(&mut buffer) {
52 Ok(read) => {
53 assert!(expected_chunk_until > Instant::now());
54 assert!(read > 0);
55 println!(
56 "receive: {} bytes after waiting {} ms",
57 read,
58 (Instant::now() - chunk_start).as_millis()
59 );
60 received_message.extend_from_slice(&buffer[..read]);
61 }
62 e => panic!("unexpected error {:?}", e),
63 }
64
65 if received_message.len() >= expected_message.len() {
66 break;
67 }
68 }
69
70 assert_eq!(expected_message, received_message);
71 });
72
73 let sender_thread = thread::spawn(move || {
74 let mut next = Instant::now();
75
76 for chunk in message.chunks(chunk_size) {
77 sender.write_all(chunk).unwrap();
78 sender.flush().unwrap();
79
80 println!("send: {} bytes", chunk.len());
81
82 next += send_period;
83 thread::sleep(next - Instant::now());
84 }
85 });
86
87 sender_thread.join().unwrap();
88 receiver_thread.join().unwrap();
89 }
90
91 #[rstest]
92 #[case(b"a")]
93 #[case(b"0123456789")]
94 #[case(b"0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")]
95 #[cfg_attr(feature = "ignore-hardware-tests", ignore)]
test_timeout_zero(hw_config: HardwareConfig, #[case] message: &[u8])96 fn test_timeout_zero(hw_config: HardwareConfig, #[case] message: &[u8]) {
97 let timeout = Duration::ZERO;
98 let margin = Duration::from_millis(100);
99
100 let mut sender = serialport::new(hw_config.port_1, 115200).open().unwrap();
101 let mut receiver = serialport::new(hw_config.port_2, 115200)
102 .timeout(timeout)
103 .open()
104 .unwrap();
105 let mut buffer: [u8; 1024] = [0xff; 1024];
106
107 sender.clear(ClearBuffer::All).unwrap();
108 receiver.clear(ClearBuffer::All).unwrap();
109
110 sender.write_all(message).unwrap();
111 sender.flush().unwrap();
112 let flushed_at = Instant::now();
113
114 let expected_until = flushed_at + timeout + margin;
115 let mut timeouts = 0usize;
116
117 loop {
118 match receiver.read(&mut buffer) {
119 Ok(read) => {
120 assert!(read > 0);
121 println!(
122 "read: {} bytes of {} after {} timeouts/{} ms",
123 read,
124 message.len(),
125 timeouts,
126 (Instant::now() - flushed_at).as_millis()
127 );
128 assert_eq!(message[..read], buffer[..read]);
129 break;
130 }
131 Err(e) => {
132 assert_eq!(e.kind(), std::io::ErrorKind::TimedOut);
133 timeouts += 1;
134 }
135 }
136
137 assert!(expected_until > Instant::now());
138 }
139 }
140
141 #[rstest]
142 #[case(Duration::from_millis(10))]
143 #[case(Duration::from_millis(100))]
144 #[case(Duration::from_millis(1000))]
145 #[cfg_attr(feature = "ignore-hardware-tests", ignore)]
test_timeout_greater_zero(hw_config: HardwareConfig, #[case] timeout: Duration)146 fn test_timeout_greater_zero(hw_config: HardwareConfig, #[case] timeout: Duration) {
147 let margin = Duration::from_millis(100);
148
149 let mut sender = serialport::new(hw_config.port_1, 115200).open().unwrap();
150 let mut receiver = serialport::new(hw_config.port_2, 115200)
151 .timeout(timeout)
152 .open()
153 .unwrap();
154
155 let message =
156 b"0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
157 let mut buffer: [u8; 1024] = [0xff; 1024];
158
159 sender.clear(ClearBuffer::All).unwrap();
160 receiver.clear(ClearBuffer::All).unwrap();
161
162 sender.write_all(message).unwrap();
163 sender.flush().unwrap();
164
165 let flushed_at = Instant::now();
166
167 let read = receiver.read(&mut buffer).unwrap();
168 let read_at = Instant::now();
169
170 println!(
171 "read: {} bytes of {} after {} ms",
172 read,
173 message.len(),
174 (Instant::now() - flushed_at).as_millis()
175 );
176
177 assert!(read > 0);
178 assert!(flushed_at + timeout + margin > read_at);
179 assert_eq!(buffer[..read], message[..read]);
180 }
181
182 /// Checks that reading data with a timeout of `Duration::MAX` returns some data and no error. It
183 /// does not check the actual timeout for obvious reason.
184 #[rstest]
185 #[cfg_attr(feature = "ignore-hardware-tests", ignore)]
test_timeout_max(hw_config: HardwareConfig)186 fn test_timeout_max(hw_config: HardwareConfig) {
187 let sleep = Duration::from_millis(3000);
188 let margin = Duration::from_millis(500);
189 let mut sender = serialport::new(hw_config.port_1, 115200).open().unwrap();
190 let mut receiver = serialport::new(hw_config.port_2, 115200)
191 .timeout(Duration::MAX)
192 .open()
193 .unwrap();
194
195 let message =
196 b"0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
197 let mut buffer: [u8; 1024] = [0xff; 1024];
198
199 sender.clear(ClearBuffer::All).unwrap();
200 receiver.clear(ClearBuffer::All).unwrap();
201
202 let started_at = Instant::now();
203
204 let sender_thread = thread::spawn(move || {
205 thread::sleep(sleep);
206
207 sender.write_all(message).unwrap();
208 sender.flush().unwrap();
209 });
210
211 let read = receiver.read(&mut buffer).unwrap();
212 let read_at = Instant::now();
213
214 println!(
215 "read: {} bytes of {} after {} ms",
216 read,
217 message.len(),
218 (Instant::now() - started_at).as_millis()
219 );
220
221 assert!(read > 0);
222 assert!(read_at > started_at + sleep);
223 assert!(read_at < started_at + sleep + margin);
224 assert_eq!(buffer[..read], message[..read]);
225
226 sender_thread.join().unwrap();
227 }
228