1 #![warn(rust_2018_idioms)]
2 #![cfg(feature = "full")]
3 #![cfg(unix)]
4
5 use futures::future::try_join;
6 use std::io;
7 use tokio::{
8 io::{AsyncReadExt, AsyncWriteExt},
9 net::UnixSocket,
10 };
11
12 #[tokio::test]
13 #[cfg_attr(miri, ignore)] // No `socket` in miri.
datagram_echo_server() -> io::Result<()>14 async fn datagram_echo_server() -> io::Result<()> {
15 let dir = tempfile::tempdir().unwrap();
16 let server_path = dir.path().join("server.sock");
17 let client_path = dir.path().join("client.sock");
18
19 let server_socket = {
20 let socket = UnixSocket::new_datagram()?;
21 socket.bind(&server_path)?;
22 socket.datagram()?
23 };
24
25 tokio::spawn(async move {
26 let mut recv_buf = vec![0u8; 1024];
27 loop {
28 let (len, peer_addr) = server_socket.recv_from(&mut recv_buf[..]).await?;
29 if let Some(path) = peer_addr.as_pathname() {
30 server_socket.send_to(&recv_buf[..len], path).await?;
31 }
32 }
33
34 #[allow(unreachable_code)]
35 Ok::<(), io::Error>(())
36 });
37
38 {
39 let socket = UnixSocket::new_datagram()?;
40 socket.bind(&client_path).unwrap();
41 let socket = socket.datagram()?;
42
43 socket.connect(server_path)?;
44 socket.send(b"ECHO").await?;
45
46 let mut recv_buf = [0u8; 16];
47 let len = socket.recv(&mut recv_buf[..]).await?;
48 assert_eq!(&recv_buf[..len], b"ECHO");
49 }
50
51 Ok(())
52 }
53
54 #[tokio::test]
55 #[cfg_attr(miri, ignore)] // No `socket` in miri.
listen_and_stream() -> std::io::Result<()>56 async fn listen_and_stream() -> std::io::Result<()> {
57 let dir = tempfile::Builder::new().tempdir().unwrap();
58 let sock_path = dir.path().join("connect.sock");
59 let peer_path = dir.path().join("peer.sock");
60
61 let listener = {
62 let sock = UnixSocket::new_stream()?;
63 sock.bind(&sock_path)?;
64 sock.listen(1024)?
65 };
66
67 let accept = listener.accept();
68 let connect = {
69 let sock = UnixSocket::new_stream()?;
70 sock.bind(&peer_path)?;
71 sock.connect(&sock_path)
72 };
73
74 let ((mut server, _), mut client) = try_join(accept, connect).await?;
75
76 assert_eq!(
77 server.peer_addr().unwrap().as_pathname().unwrap(),
78 &peer_path
79 );
80
81 // Write to the client.
82 client.write_all(b"hello").await?;
83 drop(client);
84
85 // Read from the server.
86 let mut buf = vec![];
87 server.read_to_end(&mut buf).await?;
88 assert_eq!(&buf, b"hello");
89 let len = server.read(&mut buf).await?;
90 assert_eq!(len, 0);
91 Ok(())
92 }
93
94 #[tokio::test]
95 #[cfg_attr(miri, ignore)] // No `socket` in miri.
assert_usage() -> std::io::Result<()>96 async fn assert_usage() -> std::io::Result<()> {
97 let datagram_socket = UnixSocket::new_datagram()?;
98 let result = datagram_socket
99 .connect(std::path::PathBuf::new().join("invalid.sock"))
100 .await;
101 assert_eq!(
102 result.unwrap_err().to_string(),
103 "connect cannot be called on a datagram socket"
104 );
105
106 let datagram_socket = UnixSocket::new_datagram()?;
107 let result = datagram_socket.listen(1024);
108 assert_eq!(
109 result.unwrap_err().to_string(),
110 "listen cannot be called on a datagram socket"
111 );
112
113 let stream_socket = UnixSocket::new_stream()?;
114 let result = stream_socket.datagram();
115 assert_eq!(
116 result.unwrap_err().to_string(),
117 "datagram cannot be called on a stream socket"
118 );
119
120 Ok(())
121 }
122