use std::io;
use std::pin::pin;
use a10::fd::{self, AsyncFd};
use a10::pipe::{Pipe, pipe, sync_pipe};
use crate::util::{Waker, expect_io_error_kind, is_send, is_sync, poll_nop, test_queue};
const DATA1: &[u8] = b"Hello from the other side";
#[test]
fn pipe_is_send_and_sync() {
is_send::<Pipe>();
is_sync::<Pipe>();
}
#[test]
fn pipe_file_descriptor() {
test_pipe(create_async(fd::Kind::File))
}
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn pipe_direct_descriptor() {
test_pipe(create_async(fd::Kind::Direct))
}
#[test]
fn sync_pipe_file_descriptor() {
let sq = test_queue();
test_pipe(
sync_pipe()
.map(|[r, s]| [AsyncFd::new(r, sq.clone()), AsyncFd::new(s, sq.clone())])
.expect("failed to create pipe"),
)
}
fn create_async(fd_kind: fd::Kind) -> [AsyncFd; 2] {
let sq = test_queue();
Waker::new()
.block_on(pipe(sq).kind(fd_kind))
.expect("failed to create pipe")
}
fn test_pipe([receiver, sender]: [AsyncFd; 2]) {
let waker = Waker::new();
waker
.block_on(sender.write_all(DATA1))
.expect("failed to write");
let received = waker
.block_on(receiver.read_n(Vec::with_capacity(DATA1.len() + 1), DATA1.len()))
.expect("failed to read");
assert_eq!(received, DATA1);
}
#[test]
fn cancel_pipe() {
let sq = test_queue();
let mut pipe = pin!(pipe(sq));
_ = poll_nop(pipe.as_mut());
drop(pipe);
}
#[test]
fn writing_to_closed_pipe() {
let sq = test_queue();
let waker = Waker::new();
let [receiver, sender] = waker.block_on(pipe(sq)).expect("failed to create pipe");
waker.block_on(receiver.close()).unwrap();
match waker.block_on(sender.write_all(DATA1)) {
Ok(()) => {}
res => expect_io_error_kind(res, io::ErrorKind::BrokenPipe),
}
}
#[test]
fn reading_from_closed_pipe() {
let sq = test_queue();
let waker = Waker::new();
let [receiver, sender] = waker.block_on(pipe(sq)).expect("failed to create pipe");
waker.block_on(sender.close()).unwrap();
let buf = waker
.block_on(receiver.read(Vec::with_capacity(8)))
.expect("failed to read");
assert!(buf.is_empty());
}