]> git.proxmox.com Git - rustc.git/blob - library/std/src/sys/unix/ext/net/tests.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / library / std / src / sys / unix / ext / net / tests.rs
1 use super::*;
2 use crate::io::prelude::*;
3 use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
4 #[cfg(any(
5 target_os = "android",
6 target_os = "dragonfly",
7 target_os = "emscripten",
8 target_os = "freebsd",
9 target_os = "linux",
10 target_os = "netbsd",
11 target_os = "openbsd",
12 ))]
13 use crate::iter::FromIterator;
14 #[cfg(any(
15 target_os = "android",
16 target_os = "dragonfly",
17 target_os = "emscripten",
18 target_os = "freebsd",
19 target_os = "linux",
20 target_os = "netbsd",
21 target_os = "openbsd",
22 ))]
23 use crate::os::unix::io::AsRawFd;
24 use crate::sys_common::io::test::tmpdir;
25 use crate::thread;
26 use crate::time::Duration;
27
28 macro_rules! or_panic {
29 ($e:expr) => {
30 match $e {
31 Ok(e) => e,
32 Err(e) => panic!("{}", e),
33 }
34 };
35 }
36
37 #[test]
38 fn basic() {
39 let dir = tmpdir();
40 let socket_path = dir.path().join("sock");
41 let msg1 = b"hello";
42 let msg2 = b"world!";
43
44 let listener = or_panic!(UnixListener::bind(&socket_path));
45 let thread = thread::spawn(move || {
46 let mut stream = or_panic!(listener.accept()).0;
47 let mut buf = [0; 5];
48 or_panic!(stream.read(&mut buf));
49 assert_eq!(&msg1[..], &buf[..]);
50 or_panic!(stream.write_all(msg2));
51 });
52
53 let mut stream = or_panic!(UnixStream::connect(&socket_path));
54 assert_eq!(Some(&*socket_path), stream.peer_addr().unwrap().as_pathname());
55 or_panic!(stream.write_all(msg1));
56 let mut buf = vec![];
57 or_panic!(stream.read_to_end(&mut buf));
58 assert_eq!(&msg2[..], &buf[..]);
59 drop(stream);
60
61 thread.join().unwrap();
62 }
63
64 #[test]
65 fn vectored() {
66 let (mut s1, mut s2) = or_panic!(UnixStream::pair());
67
68 let len = or_panic!(s1.write_vectored(&[
69 IoSlice::new(b"hello"),
70 IoSlice::new(b" "),
71 IoSlice::new(b"world!")
72 ],));
73 assert_eq!(len, 12);
74
75 let mut buf1 = [0; 6];
76 let mut buf2 = [0; 7];
77 let len =
78 or_panic!(s2.read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],));
79 assert_eq!(len, 12);
80 assert_eq!(&buf1, b"hello ");
81 assert_eq!(&buf2, b"world!\0");
82 }
83
84 #[test]
85 fn pair() {
86 let msg1 = b"hello";
87 let msg2 = b"world!";
88
89 let (mut s1, mut s2) = or_panic!(UnixStream::pair());
90 let thread = thread::spawn(move || {
91 // s1 must be moved in or the test will hang!
92 let mut buf = [0; 5];
93 or_panic!(s1.read(&mut buf));
94 assert_eq!(&msg1[..], &buf[..]);
95 or_panic!(s1.write_all(msg2));
96 });
97
98 or_panic!(s2.write_all(msg1));
99 let mut buf = vec![];
100 or_panic!(s2.read_to_end(&mut buf));
101 assert_eq!(&msg2[..], &buf[..]);
102 drop(s2);
103
104 thread.join().unwrap();
105 }
106
107 #[test]
108 fn try_clone() {
109 let dir = tmpdir();
110 let socket_path = dir.path().join("sock");
111 let msg1 = b"hello";
112 let msg2 = b"world";
113
114 let listener = or_panic!(UnixListener::bind(&socket_path));
115 let thread = thread::spawn(move || {
116 let mut stream = or_panic!(listener.accept()).0;
117 or_panic!(stream.write_all(msg1));
118 or_panic!(stream.write_all(msg2));
119 });
120
121 let mut stream = or_panic!(UnixStream::connect(&socket_path));
122 let mut stream2 = or_panic!(stream.try_clone());
123
124 let mut buf = [0; 5];
125 or_panic!(stream.read(&mut buf));
126 assert_eq!(&msg1[..], &buf[..]);
127 or_panic!(stream2.read(&mut buf));
128 assert_eq!(&msg2[..], &buf[..]);
129
130 thread.join().unwrap();
131 }
132
133 #[test]
134 fn iter() {
135 let dir = tmpdir();
136 let socket_path = dir.path().join("sock");
137
138 let listener = or_panic!(UnixListener::bind(&socket_path));
139 let thread = thread::spawn(move || {
140 for stream in listener.incoming().take(2) {
141 let mut stream = or_panic!(stream);
142 let mut buf = [0];
143 or_panic!(stream.read(&mut buf));
144 }
145 });
146
147 for _ in 0..2 {
148 let mut stream = or_panic!(UnixStream::connect(&socket_path));
149 or_panic!(stream.write_all(&[0]));
150 }
151
152 thread.join().unwrap();
153 }
154
155 #[test]
156 fn long_path() {
157 let dir = tmpdir();
158 let socket_path = dir.path().join(
159 "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
160 sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf",
161 );
162 match UnixStream::connect(&socket_path) {
163 Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
164 Err(e) => panic!("unexpected error {}", e),
165 Ok(_) => panic!("unexpected success"),
166 }
167
168 match UnixListener::bind(&socket_path) {
169 Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
170 Err(e) => panic!("unexpected error {}", e),
171 Ok(_) => panic!("unexpected success"),
172 }
173
174 match UnixDatagram::bind(&socket_path) {
175 Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
176 Err(e) => panic!("unexpected error {}", e),
177 Ok(_) => panic!("unexpected success"),
178 }
179 }
180
181 #[test]
182 fn timeouts() {
183 let dir = tmpdir();
184 let socket_path = dir.path().join("sock");
185
186 let _listener = or_panic!(UnixListener::bind(&socket_path));
187
188 let stream = or_panic!(UnixStream::connect(&socket_path));
189 let dur = Duration::new(15410, 0);
190
191 assert_eq!(None, or_panic!(stream.read_timeout()));
192
193 or_panic!(stream.set_read_timeout(Some(dur)));
194 assert_eq!(Some(dur), or_panic!(stream.read_timeout()));
195
196 assert_eq!(None, or_panic!(stream.write_timeout()));
197
198 or_panic!(stream.set_write_timeout(Some(dur)));
199 assert_eq!(Some(dur), or_panic!(stream.write_timeout()));
200
201 or_panic!(stream.set_read_timeout(None));
202 assert_eq!(None, or_panic!(stream.read_timeout()));
203
204 or_panic!(stream.set_write_timeout(None));
205 assert_eq!(None, or_panic!(stream.write_timeout()));
206 }
207
208 #[test]
209 fn test_read_timeout() {
210 let dir = tmpdir();
211 let socket_path = dir.path().join("sock");
212
213 let _listener = or_panic!(UnixListener::bind(&socket_path));
214
215 let mut stream = or_panic!(UnixStream::connect(&socket_path));
216 or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
217
218 let mut buf = [0; 10];
219 let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
220 assert!(
221 kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
222 "unexpected_error: {:?}",
223 kind
224 );
225 }
226
227 #[test]
228 fn test_read_with_timeout() {
229 let dir = tmpdir();
230 let socket_path = dir.path().join("sock");
231
232 let listener = or_panic!(UnixListener::bind(&socket_path));
233
234 let mut stream = or_panic!(UnixStream::connect(&socket_path));
235 or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
236
237 let mut other_end = or_panic!(listener.accept()).0;
238 or_panic!(other_end.write_all(b"hello world"));
239
240 let mut buf = [0; 11];
241 or_panic!(stream.read(&mut buf));
242 assert_eq!(b"hello world", &buf[..]);
243
244 let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
245 assert!(
246 kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
247 "unexpected_error: {:?}",
248 kind
249 );
250 }
251
252 // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
253 // when passed zero Durations
254 #[test]
255 fn test_unix_stream_timeout_zero_duration() {
256 let dir = tmpdir();
257 let socket_path = dir.path().join("sock");
258
259 let listener = or_panic!(UnixListener::bind(&socket_path));
260 let stream = or_panic!(UnixStream::connect(&socket_path));
261
262 let result = stream.set_write_timeout(Some(Duration::new(0, 0)));
263 let err = result.unwrap_err();
264 assert_eq!(err.kind(), ErrorKind::InvalidInput);
265
266 let result = stream.set_read_timeout(Some(Duration::new(0, 0)));
267 let err = result.unwrap_err();
268 assert_eq!(err.kind(), ErrorKind::InvalidInput);
269
270 drop(listener);
271 }
272
273 #[test]
274 fn test_unix_datagram() {
275 let dir = tmpdir();
276 let path1 = dir.path().join("sock1");
277 let path2 = dir.path().join("sock2");
278
279 let sock1 = or_panic!(UnixDatagram::bind(&path1));
280 let sock2 = or_panic!(UnixDatagram::bind(&path2));
281
282 let msg = b"hello world";
283 or_panic!(sock1.send_to(msg, &path2));
284 let mut buf = [0; 11];
285 or_panic!(sock2.recv_from(&mut buf));
286 assert_eq!(msg, &buf[..]);
287 }
288
289 #[test]
290 fn test_unnamed_unix_datagram() {
291 let dir = tmpdir();
292 let path1 = dir.path().join("sock1");
293
294 let sock1 = or_panic!(UnixDatagram::bind(&path1));
295 let sock2 = or_panic!(UnixDatagram::unbound());
296
297 let msg = b"hello world";
298 or_panic!(sock2.send_to(msg, &path1));
299 let mut buf = [0; 11];
300 let (usize, addr) = or_panic!(sock1.recv_from(&mut buf));
301 assert_eq!(usize, 11);
302 assert!(addr.is_unnamed());
303 assert_eq!(msg, &buf[..]);
304 }
305
306 #[test]
307 fn test_connect_unix_datagram() {
308 let dir = tmpdir();
309 let path1 = dir.path().join("sock1");
310 let path2 = dir.path().join("sock2");
311
312 let bsock1 = or_panic!(UnixDatagram::bind(&path1));
313 let bsock2 = or_panic!(UnixDatagram::bind(&path2));
314 let sock = or_panic!(UnixDatagram::unbound());
315 or_panic!(sock.connect(&path1));
316
317 // Check send()
318 let msg = b"hello there";
319 or_panic!(sock.send(msg));
320 let mut buf = [0; 11];
321 let (usize, addr) = or_panic!(bsock1.recv_from(&mut buf));
322 assert_eq!(usize, 11);
323 assert!(addr.is_unnamed());
324 assert_eq!(msg, &buf[..]);
325
326 // Changing default socket works too
327 or_panic!(sock.connect(&path2));
328 or_panic!(sock.send(msg));
329 or_panic!(bsock2.recv_from(&mut buf));
330 }
331
332 #[test]
333 fn test_unix_datagram_recv() {
334 let dir = tmpdir();
335 let path1 = dir.path().join("sock1");
336
337 let sock1 = or_panic!(UnixDatagram::bind(&path1));
338 let sock2 = or_panic!(UnixDatagram::unbound());
339 or_panic!(sock2.connect(&path1));
340
341 let msg = b"hello world";
342 or_panic!(sock2.send(msg));
343 let mut buf = [0; 11];
344 let size = or_panic!(sock1.recv(&mut buf));
345 assert_eq!(size, 11);
346 assert_eq!(msg, &buf[..]);
347 }
348
349 #[test]
350 fn datagram_pair() {
351 let msg1 = b"hello";
352 let msg2 = b"world!";
353
354 let (s1, s2) = or_panic!(UnixDatagram::pair());
355 let thread = thread::spawn(move || {
356 // s1 must be moved in or the test will hang!
357 let mut buf = [0; 5];
358 or_panic!(s1.recv(&mut buf));
359 assert_eq!(&msg1[..], &buf[..]);
360 or_panic!(s1.send(msg2));
361 });
362
363 or_panic!(s2.send(msg1));
364 let mut buf = [0; 6];
365 or_panic!(s2.recv(&mut buf));
366 assert_eq!(&msg2[..], &buf[..]);
367 drop(s2);
368
369 thread.join().unwrap();
370 }
371
372 // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
373 // when passed zero Durations
374 #[test]
375 fn test_unix_datagram_timeout_zero_duration() {
376 let dir = tmpdir();
377 let path = dir.path().join("sock");
378
379 let datagram = or_panic!(UnixDatagram::bind(&path));
380
381 let result = datagram.set_write_timeout(Some(Duration::new(0, 0)));
382 let err = result.unwrap_err();
383 assert_eq!(err.kind(), ErrorKind::InvalidInput);
384
385 let result = datagram.set_read_timeout(Some(Duration::new(0, 0)));
386 let err = result.unwrap_err();
387 assert_eq!(err.kind(), ErrorKind::InvalidInput);
388 }
389
390 #[test]
391 fn abstract_namespace_not_allowed() {
392 assert!(UnixStream::connect("\0asdf").is_err());
393 }
394
395 #[test]
396 fn test_unix_stream_peek() {
397 let (txdone, rxdone) = crate::sync::mpsc::channel();
398
399 let dir = tmpdir();
400 let path = dir.path().join("sock");
401
402 let listener = or_panic!(UnixListener::bind(&path));
403 let thread = thread::spawn(move || {
404 let mut stream = or_panic!(listener.accept()).0;
405 or_panic!(stream.write_all(&[1, 3, 3, 7]));
406 or_panic!(rxdone.recv());
407 });
408
409 let mut stream = or_panic!(UnixStream::connect(&path));
410 let mut buf = [0; 10];
411 for _ in 0..2 {
412 assert_eq!(or_panic!(stream.peek(&mut buf)), 4);
413 }
414 assert_eq!(or_panic!(stream.read(&mut buf)), 4);
415
416 or_panic!(stream.set_nonblocking(true));
417 match stream.peek(&mut buf) {
418 Ok(_) => panic!("expected error"),
419 Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
420 Err(e) => panic!("unexpected error: {}", e),
421 }
422
423 or_panic!(txdone.send(()));
424 thread.join().unwrap();
425 }
426
427 #[test]
428 fn test_unix_datagram_peek() {
429 let dir = tmpdir();
430 let path1 = dir.path().join("sock");
431
432 let sock1 = or_panic!(UnixDatagram::bind(&path1));
433 let sock2 = or_panic!(UnixDatagram::unbound());
434 or_panic!(sock2.connect(&path1));
435
436 let msg = b"hello world";
437 or_panic!(sock2.send(msg));
438 for _ in 0..2 {
439 let mut buf = [0; 11];
440 let size = or_panic!(sock1.peek(&mut buf));
441 assert_eq!(size, 11);
442 assert_eq!(msg, &buf[..]);
443 }
444
445 let mut buf = [0; 11];
446 let size = or_panic!(sock1.recv(&mut buf));
447 assert_eq!(size, 11);
448 assert_eq!(msg, &buf[..]);
449 }
450
451 #[test]
452 fn test_unix_datagram_peek_from() {
453 let dir = tmpdir();
454 let path1 = dir.path().join("sock");
455
456 let sock1 = or_panic!(UnixDatagram::bind(&path1));
457 let sock2 = or_panic!(UnixDatagram::unbound());
458 or_panic!(sock2.connect(&path1));
459
460 let msg = b"hello world";
461 or_panic!(sock2.send(msg));
462 for _ in 0..2 {
463 let mut buf = [0; 11];
464 let (size, _) = or_panic!(sock1.peek_from(&mut buf));
465 assert_eq!(size, 11);
466 assert_eq!(msg, &buf[..]);
467 }
468
469 let mut buf = [0; 11];
470 let size = or_panic!(sock1.recv(&mut buf));
471 assert_eq!(size, 11);
472 assert_eq!(msg, &buf[..]);
473 }
474
475 #[cfg(any(
476 target_os = "android",
477 target_os = "dragonfly",
478 target_os = "emscripten",
479 target_os = "freebsd",
480 target_os = "linux",
481 target_os = "netbsd",
482 target_os = "openbsd",
483 ))]
484 #[test]
485 fn test_send_vectored_fds_unix_stream() {
486 let (s1, s2) = or_panic!(UnixStream::pair());
487
488 let buf1 = [1; 8];
489 let bufs_send = &[IoSlice::new(&buf1[..])][..];
490
491 let mut ancillary1_buffer = [0; 128];
492 let mut ancillary1 = SocketAncillary::new(&mut ancillary1_buffer[..]);
493 assert!(ancillary1.add_fds(&[s1.as_raw_fd()][..]));
494
495 let usize = or_panic!(s1.send_vectored_with_ancillary(&bufs_send, &mut ancillary1));
496 assert_eq!(usize, 8);
497
498 let mut buf2 = [0; 8];
499 let mut bufs_recv = &mut [IoSliceMut::new(&mut buf2[..])][..];
500
501 let mut ancillary2_buffer = [0; 128];
502 let mut ancillary2 = SocketAncillary::new(&mut ancillary2_buffer[..]);
503
504 let usize = or_panic!(s2.recv_vectored_with_ancillary(&mut bufs_recv, &mut ancillary2));
505 assert_eq!(usize, 8);
506 assert_eq!(buf1, buf2);
507
508 let mut ancillary_data_vec = Vec::from_iter(ancillary2.messages());
509 assert_eq!(ancillary_data_vec.len(), 1);
510 if let AncillaryData::ScmRights(scm_rights) = ancillary_data_vec.pop().unwrap().unwrap() {
511 let fd_vec = Vec::from_iter(scm_rights);
512 assert_eq!(fd_vec.len(), 1);
513 unsafe {
514 libc::close(fd_vec[0]);
515 }
516 } else {
517 unreachable!("must be ScmRights");
518 }
519 }
520
521 #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux",))]
522 #[test]
523 fn test_send_vectored_with_ancillary_to_unix_datagram() {
524 fn getpid() -> libc::pid_t {
525 unsafe { libc::getpid() }
526 }
527
528 fn getuid() -> libc::uid_t {
529 unsafe { libc::getuid() }
530 }
531
532 fn getgid() -> libc::gid_t {
533 unsafe { libc::getgid() }
534 }
535
536 let dir = tmpdir();
537 let path1 = dir.path().join("sock1");
538 let path2 = dir.path().join("sock2");
539
540 let bsock1 = or_panic!(UnixDatagram::bind(&path1));
541 let bsock2 = or_panic!(UnixDatagram::bind(&path2));
542
543 or_panic!(bsock2.set_passcred(true));
544
545 let buf1 = [1; 8];
546 let bufs_send = &[IoSlice::new(&buf1[..])][..];
547
548 let mut ancillary1_buffer = [0; 128];
549 let mut ancillary1 = SocketAncillary::new(&mut ancillary1_buffer[..]);
550 let mut cred1 = SocketCred::new();
551 cred1.set_pid(getpid());
552 cred1.set_uid(getuid());
553 cred1.set_gid(getgid());
554 assert!(ancillary1.add_creds(&[cred1.clone()][..]));
555
556 let usize =
557 or_panic!(bsock1.send_vectored_with_ancillary_to(&bufs_send, &mut ancillary1, &path2));
558 assert_eq!(usize, 8);
559
560 let mut buf2 = [0; 8];
561 let mut bufs_recv = &mut [IoSliceMut::new(&mut buf2[..])][..];
562
563 let mut ancillary2_buffer = [0; 128];
564 let mut ancillary2 = SocketAncillary::new(&mut ancillary2_buffer[..]);
565
566 let (usize, truncated, _addr) =
567 or_panic!(bsock2.recv_vectored_with_ancillary_from(&mut bufs_recv, &mut ancillary2));
568 assert_eq!(ancillary2.truncated(), false);
569 assert_eq!(usize, 8);
570 assert_eq!(truncated, false);
571 assert_eq!(buf1, buf2);
572
573 let mut ancillary_data_vec = Vec::from_iter(ancillary2.messages());
574 assert_eq!(ancillary_data_vec.len(), 1);
575 if let AncillaryData::ScmCredentials(scm_credentials) =
576 ancillary_data_vec.pop().unwrap().unwrap()
577 {
578 let cred_vec = Vec::from_iter(scm_credentials);
579 assert_eq!(cred_vec.len(), 1);
580 assert_eq!(cred1.get_pid(), cred_vec[0].get_pid());
581 assert_eq!(cred1.get_uid(), cred_vec[0].get_uid());
582 assert_eq!(cred1.get_gid(), cred_vec[0].get_gid());
583 } else {
584 unreachable!("must be ScmCredentials");
585 }
586 }
587
588 #[cfg(any(
589 target_os = "android",
590 target_os = "dragonfly",
591 target_os = "emscripten",
592 target_os = "freebsd",
593 target_os = "linux",
594 target_os = "netbsd",
595 target_os = "openbsd",
596 ))]
597 #[test]
598 fn test_send_vectored_with_ancillary_unix_datagram() {
599 let dir = tmpdir();
600 let path1 = dir.path().join("sock1");
601 let path2 = dir.path().join("sock2");
602
603 let bsock1 = or_panic!(UnixDatagram::bind(&path1));
604 let bsock2 = or_panic!(UnixDatagram::bind(&path2));
605
606 let buf1 = [1; 8];
607 let bufs_send = &[IoSlice::new(&buf1[..])][..];
608
609 let mut ancillary1_buffer = [0; 128];
610 let mut ancillary1 = SocketAncillary::new(&mut ancillary1_buffer[..]);
611 assert!(ancillary1.add_fds(&[bsock1.as_raw_fd()][..]));
612
613 or_panic!(bsock1.connect(&path2));
614 let usize = or_panic!(bsock1.send_vectored_with_ancillary(&bufs_send, &mut ancillary1));
615 assert_eq!(usize, 8);
616
617 let mut buf2 = [0; 8];
618 let mut bufs_recv = &mut [IoSliceMut::new(&mut buf2[..])][..];
619
620 let mut ancillary2_buffer = [0; 128];
621 let mut ancillary2 = SocketAncillary::new(&mut ancillary2_buffer[..]);
622
623 let (usize, truncated) =
624 or_panic!(bsock2.recv_vectored_with_ancillary(&mut bufs_recv, &mut ancillary2));
625 assert_eq!(usize, 8);
626 assert_eq!(truncated, false);
627 assert_eq!(buf1, buf2);
628
629 let mut ancillary_data_vec = Vec::from_iter(ancillary2.messages());
630 assert_eq!(ancillary_data_vec.len(), 1);
631 if let AncillaryData::ScmRights(scm_rights) = ancillary_data_vec.pop().unwrap().unwrap() {
632 let fd_vec = Vec::from_iter(scm_rights);
633 assert_eq!(fd_vec.len(), 1);
634 unsafe {
635 libc::close(fd_vec[0]);
636 }
637 } else {
638 unreachable!("must be ScmRights");
639 }
640 }