Expose Codec via an unstable flag (#49)

Exposes `Codec` using an unstable flag. This is useful for testing.
This commit is contained in:
Carl Lerche
2017-09-03 16:17:05 -07:00
committed by GitHub
parent c122e97127
commit 88d1de2da0
33 changed files with 222 additions and 85 deletions

View File

@@ -0,0 +1,64 @@
#[macro_export]
macro_rules! assert_closed {
($transport:expr) => {{
assert_eq!($transport.poll().unwrap(), None.into());
}}
}
#[macro_export]
macro_rules! poll_data {
($transport:expr) => {{
use h2::frame::Frame;
use futures::Async;
match $transport.poll() {
Ok(Async::Ready(Some(Frame::Data(frame)))) => frame,
frame => panic!("expected data frame; actual={:?}", frame),
}
}}
}
#[macro_export]
macro_rules! raw_codec {
(
$(
$fn:ident => [$($chunk:expr,)+];
)*
) => {{
let mut b = $crate::mock_io::Builder::new();
$({
let mut chunk = vec![];
$(
$crate::codec::Chunk::push(&$chunk, &mut chunk);
)+
b.$fn(&chunk[..]);
})*
$crate::Codec::new(b.build())
}}
}
pub trait Chunk {
fn push(&self, dst: &mut Vec<u8>);
}
impl Chunk for u8 {
fn push(&self, dst: &mut Vec<u8>) {
dst.push(*self);
}
}
impl<'a> Chunk for &'a [u8] {
fn push(&self, dst: &mut Vec<u8>) {
dst.extend(*self)
}
}
impl<'a> Chunk for &'a str {
fn push(&self, dst: &mut Vec<u8>) {
dst.extend(self.as_bytes())
}
}

95
tests/support/src/lib.rs Normal file
View File

@@ -0,0 +1,95 @@
//! Utilities to support tests.
pub extern crate bytes;
pub extern crate h2;
pub extern crate http;
pub extern crate tokio_io;
pub extern crate futures;
pub extern crate mock_io;
pub extern crate env_logger;
#[macro_use]
pub mod codec;
pub use self::futures::{
Future,
Sink,
Stream,
};
pub use self::futures::future::poll_fn;
pub use self::http::{
request,
response,
method,
status,
Request,
Response,
HeaderMap,
};
pub use self::h2::*;
pub use self::h2::client::{self, Client};
pub use self::h2::server::{self, Server};
pub type Codec<T> = h2::Codec<T, ::std::io::Cursor<::bytes::Bytes>>;
pub use self::bytes::{
Buf,
BufMut,
Bytes,
BytesMut,
IntoBuf,
};
pub use std::time::Duration;
use tokio_io::{AsyncRead, AsyncWrite};
pub trait MockH2 {
fn handshake(&mut self) -> &mut Self;
}
impl MockH2 for mock_io::Builder {
fn handshake(&mut self) -> &mut Self {
self.write(b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n")
// Settings frame
.write(frames::SETTINGS)
.read(frames::SETTINGS)
.read(frames::SETTINGS_ACK)
}
}
pub trait ClientExt {
fn run<F: Future>(&mut self, f: F) -> Result<F::Item, F::Error>;
}
impl<T, B> ClientExt for Client<T, B>
where T: AsyncRead + AsyncWrite + 'static,
B: IntoBuf + 'static,
{
fn run<F: Future>(&mut self, f: F) -> Result<F::Item, F::Error> {
use futures::future::{self, Future};
use futures::future::Either::*;
let res = future::poll_fn(|| self.poll())
.select2(f).wait();
match res {
Ok(A((_, b))) => {
// Connection is done...
b.wait()
}
Ok(B((v, _))) => return Ok(v),
Err(A((e, _))) => panic!("err: {:?}", e),
Err(B((e, _))) => return Err(e),
}
}
}
pub mod frames {
//! Some useful frames
pub const SETTINGS: &'static [u8] = &[0, 0, 0, 4, 0, 0, 0, 0, 0];
pub const SETTINGS_ACK: &'static [u8] = &[0, 0, 0, 4, 1, 0, 0, 0, 0];
}