summaryrefslogtreecommitdiffstats
path: root/third_party/rust/tokio-io/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/tokio-io/tests
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/tokio-io/tests')
-rw-r--r--third_party/rust/tokio-io/tests/async_read.rs149
-rw-r--r--third_party/rust/tokio-io/tests/length_delimited.rs553
2 files changed, 702 insertions, 0 deletions
diff --git a/third_party/rust/tokio-io/tests/async_read.rs b/third_party/rust/tokio-io/tests/async_read.rs
new file mode 100644
index 0000000000..604e99fd45
--- /dev/null
+++ b/third_party/rust/tokio-io/tests/async_read.rs
@@ -0,0 +1,149 @@
+extern crate bytes;
+extern crate futures;
+extern crate tokio_io;
+
+use bytes::{BufMut, BytesMut};
+use futures::Async;
+use tokio_io::AsyncRead;
+
+use std::io::{self, Read};
+
+#[test]
+fn read_buf_success() {
+ struct R;
+
+ impl Read for R {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ buf[0..11].copy_from_slice(b"hello world");
+ Ok(11)
+ }
+ }
+
+ impl AsyncRead for R {}
+
+ let mut buf = BytesMut::with_capacity(65);
+
+ let n = match R.read_buf(&mut buf).unwrap() {
+ Async::Ready(n) => n,
+ _ => panic!(),
+ };
+
+ assert_eq!(11, n);
+ assert_eq!(buf[..], b"hello world"[..]);
+}
+
+#[test]
+fn read_buf_error() {
+ struct R;
+
+ impl Read for R {
+ fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
+ Err(io::Error::new(io::ErrorKind::Other, "other"))
+ }
+ }
+
+ impl AsyncRead for R {}
+
+ let mut buf = BytesMut::with_capacity(65);
+
+ let err = R.read_buf(&mut buf).unwrap_err();
+ assert_eq!(err.kind(), io::ErrorKind::Other);
+}
+
+#[test]
+fn read_buf_no_capacity() {
+ struct R;
+
+ impl Read for R {
+ fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
+ unimplemented!();
+ }
+ }
+
+ impl AsyncRead for R {}
+
+ // Can't create BytesMut w/ zero capacity, so fill it up
+ let mut buf = BytesMut::with_capacity(64);
+ buf.put(&[0; 64][..]);
+
+ let n = match R.read_buf(&mut buf).unwrap() {
+ Async::Ready(n) => n,
+ _ => panic!(),
+ };
+
+ assert_eq!(0, n);
+}
+
+#[test]
+fn read_buf_no_uninitialized() {
+ struct R;
+
+ impl Read for R {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ for b in buf {
+ assert_eq!(0, *b);
+ }
+
+ Ok(0)
+ }
+ }
+
+ impl AsyncRead for R {}
+
+ // Can't create BytesMut w/ zero capacity, so fill it up
+ let mut buf = BytesMut::with_capacity(64);
+
+ let n = match R.read_buf(&mut buf).unwrap() {
+ Async::Ready(n) => n,
+ _ => panic!(),
+ };
+
+ assert_eq!(0, n);
+}
+
+#[test]
+fn read_buf_uninitialized_ok() {
+ struct R;
+
+ impl Read for R {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ assert_eq!(buf[0..11], b"hello world"[..]);
+ Ok(0)
+ }
+ }
+
+ impl AsyncRead for R {
+ unsafe fn prepare_uninitialized_buffer(&self, _: &mut [u8]) -> bool {
+ false
+ }
+ }
+
+ // Can't create BytesMut w/ zero capacity, so fill it up
+ let mut buf = BytesMut::with_capacity(64);
+ unsafe {
+ buf.bytes_mut()[0..11].copy_from_slice(b"hello world");
+ }
+
+ let n = match R.read_buf(&mut buf).unwrap() {
+ Async::Ready(n) => n,
+ _ => panic!(),
+ };
+
+ assert_eq!(0, n);
+}
+
+#[test]
+fn read_buf_translate_wouldblock_to_not_ready() {
+ struct R;
+
+ impl Read for R {
+ fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
+ Err(io::Error::new(io::ErrorKind::WouldBlock, ""))
+ }
+ }
+
+ impl AsyncRead for R {}
+
+ let mut buf = BytesMut::with_capacity(65);
+ assert!(!R.read_buf(&mut buf).unwrap().is_ready());
+}
diff --git a/third_party/rust/tokio-io/tests/length_delimited.rs b/third_party/rust/tokio-io/tests/length_delimited.rs
new file mode 100644
index 0000000000..c99bbf089a
--- /dev/null
+++ b/third_party/rust/tokio-io/tests/length_delimited.rs
@@ -0,0 +1,553 @@
+// This file is testing deprecated code.
+#![allow(deprecated)]
+
+extern crate futures;
+extern crate tokio_io;
+
+use tokio_io::codec::length_delimited::*;
+use tokio_io::{AsyncRead, AsyncWrite};
+
+use futures::Async::*;
+use futures::{Poll, Sink, Stream};
+
+use std::collections::VecDeque;
+use std::io;
+
+macro_rules! mock {
+ ($($x:expr,)*) => {{
+ let mut v = VecDeque::new();
+ v.extend(vec![$($x),*]);
+ Mock { calls: v }
+ }};
+}
+
+#[test]
+fn read_empty_io_yields_nothing() {
+ let mut io = FramedRead::new(mock!());
+
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn read_single_frame_one_packet() {
+ let mut io = FramedRead::new(mock! {
+ Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
+ });
+
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn read_single_frame_one_packet_little_endian() {
+ let mut io = Builder::new().little_endian().new_read(mock! {
+ Ok(b"\x09\x00\x00\x00abcdefghi"[..].into()),
+ });
+
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn read_single_frame_one_packet_native_endian() {
+ let data = if cfg!(target_endian = "big") {
+ b"\x00\x00\x00\x09abcdefghi"
+ } else {
+ b"\x09\x00\x00\x00abcdefghi"
+ };
+ let mut io = Builder::new().native_endian().new_read(mock! {
+ Ok(data[..].into()),
+ });
+
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn read_single_multi_frame_one_packet() {
+ let mut data: Vec<u8> = vec![];
+ data.extend_from_slice(b"\x00\x00\x00\x09abcdefghi");
+ data.extend_from_slice(b"\x00\x00\x00\x03123");
+ data.extend_from_slice(b"\x00\x00\x00\x0bhello world");
+
+ let mut io = FramedRead::new(mock! {
+ Ok(data.into()),
+ });
+
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"123"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"hello world"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn read_single_frame_multi_packet() {
+ let mut io = FramedRead::new(mock! {
+ Ok(b"\x00\x00"[..].into()),
+ Ok(b"\x00\x09abc"[..].into()),
+ Ok(b"defghi"[..].into()),
+ });
+
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn read_multi_frame_multi_packet() {
+ let mut io = FramedRead::new(mock! {
+ Ok(b"\x00\x00"[..].into()),
+ Ok(b"\x00\x09abc"[..].into()),
+ Ok(b"defghi"[..].into()),
+ Ok(b"\x00\x00\x00\x0312"[..].into()),
+ Ok(b"3\x00\x00\x00\x0bhello world"[..].into()),
+ });
+
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"123"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"hello world"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn read_single_frame_multi_packet_wait() {
+ let mut io = FramedRead::new(mock! {
+ Ok(b"\x00\x00"[..].into()),
+ Err(would_block()),
+ Ok(b"\x00\x09abc"[..].into()),
+ Err(would_block()),
+ Ok(b"defghi"[..].into()),
+ Err(would_block()),
+ });
+
+ assert_eq!(io.poll().unwrap(), NotReady);
+ assert_eq!(io.poll().unwrap(), NotReady);
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ assert_eq!(io.poll().unwrap(), NotReady);
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn read_multi_frame_multi_packet_wait() {
+ let mut io = FramedRead::new(mock! {
+ Ok(b"\x00\x00"[..].into()),
+ Err(would_block()),
+ Ok(b"\x00\x09abc"[..].into()),
+ Err(would_block()),
+ Ok(b"defghi"[..].into()),
+ Err(would_block()),
+ Ok(b"\x00\x00\x00\x0312"[..].into()),
+ Err(would_block()),
+ Ok(b"3\x00\x00\x00\x0bhello world"[..].into()),
+ Err(would_block()),
+ });
+
+ assert_eq!(io.poll().unwrap(), NotReady);
+ assert_eq!(io.poll().unwrap(), NotReady);
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ assert_eq!(io.poll().unwrap(), NotReady);
+ assert_eq!(io.poll().unwrap(), NotReady);
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"123"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"hello world"[..].into())));
+ assert_eq!(io.poll().unwrap(), NotReady);
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn read_incomplete_head() {
+ let mut io = FramedRead::new(mock! {
+ Ok(b"\x00\x00"[..].into()),
+ });
+
+ assert!(io.poll().is_err());
+}
+
+#[test]
+fn read_incomplete_head_multi() {
+ let mut io = FramedRead::new(mock! {
+ Err(would_block()),
+ Ok(b"\x00"[..].into()),
+ Err(would_block()),
+ });
+
+ assert_eq!(io.poll().unwrap(), NotReady);
+ assert_eq!(io.poll().unwrap(), NotReady);
+ assert!(io.poll().is_err());
+}
+
+#[test]
+fn read_incomplete_payload() {
+ let mut io = FramedRead::new(mock! {
+ Ok(b"\x00\x00\x00\x09ab"[..].into()),
+ Err(would_block()),
+ Ok(b"cd"[..].into()),
+ Err(would_block()),
+ });
+
+ assert_eq!(io.poll().unwrap(), NotReady);
+ assert_eq!(io.poll().unwrap(), NotReady);
+ assert!(io.poll().is_err());
+}
+
+#[test]
+fn read_max_frame_len() {
+ let mut io = Builder::new().max_frame_length(5).new_read(mock! {
+ Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
+ });
+
+ assert_eq!(io.poll().unwrap_err().kind(), io::ErrorKind::InvalidData);
+}
+
+#[test]
+fn read_update_max_frame_len_at_rest() {
+ let mut io = Builder::new().new_read(mock! {
+ Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
+ Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
+ });
+
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ io.set_max_frame_length(5);
+ assert_eq!(io.poll().unwrap_err().kind(), io::ErrorKind::InvalidData);
+}
+
+#[test]
+fn read_update_max_frame_len_in_flight() {
+ let mut io = Builder::new().new_read(mock! {
+ Ok(b"\x00\x00\x00\x09abcd"[..].into()),
+ Err(would_block()),
+ Ok(b"efghi"[..].into()),
+ Ok(b"\x00\x00\x00\x09abcdefghi"[..].into()),
+ });
+
+ assert_eq!(io.poll().unwrap(), NotReady);
+ io.set_max_frame_length(5);
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ assert_eq!(io.poll().unwrap_err().kind(), io::ErrorKind::InvalidData);
+}
+
+#[test]
+fn read_one_byte_length_field() {
+ let mut io = Builder::new().length_field_length(1).new_read(mock! {
+ Ok(b"\x09abcdefghi"[..].into()),
+ });
+
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn read_header_offset() {
+ let mut io = Builder::new()
+ .length_field_length(2)
+ .length_field_offset(4)
+ .new_read(mock! {
+ Ok(b"zzzz\x00\x09abcdefghi"[..].into()),
+ });
+
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn read_single_multi_frame_one_packet_skip_none_adjusted() {
+ let mut data: Vec<u8> = vec![];
+ data.extend_from_slice(b"xx\x00\x09abcdefghi");
+ data.extend_from_slice(b"yy\x00\x03123");
+ data.extend_from_slice(b"zz\x00\x0bhello world");
+
+ let mut io = Builder::new()
+ .length_field_length(2)
+ .length_field_offset(2)
+ .num_skip(0)
+ .length_adjustment(4)
+ .new_read(mock! {
+ Ok(data.into()),
+ });
+
+ assert_eq!(
+ io.poll().unwrap(),
+ Ready(Some(b"xx\x00\x09abcdefghi"[..].into()))
+ );
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"yy\x00\x03123"[..].into())));
+ assert_eq!(
+ io.poll().unwrap(),
+ Ready(Some(b"zz\x00\x0bhello world"[..].into()))
+ );
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn read_single_multi_frame_one_packet_length_includes_head() {
+ let mut data: Vec<u8> = vec![];
+ data.extend_from_slice(b"\x00\x0babcdefghi");
+ data.extend_from_slice(b"\x00\x05123");
+ data.extend_from_slice(b"\x00\x0dhello world");
+
+ let mut io = Builder::new()
+ .length_field_length(2)
+ .length_adjustment(-2)
+ .new_read(mock! {
+ Ok(data.into()),
+ });
+
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"abcdefghi"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"123"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(Some(b"hello world"[..].into())));
+ assert_eq!(io.poll().unwrap(), Ready(None));
+}
+
+#[test]
+fn write_single_frame_length_adjusted() {
+ let mut io = Builder::new().length_adjustment(-2).new_write(mock! {
+ Ok(b"\x00\x00\x00\x0b"[..].into()),
+ Ok(b"abcdefghi"[..].into()),
+ Ok(Flush),
+ });
+ assert!(io.start_send("abcdefghi").unwrap().is_ready());
+ assert!(io.poll_complete().unwrap().is_ready());
+ assert!(io.get_ref().calls.is_empty());
+}
+
+#[test]
+fn write_nothing_yields_nothing() {
+ let mut io: FramedWrite<_, &'static [u8]> = FramedWrite::new(mock!());
+ assert!(io.poll_complete().unwrap().is_ready());
+}
+
+#[test]
+fn write_single_frame_one_packet() {
+ let mut io = FramedWrite::new(mock! {
+ Ok(b"\x00\x00\x00\x09"[..].into()),
+ Ok(b"abcdefghi"[..].into()),
+ Ok(Flush),
+ });
+
+ assert!(io.start_send("abcdefghi").unwrap().is_ready());
+ assert!(io.poll_complete().unwrap().is_ready());
+ assert!(io.get_ref().calls.is_empty());
+}
+
+#[test]
+fn write_single_multi_frame_one_packet() {
+ let mut io = FramedWrite::new(mock! {
+ Ok(b"\x00\x00\x00\x09"[..].into()),
+ Ok(b"abcdefghi"[..].into()),
+ Ok(b"\x00\x00\x00\x03"[..].into()),
+ Ok(b"123"[..].into()),
+ Ok(b"\x00\x00\x00\x0b"[..].into()),
+ Ok(b"hello world"[..].into()),
+ Ok(Flush),
+ });
+
+ assert!(io.start_send("abcdefghi").unwrap().is_ready());
+ assert!(io.start_send("123").unwrap().is_ready());
+ assert!(io.start_send("hello world").unwrap().is_ready());
+ assert!(io.poll_complete().unwrap().is_ready());
+ assert!(io.get_ref().calls.is_empty());
+}
+
+#[test]
+fn write_single_multi_frame_multi_packet() {
+ let mut io = FramedWrite::new(mock! {
+ Ok(b"\x00\x00\x00\x09"[..].into()),
+ Ok(b"abcdefghi"[..].into()),
+ Ok(Flush),
+ Ok(b"\x00\x00\x00\x03"[..].into()),
+ Ok(b"123"[..].into()),
+ Ok(Flush),
+ Ok(b"\x00\x00\x00\x0b"[..].into()),
+ Ok(b"hello world"[..].into()),
+ Ok(Flush),
+ });
+
+ assert!(io.start_send("abcdefghi").unwrap().is_ready());
+ assert!(io.poll_complete().unwrap().is_ready());
+ assert!(io.start_send("123").unwrap().is_ready());
+ assert!(io.poll_complete().unwrap().is_ready());
+ assert!(io.start_send("hello world").unwrap().is_ready());
+ assert!(io.poll_complete().unwrap().is_ready());
+ assert!(io.get_ref().calls.is_empty());
+}
+
+#[test]
+fn write_single_frame_would_block() {
+ let mut io = FramedWrite::new(mock! {
+ Err(would_block()),
+ Ok(b"\x00\x00"[..].into()),
+ Err(would_block()),
+ Ok(b"\x00\x09"[..].into()),
+ Ok(b"abcdefghi"[..].into()),
+ Ok(Flush),
+ });
+
+ assert!(io.start_send("abcdefghi").unwrap().is_ready());
+ assert!(!io.poll_complete().unwrap().is_ready());
+ assert!(!io.poll_complete().unwrap().is_ready());
+ assert!(io.poll_complete().unwrap().is_ready());
+
+ assert!(io.get_ref().calls.is_empty());
+}
+
+#[test]
+fn write_single_frame_little_endian() {
+ let mut io = Builder::new().little_endian().new_write(mock! {
+ Ok(b"\x09\x00\x00\x00"[..].into()),
+ Ok(b"abcdefghi"[..].into()),
+ Ok(Flush),
+ });
+
+ assert!(io.start_send("abcdefghi").unwrap().is_ready());
+ assert!(io.poll_complete().unwrap().is_ready());
+ assert!(io.get_ref().calls.is_empty());
+}
+
+#[test]
+fn write_single_frame_with_short_length_field() {
+ let mut io = Builder::new().length_field_length(1).new_write(mock! {
+ Ok(b"\x09"[..].into()),
+ Ok(b"abcdefghi"[..].into()),
+ Ok(Flush),
+ });
+
+ assert!(io.start_send("abcdefghi").unwrap().is_ready());
+ assert!(io.poll_complete().unwrap().is_ready());
+ assert!(io.get_ref().calls.is_empty());
+}
+
+#[test]
+fn write_max_frame_len() {
+ let mut io = Builder::new().max_frame_length(5).new_write(mock! {});
+
+ assert_eq!(
+ io.start_send("abcdef").unwrap_err().kind(),
+ io::ErrorKind::InvalidInput
+ );
+ assert!(io.get_ref().calls.is_empty());
+}
+
+#[test]
+fn write_zero() {
+ let mut io = Builder::new().new_write(mock! {});
+
+ assert!(io.start_send("abcdef").unwrap().is_ready());
+ assert_eq!(
+ io.poll_complete().unwrap_err().kind(),
+ io::ErrorKind::WriteZero
+ );
+ assert!(io.get_ref().calls.is_empty());
+}
+
+#[test]
+fn write_update_max_frame_len_at_rest() {
+ let mut io = Builder::new().new_write(mock! {
+ Ok(b"\x00\x00\x00\x06"[..].into()),
+ Ok(b"abcdef"[..].into()),
+ Ok(Flush),
+ });
+
+ assert!(io.start_send("abcdef").unwrap().is_ready());
+ assert!(io.poll_complete().unwrap().is_ready());
+ io.set_max_frame_length(5);
+ assert_eq!(
+ io.start_send("abcdef").unwrap_err().kind(),
+ io::ErrorKind::InvalidInput
+ );
+ assert!(io.get_ref().calls.is_empty());
+}
+
+#[test]
+fn write_update_max_frame_len_in_flight() {
+ let mut io = Builder::new().new_write(mock! {
+ Ok(b"\x00\x00\x00\x06"[..].into()),
+ Ok(b"ab"[..].into()),
+ Err(would_block()),
+ Ok(b"cdef"[..].into()),
+ Ok(Flush),
+ });
+
+ assert!(io.start_send("abcdef").unwrap().is_ready());
+ assert!(!io.poll_complete().unwrap().is_ready());
+ io.set_max_frame_length(5);
+ assert!(io.poll_complete().unwrap().is_ready());
+ assert_eq!(
+ io.start_send("abcdef").unwrap_err().kind(),
+ io::ErrorKind::InvalidInput
+ );
+ assert!(io.get_ref().calls.is_empty());
+}
+
+// ===== Test utils =====
+
+fn would_block() -> io::Error {
+ io::Error::new(io::ErrorKind::WouldBlock, "would block")
+}
+
+struct Mock {
+ calls: VecDeque<io::Result<Op>>,
+}
+
+enum Op {
+ Data(Vec<u8>),
+ Flush,
+}
+
+use self::Op::*;
+
+impl io::Read for Mock {
+ fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
+ match self.calls.pop_front() {
+ Some(Ok(Op::Data(data))) => {
+ debug_assert!(dst.len() >= data.len());
+ dst[..data.len()].copy_from_slice(&data[..]);
+ Ok(data.len())
+ }
+ Some(Ok(_)) => panic!(),
+ Some(Err(e)) => Err(e),
+ None => Ok(0),
+ }
+ }
+}
+
+impl AsyncRead for Mock {}
+
+impl io::Write for Mock {
+ fn write(&mut self, src: &[u8]) -> io::Result<usize> {
+ match self.calls.pop_front() {
+ Some(Ok(Op::Data(data))) => {
+ let len = data.len();
+ assert!(src.len() >= len, "expect={:?}; actual={:?}", data, src);
+ assert_eq!(&data[..], &src[..len]);
+ Ok(len)
+ }
+ Some(Ok(_)) => panic!(),
+ Some(Err(e)) => Err(e),
+ None => Ok(0),
+ }
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ match self.calls.pop_front() {
+ Some(Ok(Op::Flush)) => Ok(()),
+ Some(Ok(_)) => panic!(),
+ Some(Err(e)) => Err(e),
+ None => Ok(()),
+ }
+ }
+}
+
+impl AsyncWrite for Mock {
+ fn shutdown(&mut self) -> Poll<(), io::Error> {
+ Ok(Ready(()))
+ }
+}
+
+impl<'a> From<&'a [u8]> for Op {
+ fn from(src: &'a [u8]) -> Op {
+ Op::Data(src.into())
+ }
+}
+
+impl From<Vec<u8>> for Op {
+ fn from(src: Vec<u8>) -> Op {
+ Op::Data(src)
+ }
+}