]> git.lizzy.rs Git - rust.git/blob - library/std/src/net/udp/tests.rs
Rollup merge of #107074 - lcnr:validate-dont-skip-opaque, r=compiler-errors
[rust.git] / library / std / src / net / udp / tests.rs
1 use crate::io::ErrorKind;
2 use crate::net::test::{next_test_ip4, next_test_ip6};
3 use crate::net::*;
4 use crate::sync::mpsc::channel;
5 use crate::thread;
6 use crate::time::{Duration, Instant};
7
8 fn each_ip(f: &mut dyn FnMut(SocketAddr, SocketAddr)) {
9     f(next_test_ip4(), next_test_ip4());
10     f(next_test_ip6(), next_test_ip6());
11 }
12
13 macro_rules! t {
14     ($e:expr) => {
15         match $e {
16             Ok(t) => t,
17             Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
18         }
19     };
20 }
21
22 #[test]
23 fn bind_error() {
24     match UdpSocket::bind("1.1.1.1:9999") {
25         Ok(..) => panic!(),
26         Err(e) => assert_eq!(e.kind(), ErrorKind::AddrNotAvailable),
27     }
28 }
29
30 #[test]
31 fn socket_smoke_test_ip4() {
32     each_ip(&mut |server_ip, client_ip| {
33         let (tx1, rx1) = channel();
34         let (tx2, rx2) = channel();
35
36         let _t = thread::spawn(move || {
37             let client = t!(UdpSocket::bind(&client_ip));
38             rx1.recv().unwrap();
39             t!(client.send_to(&[99], &server_ip));
40             tx2.send(()).unwrap();
41         });
42
43         let server = t!(UdpSocket::bind(&server_ip));
44         tx1.send(()).unwrap();
45         let mut buf = [0];
46         let (nread, src) = t!(server.recv_from(&mut buf));
47         assert_eq!(nread, 1);
48         assert_eq!(buf[0], 99);
49         assert_eq!(src, client_ip);
50         rx2.recv().unwrap();
51     })
52 }
53
54 #[test]
55 fn socket_name() {
56     each_ip(&mut |addr, _| {
57         let server = t!(UdpSocket::bind(&addr));
58         assert_eq!(addr, t!(server.local_addr()));
59     })
60 }
61
62 #[test]
63 fn socket_peer() {
64     each_ip(&mut |addr1, addr2| {
65         let server = t!(UdpSocket::bind(&addr1));
66         assert_eq!(server.peer_addr().unwrap_err().kind(), ErrorKind::NotConnected);
67         t!(server.connect(&addr2));
68         assert_eq!(addr2, t!(server.peer_addr()));
69     })
70 }
71
72 #[test]
73 fn udp_clone_smoke() {
74     each_ip(&mut |addr1, addr2| {
75         let sock1 = t!(UdpSocket::bind(&addr1));
76         let sock2 = t!(UdpSocket::bind(&addr2));
77
78         let _t = thread::spawn(move || {
79             let mut buf = [0, 0];
80             assert_eq!(sock2.recv_from(&mut buf).unwrap(), (1, addr1));
81             assert_eq!(buf[0], 1);
82             t!(sock2.send_to(&[2], &addr1));
83         });
84
85         let sock3 = t!(sock1.try_clone());
86
87         let (tx1, rx1) = channel();
88         let (tx2, rx2) = channel();
89         let _t = thread::spawn(move || {
90             rx1.recv().unwrap();
91             t!(sock3.send_to(&[1], &addr2));
92             tx2.send(()).unwrap();
93         });
94         tx1.send(()).unwrap();
95         let mut buf = [0, 0];
96         assert_eq!(sock1.recv_from(&mut buf).unwrap(), (1, addr2));
97         rx2.recv().unwrap();
98     })
99 }
100
101 #[test]
102 fn udp_clone_two_read() {
103     each_ip(&mut |addr1, addr2| {
104         let sock1 = t!(UdpSocket::bind(&addr1));
105         let sock2 = t!(UdpSocket::bind(&addr2));
106         let (tx1, rx) = channel();
107         let tx2 = tx1.clone();
108
109         let _t = thread::spawn(move || {
110             t!(sock2.send_to(&[1], &addr1));
111             rx.recv().unwrap();
112             t!(sock2.send_to(&[2], &addr1));
113             rx.recv().unwrap();
114         });
115
116         let sock3 = t!(sock1.try_clone());
117
118         let (done, rx) = channel();
119         let _t = thread::spawn(move || {
120             let mut buf = [0, 0];
121             t!(sock3.recv_from(&mut buf));
122             tx2.send(()).unwrap();
123             done.send(()).unwrap();
124         });
125         let mut buf = [0, 0];
126         t!(sock1.recv_from(&mut buf));
127         tx1.send(()).unwrap();
128
129         rx.recv().unwrap();
130     })
131 }
132
133 #[test]
134 fn udp_clone_two_write() {
135     each_ip(&mut |addr1, addr2| {
136         let sock1 = t!(UdpSocket::bind(&addr1));
137         let sock2 = t!(UdpSocket::bind(&addr2));
138
139         let (tx, rx) = channel();
140         let (serv_tx, serv_rx) = channel();
141
142         let _t = thread::spawn(move || {
143             let mut buf = [0, 1];
144             rx.recv().unwrap();
145             t!(sock2.recv_from(&mut buf));
146             serv_tx.send(()).unwrap();
147         });
148
149         let sock3 = t!(sock1.try_clone());
150
151         let (done, rx) = channel();
152         let tx2 = tx.clone();
153         let _t = thread::spawn(move || {
154             if sock3.send_to(&[1], &addr2).is_ok() {
155                 let _ = tx2.send(());
156             }
157             done.send(()).unwrap();
158         });
159         if sock1.send_to(&[2], &addr2).is_ok() {
160             let _ = tx.send(());
161         }
162         drop(tx);
163
164         rx.recv().unwrap();
165         serv_rx.recv().unwrap();
166     })
167 }
168
169 #[test]
170 fn debug() {
171     let name = if cfg!(windows) { "socket" } else { "fd" };
172     let socket_addr = next_test_ip4();
173
174     let udpsock = t!(UdpSocket::bind(&socket_addr));
175     let udpsock_inner = udpsock.0.socket().as_raw();
176     let compare = format!("UdpSocket {{ addr: {socket_addr:?}, {name}: {udpsock_inner:?} }}");
177     assert_eq!(format!("{udpsock:?}"), compare);
178 }
179
180 // FIXME: re-enabled openbsd/netbsd tests once their socket timeout code
181 //        no longer has rounding errors.
182 // VxWorks ignores SO_SNDTIMEO.
183 #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd", target_os = "vxworks"), ignore)]
184 #[test]
185 fn timeouts() {
186     let addr = next_test_ip4();
187
188     let stream = t!(UdpSocket::bind(&addr));
189     let dur = Duration::new(15410, 0);
190
191     assert_eq!(None, t!(stream.read_timeout()));
192
193     t!(stream.set_read_timeout(Some(dur)));
194     assert_eq!(Some(dur), t!(stream.read_timeout()));
195
196     assert_eq!(None, t!(stream.write_timeout()));
197
198     t!(stream.set_write_timeout(Some(dur)));
199     assert_eq!(Some(dur), t!(stream.write_timeout()));
200
201     t!(stream.set_read_timeout(None));
202     assert_eq!(None, t!(stream.read_timeout()));
203
204     t!(stream.set_write_timeout(None));
205     assert_eq!(None, t!(stream.write_timeout()));
206 }
207
208 #[test]
209 fn test_read_timeout() {
210     let addr = next_test_ip4();
211
212     let stream = t!(UdpSocket::bind(&addr));
213     t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
214
215     let mut buf = [0; 10];
216
217     let start = Instant::now();
218     loop {
219         let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
220         if kind != ErrorKind::Interrupted {
221             assert!(
222                 kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
223                 "unexpected_error: {:?}",
224                 kind
225             );
226             break;
227         }
228     }
229     assert!(start.elapsed() > Duration::from_millis(400));
230 }
231
232 #[test]
233 fn test_read_with_timeout() {
234     let addr = next_test_ip4();
235
236     let stream = t!(UdpSocket::bind(&addr));
237     t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
238
239     t!(stream.send_to(b"hello world", &addr));
240
241     let mut buf = [0; 11];
242     t!(stream.recv_from(&mut buf));
243     assert_eq!(b"hello world", &buf[..]);
244
245     let start = Instant::now();
246     loop {
247         let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
248         if kind != ErrorKind::Interrupted {
249             assert!(
250                 kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
251                 "unexpected_error: {:?}",
252                 kind
253             );
254             break;
255         }
256     }
257     assert!(start.elapsed() > Duration::from_millis(400));
258 }
259
260 // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
261 // when passed zero Durations
262 #[test]
263 fn test_timeout_zero_duration() {
264     let addr = next_test_ip4();
265
266     let socket = t!(UdpSocket::bind(&addr));
267
268     let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
269     let err = result.unwrap_err();
270     assert_eq!(err.kind(), ErrorKind::InvalidInput);
271
272     let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
273     let err = result.unwrap_err();
274     assert_eq!(err.kind(), ErrorKind::InvalidInput);
275 }
276
277 #[test]
278 fn connect_send_recv() {
279     let addr = next_test_ip4();
280
281     let socket = t!(UdpSocket::bind(&addr));
282     t!(socket.connect(addr));
283
284     t!(socket.send(b"hello world"));
285
286     let mut buf = [0; 11];
287     t!(socket.recv(&mut buf));
288     assert_eq!(b"hello world", &buf[..]);
289 }
290
291 #[test]
292 fn connect_send_peek_recv() {
293     each_ip(&mut |addr, _| {
294         let socket = t!(UdpSocket::bind(&addr));
295         t!(socket.connect(addr));
296
297         t!(socket.send(b"hello world"));
298
299         for _ in 1..3 {
300             let mut buf = [0; 11];
301             let size = t!(socket.peek(&mut buf));
302             assert_eq!(b"hello world", &buf[..]);
303             assert_eq!(size, 11);
304         }
305
306         let mut buf = [0; 11];
307         let size = t!(socket.recv(&mut buf));
308         assert_eq!(b"hello world", &buf[..]);
309         assert_eq!(size, 11);
310     })
311 }
312
313 #[test]
314 fn peek_from() {
315     each_ip(&mut |addr, _| {
316         let socket = t!(UdpSocket::bind(&addr));
317         t!(socket.send_to(b"hello world", &addr));
318
319         for _ in 1..3 {
320             let mut buf = [0; 11];
321             let (size, _) = t!(socket.peek_from(&mut buf));
322             assert_eq!(b"hello world", &buf[..]);
323             assert_eq!(size, 11);
324         }
325
326         let mut buf = [0; 11];
327         let (size, _) = t!(socket.recv_from(&mut buf));
328         assert_eq!(b"hello world", &buf[..]);
329         assert_eq!(size, 11);
330     })
331 }
332
333 #[test]
334 fn ttl() {
335     let ttl = 100;
336
337     let addr = next_test_ip4();
338
339     let stream = t!(UdpSocket::bind(&addr));
340
341     t!(stream.set_ttl(ttl));
342     assert_eq!(ttl, t!(stream.ttl()));
343 }
344
345 #[test]
346 fn set_nonblocking() {
347     each_ip(&mut |addr, _| {
348         let socket = t!(UdpSocket::bind(&addr));
349
350         t!(socket.set_nonblocking(true));
351         t!(socket.set_nonblocking(false));
352
353         t!(socket.connect(addr));
354
355         t!(socket.set_nonblocking(false));
356         t!(socket.set_nonblocking(true));
357
358         let mut buf = [0];
359         match socket.recv(&mut buf) {
360             Ok(_) => panic!("expected error"),
361             Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
362             Err(e) => panic!("unexpected error {e}"),
363         }
364     })
365 }