test(h1): re-enable the proto::h1::io tests
This commit is contained in:
@@ -242,6 +242,11 @@ where
|
||||
}
|
||||
Pin::new(&mut self.io).poll_flush(cx)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn flush<'a>(&'a mut self) -> impl std::future::Future<Output = io::Result<()>> + 'a {
|
||||
futures_util::future::poll_fn(move |cx| self.poll_flush(cx))
|
||||
}
|
||||
}
|
||||
|
||||
// The `B` is a `Buf`, we never project a pin to it
|
||||
@@ -252,7 +257,7 @@ pub trait MemRead {
|
||||
fn read_mem(&mut self, cx: &mut task::Context<'_>, len: usize) -> Poll<io::Result<Bytes>>;
|
||||
}
|
||||
|
||||
impl<T, B> MemRead for Buffered<T, B>
|
||||
impl<T, B> MemRead for Buffered<T, B>
|
||||
where
|
||||
T: AsyncRead + AsyncWrite + Unpin,
|
||||
B: Buf,
|
||||
@@ -650,17 +655,15 @@ impl<T: Buf> Buf for BufDeque<T> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
// FIXME: re-implement tests with `async/await`, this import should
|
||||
// trigger a warning to remind us
|
||||
use crate::Error;
|
||||
/*
|
||||
use super::*;
|
||||
use std::io::Read;
|
||||
use crate::mock::AsyncIo;
|
||||
use std::time::Duration;
|
||||
|
||||
use tokio_test::io::Builder as Mock;
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
use test::Bencher;
|
||||
|
||||
/*
|
||||
impl<T: Read> MemRead for AsyncIo<T> {
|
||||
fn read_mem(&mut self, len: usize) -> Poll<Bytes, io::Error> {
|
||||
let mut v = vec![0; len];
|
||||
@@ -668,33 +671,51 @@ mod tests {
|
||||
Ok(Async::Ready(BytesMut::from(&v[..n]).freeze()))
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn iobuf_write_empty_slice() {
|
||||
let mut mock = AsyncIo::new_buf(vec![], 256);
|
||||
mock.error(io::Error::new(io::ErrorKind::Other, "logic error"));
|
||||
|
||||
let mut io_buf = Buffered::<_, Cursor<Vec<u8>>>::new(mock);
|
||||
#[tokio::test]
|
||||
async fn iobuf_write_empty_slice() {
|
||||
// First, let's just check that the Mock would normally return an
|
||||
// error on an unexpected write, even if the buffer is empty...
|
||||
let mut mock = Mock::new().build();
|
||||
futures_util::future::poll_fn(|cx| Pin::new(&mut mock).poll_write_buf(cx, &mut Cursor::new(&[])))
|
||||
.await
|
||||
.expect_err("should be a broken pipe");
|
||||
|
||||
// underlying io will return the logic error upon write,
|
||||
// so we are testing that the io_buf does not trigger a write
|
||||
// when there is nothing to flush
|
||||
io_buf.flush().expect("should short-circuit flush");
|
||||
let mock = Mock::new().build();
|
||||
let mut io_buf = Buffered::<_, Cursor<Vec<u8>>>::new(mock);
|
||||
io_buf.flush().await.expect("should short-circuit flush");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_reads_until_blocked() {
|
||||
// missing last line ending
|
||||
let raw = "HTTP/1.1 200 OK\r\n";
|
||||
#[tokio::test]
|
||||
async fn parse_reads_until_blocked() {
|
||||
use crate::proto::h1::ClientTransaction;
|
||||
|
||||
let mock = Mock::new()
|
||||
// Split over multiple reads will read all of it
|
||||
.read(b"HTTP/1.1 200 OK\r\n")
|
||||
.read(b"Server: hyper\r\n")
|
||||
// missing last line ending
|
||||
.wait(Duration::from_secs(1))
|
||||
.build();
|
||||
|
||||
let mock = AsyncIo::new_buf(raw, raw.len());
|
||||
let mut buffered = Buffered::<_, Cursor<Vec<u8>>>::new(mock);
|
||||
let ctx = ParseContext {
|
||||
cached_headers: &mut None,
|
||||
req_method: &mut None,
|
||||
};
|
||||
assert!(buffered.parse::<crate::proto::h1::ClientTransaction>(ctx).unwrap().is_not_ready());
|
||||
assert!(buffered.io.blocked());
|
||||
|
||||
// We expect a `parse` to be not ready, and so can't await it directly.
|
||||
// Rather, this `poll_fn` will wrap the `Poll` result.
|
||||
futures_util::future::poll_fn(|cx| {
|
||||
let parse_ctx = ParseContext {
|
||||
cached_headers: &mut None,
|
||||
req_method: &mut None,
|
||||
};
|
||||
assert!(buffered.parse::<ClientTransaction>(cx, parse_ctx).is_pending());
|
||||
Poll::Ready(())
|
||||
}).await;
|
||||
|
||||
assert_eq!(buffered.read_buf, b"HTTP/1.1 200 OK\r\nServer: hyper\r\n"[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -791,12 +812,14 @@ mod tests {
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn write_buf_requires_non_empty_bufs() {
|
||||
let mock = AsyncIo::new_buf(vec![], 1024);
|
||||
let mock = Mock::new().build();
|
||||
let mut buffered = Buffered::<_, Cursor<Vec<u8>>>::new(mock);
|
||||
|
||||
buffered.buffer(Cursor::new(Vec::new()));
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: needs tokio_test::io to allow configure write_buf calls
|
||||
#[test]
|
||||
fn write_buf_queue() {
|
||||
extern crate pretty_env_logger;
|
||||
@@ -817,13 +840,18 @@ mod tests {
|
||||
assert_eq!(buffered.io.num_writes(), 1);
|
||||
assert_eq!(buffered.write_buf.queue.bufs.len(), 0);
|
||||
}
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn write_buf_flatten() {
|
||||
#[tokio::test]
|
||||
async fn write_buf_flatten() {
|
||||
extern crate pretty_env_logger;
|
||||
let _ = pretty_env_logger::try_init();
|
||||
|
||||
let mock = AsyncIo::new_buf(vec![], 1024);
|
||||
let mock = Mock::new()
|
||||
// Just a single write
|
||||
.write(b"hello world, it's hyper!")
|
||||
.build();
|
||||
|
||||
let mut buffered = Buffered::<_, Cursor<Vec<u8>>>::new(mock);
|
||||
buffered.write_buf.set_strategy(WriteStrategy::Flatten);
|
||||
|
||||
@@ -833,19 +861,21 @@ mod tests {
|
||||
buffered.buffer(Cursor::new(b"hyper!".to_vec()));
|
||||
assert_eq!(buffered.write_buf.queue.bufs.len(), 0);
|
||||
|
||||
buffered.flush().unwrap();
|
||||
|
||||
assert_eq!(buffered.io, b"hello world, it's hyper!");
|
||||
assert_eq!(buffered.io.num_writes(), 1);
|
||||
buffered.flush().await.expect("flush");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_buf_auto_flatten() {
|
||||
#[tokio::test]
|
||||
async fn write_buf_auto_flatten() {
|
||||
extern crate pretty_env_logger;
|
||||
let _ = pretty_env_logger::try_init();
|
||||
|
||||
let mut mock = AsyncIo::new_buf(vec![], 1024);
|
||||
mock.max_read_vecs(0); // disable vectored IO
|
||||
let mock = Mock::new()
|
||||
// Expects write_buf to only consume first buffer
|
||||
.write(b"hello ")
|
||||
// And then the Auto strategy will have flattened
|
||||
.write(b"world, it's hyper!")
|
||||
.build();
|
||||
|
||||
let mut buffered = Buffered::<_, Cursor<Vec<u8>>>::new(mock);
|
||||
|
||||
// we have 4 buffers, but hope to detect that vectored IO isn't
|
||||
@@ -856,20 +886,24 @@ mod tests {
|
||||
buffered.buffer(Cursor::new(b"it's ".to_vec()));
|
||||
buffered.buffer(Cursor::new(b"hyper!".to_vec()));
|
||||
assert_eq!(buffered.write_buf.queue.bufs.len(), 3);
|
||||
buffered.flush().unwrap();
|
||||
|
||||
assert_eq!(buffered.io, b"hello world, it's hyper!");
|
||||
assert_eq!(buffered.io.num_writes(), 2);
|
||||
buffered.flush().await.expect("flush");
|
||||
|
||||
assert_eq!(buffered.write_buf.queue.bufs.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_buf_queue_disable_auto() {
|
||||
#[tokio::test]
|
||||
async fn write_buf_queue_disable_auto() {
|
||||
extern crate pretty_env_logger;
|
||||
let _ = pretty_env_logger::try_init();
|
||||
|
||||
let mut mock = AsyncIo::new_buf(vec![], 1024);
|
||||
mock.max_read_vecs(0); // disable vectored IO
|
||||
let mock = Mock::new()
|
||||
.write(b"hello ")
|
||||
.write(b"world, ")
|
||||
.write(b"it's ")
|
||||
.write(b"hyper!")
|
||||
.build();
|
||||
|
||||
let mut buffered = Buffered::<_, Cursor<Vec<u8>>>::new(mock);
|
||||
buffered.write_buf.set_strategy(WriteStrategy::Queue);
|
||||
|
||||
@@ -881,10 +915,9 @@ mod tests {
|
||||
buffered.buffer(Cursor::new(b"it's ".to_vec()));
|
||||
buffered.buffer(Cursor::new(b"hyper!".to_vec()));
|
||||
assert_eq!(buffered.write_buf.queue.bufs.len(), 3);
|
||||
buffered.flush().unwrap();
|
||||
|
||||
assert_eq!(buffered.io, b"hello world, it's hyper!");
|
||||
assert_eq!(buffered.io.num_writes(), 4);
|
||||
buffered.flush().await.expect("flush");
|
||||
|
||||
assert_eq!(buffered.write_buf.queue.bufs.len(), 0);
|
||||
}
|
||||
|
||||
@@ -903,5 +936,4 @@ mod tests {
|
||||
write_buf.headers.bytes.clear();
|
||||
})
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user