|
|
|
#![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 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_datagram() -> 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(())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn into_raw_fd_stream() -> io::Result<()> {
|
|
|
|
use async_std::os::unix::io::{FromRawFd, IntoRawFd};
|
|
|
|
task::block_on(async {
|
|
|
|
let (mut socket1, socket2) = UnixStream::pair().unwrap();
|
|
|
|
socket1.write(JULIUS_CAESAR).await?;
|
|
|
|
|
|
|
|
let mut buf = vec![0; 1024];
|
|
|
|
|
|
|
|
let mut socket2 = unsafe { UnixStream::from_raw_fd(socket2.into_raw_fd()) };
|
|
|
|
let n = socket2.read(&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 = tempfile::Builder::new()
|
|
|
|
.prefix("socket_ping_pong")
|
|
|
|
.tempdir()
|
|
|
|
.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 = tempfile::Builder::new()
|
|
|
|
.prefix("socket_ping_pong")
|
|
|
|
.tempdir()
|
|
|
|
.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(())
|
|
|
|
})
|
|
|
|
}
|