| #![cfg(all(unix, not(target_os = "unknown")))] |
| |
| use async_std::io; |
| use async_std::os::unix::net::{UnixDatagram, UnixListener, UnixStream}; |
| use async_std::prelude::*; |
| use async_std::task; |
| |
| use tempdir::TempDir; |
| |
| use std::time::Duration; |
| |
| const JULIUS_CAESAR: &[u8] = b" |
| Friends, Romans, countrymen - lend me your ears! |
| I come not to praise Caesar, but to bury him. |
| "; |
| |
| #[test] |
| fn send_recv() -> io::Result<()> { |
| task::block_on(async { |
| let (socket1, socket2) = UnixDatagram::pair().unwrap(); |
| socket1.send(JULIUS_CAESAR).await?; |
| |
| let mut buf = vec![0; 1024]; |
| let n = socket2.recv(&mut buf).await?; |
| assert_eq!(&buf[..n], JULIUS_CAESAR); |
| |
| Ok(()) |
| }) |
| } |
| |
| #[test] |
| fn into_raw_fd() -> io::Result<()> { |
| use async_std::os::unix::io::{FromRawFd, IntoRawFd}; |
| task::block_on(async { |
| let (socket1, socket2) = UnixDatagram::pair().unwrap(); |
| socket1.send(JULIUS_CAESAR).await?; |
| |
| let mut buf = vec![0; 1024]; |
| |
| let socket2 = unsafe { UnixDatagram::from_raw_fd(socket2.into_raw_fd()) }; |
| let n = socket2.recv(&mut buf).await?; |
| assert_eq!(&buf[..n], JULIUS_CAESAR); |
| |
| Ok(()) |
| }) |
| } |
| |
| const PING: &[u8] = b"ping"; |
| const PONG: &[u8] = b"pong"; |
| const TEST_TIMEOUT: Duration = Duration::from_secs(3); |
| |
| #[test] |
| fn socket_ping_pong() { |
| let tmp_dir = TempDir::new("socket_ping_pong").expect("Temp dir not created"); |
| let sock_path = tmp_dir.as_ref().join("sock"); |
| let iter_cnt = 16; |
| |
| let listener = |
| task::block_on(async { UnixListener::bind(&sock_path).await.expect("Socket bind") }); |
| |
| let server_handle = std::thread::spawn(move || { |
| task::block_on(async { ping_pong_server(listener, iter_cnt).await }).unwrap() |
| }); |
| |
| let client_handle = std::thread::spawn(move || { |
| task::block_on(async { ping_pong_client(&sock_path, iter_cnt).await }).unwrap() |
| }); |
| |
| client_handle.join().unwrap(); |
| server_handle.join().unwrap(); |
| } |
| |
| async fn ping_pong_server(listener: UnixListener, iterations: u32) -> std::io::Result<()> { |
| let mut incoming = listener.incoming(); |
| let mut buf = [0; 1024]; |
| for _ix in 0..iterations { |
| if let Some(s) = incoming.next().await { |
| let mut s = s?; |
| let n = s.read(&mut buf[..]).await?; |
| assert_eq!(&buf[..n], PING); |
| s.write_all(&PONG).await?; |
| } |
| } |
| Ok(()) |
| } |
| |
| async fn ping_pong_client(socket: &std::path::PathBuf, iterations: u32) -> std::io::Result<()> { |
| let mut buf = [0; 1024]; |
| for _ix in 0..iterations { |
| let mut socket = UnixStream::connect(&socket).await?; |
| socket.write_all(&PING).await?; |
| let n = async_std::io::timeout(TEST_TIMEOUT, socket.read(&mut buf[..])).await?; |
| assert_eq!(&buf[..n], PONG); |
| } |
| Ok(()) |
| } |
| |
| #[test] |
| fn uds_clone() -> io::Result<()> { |
| task::block_on(async { |
| let tmp_dir = TempDir::new("socket_ping_pong").expect("Temp dir not created"); |
| let sock_path = tmp_dir.as_ref().join("sock"); |
| let input = UnixListener::bind(&sock_path).await?; |
| |
| let mut writer = UnixStream::connect(&sock_path).await?; |
| let mut reader = input.incoming().next().await.unwrap()?; |
| |
| writer.write(b"original").await.unwrap(); |
| let mut original_buf = [0; 8]; |
| reader.read(&mut original_buf).await?; |
| assert_eq!(&original_buf, b"original"); |
| |
| writer.clone().write(b"clone").await.unwrap(); |
| let mut clone_buf = [0; 5]; |
| reader.clone().read(&mut clone_buf).await?; |
| assert_eq!(&clone_buf, b"clone"); |
| |
| Ok(()) |
| }) |
| } |