tests: reduce boilerplate of sending GET requests
This adds a `SendRequestExt` trait to h2-support, with a `get` method that does a lot of the repeated request building stuff many test cases were doing. As a first step, the cleans up stream_states tests to use it.
This commit is contained in:
		
							
								
								
									
										30
									
								
								tests/h2-support/src/client_ext.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								tests/h2-support/src/client_ext.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| use bytes::IntoBuf; | ||||
| use http::Request; | ||||
| use h2::client::{ResponseFuture, SendRequest}; | ||||
|  | ||||
| /// Extend the `h2::client::SendRequest` type with convenience methods. | ||||
| pub trait SendRequestExt { | ||||
|     /// Convenience method to send a GET request and ignore the SendStream | ||||
|     /// (since GETs don't need to send a body). | ||||
|     fn get(&mut self, uri: &str) -> ResponseFuture; | ||||
| } | ||||
|  | ||||
| impl<B> SendRequestExt for SendRequest<B> | ||||
| where | ||||
|     B: IntoBuf, | ||||
|     B::Buf: 'static, | ||||
| { | ||||
|     fn get(&mut self, uri: &str) -> ResponseFuture { | ||||
|         let req = Request::builder() | ||||
|             // method is GET by default | ||||
|             .uri(uri) | ||||
|             .body(()) | ||||
|             .expect("valid uri"); | ||||
|  | ||||
|         let (fut, _tx) = self | ||||
|             .send_request(req, /*eos =*/true) | ||||
|             .expect("send_request"); | ||||
|  | ||||
|         fut | ||||
|     } | ||||
| } | ||||
| @@ -72,20 +72,11 @@ pub trait FutureExt: Future { | ||||
|     /// | ||||
|     /// This allows the executor to poll other futures before trying this one | ||||
|     /// again. | ||||
|     fn yield_once(self) -> Box<Future<Item = Self::Item, Error = Self::Error>> | ||||
|     fn yield_once(self) -> Box<dyn Future<Item = Self::Item, Error = Self::Error>> | ||||
|     where | ||||
|         Self: Future + Sized + 'static, | ||||
|     { | ||||
|         let mut ready = false; | ||||
|         Box::new(::futures::future::poll_fn(move || { | ||||
|             if ready { | ||||
|                 Ok::<_, ()>(().into()) | ||||
|             } else { | ||||
|                 ready = true; | ||||
|                 ::futures::task::current().notify(); | ||||
|                 Ok(::futures::Async::NotReady) | ||||
|             } | ||||
|         }).then(|_| self)) | ||||
|         Box::new(super::util::yield_once().then(move |_| self)) | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -22,8 +22,10 @@ pub mod mock_io; | ||||
| pub mod notify; | ||||
| pub mod util; | ||||
|  | ||||
| mod client_ext; | ||||
| mod future_ext; | ||||
|  | ||||
| pub use client_ext::{SendRequestExt}; | ||||
| pub use future_ext::{FutureExt, Unwrap}; | ||||
|  | ||||
| pub type WindowSize = usize; | ||||
|   | ||||
| @@ -116,7 +116,7 @@ impl Handle { | ||||
|     } | ||||
|  | ||||
|     /// Read the client preface | ||||
|     pub fn read_preface(self) -> Box<Future<Item = Self, Error = io::Error>> { | ||||
|     pub fn read_preface(self) -> Box<dyn Future<Item = Self, Error = io::Error>> { | ||||
|         let buf = vec![0; PREFACE.len()]; | ||||
|         let ret = read_exact(self, buf).and_then(|(me, buf)| { | ||||
|             assert_eq!(buf, PREFACE); | ||||
| @@ -129,7 +129,7 @@ impl Handle { | ||||
|     /// Perform the H2 handshake | ||||
|     pub fn assert_client_handshake( | ||||
|         self, | ||||
|     ) -> Box<Future<Item = (frame::Settings, Self), Error = h2::Error>> { | ||||
|     ) -> Box<dyn Future<Item = (frame::Settings, Self), Error = h2::Error>> { | ||||
|         self.assert_client_handshake_with_settings(frame::Settings::default()) | ||||
|     } | ||||
|  | ||||
| @@ -137,7 +137,7 @@ impl Handle { | ||||
|     pub fn assert_client_handshake_with_settings<T>( | ||||
|         mut self, | ||||
|         settings: T, | ||||
|     ) -> Box<Future<Item = (frame::Settings, Self), Error = h2::Error>> | ||||
|     ) -> Box<dyn Future<Item = (frame::Settings, Self), Error = h2::Error>> | ||||
|     where | ||||
|         T: Into<frame::Settings>, | ||||
|     { | ||||
| @@ -189,7 +189,7 @@ impl Handle { | ||||
|     /// Perform the H2 handshake | ||||
|     pub fn assert_server_handshake( | ||||
|         self, | ||||
|     ) -> Box<Future<Item = (frame::Settings, Self), Error = h2::Error>> { | ||||
|     ) -> Box<dyn Future<Item = (frame::Settings, Self), Error = h2::Error>> { | ||||
|         self.assert_server_handshake_with_settings(frame::Settings::default()) | ||||
|     } | ||||
|  | ||||
| @@ -197,7 +197,7 @@ impl Handle { | ||||
|     pub fn assert_server_handshake_with_settings<T>( | ||||
|         mut self, | ||||
|         settings: T, | ||||
|     ) -> Box<Future<Item = (frame::Settings, Self), Error = h2::Error>> | ||||
|     ) -> Box<dyn Future<Item = (frame::Settings, Self), Error = h2::Error>> | ||||
|     where | ||||
|         T: Into<frame::Settings>, | ||||
|     { | ||||
| @@ -433,7 +433,7 @@ impl AsyncWrite for Pipe { | ||||
|  | ||||
| pub trait HandleFutureExt { | ||||
|     fn recv_settings(self) | ||||
|         -> RecvFrame<Box<Future<Item = (Option<Frame>, Handle), Error = ()>>> | ||||
|         -> RecvFrame<Box<dyn Future<Item = (Option<Frame>, Handle), Error = ()>>> | ||||
|     where | ||||
|         Self: Sized + 'static, | ||||
|         Self: Future<Item = (frame::Settings, Handle)>, | ||||
| @@ -443,7 +443,7 @@ pub trait HandleFutureExt { | ||||
|     } | ||||
|  | ||||
|     fn recv_custom_settings<T>(self, settings: T) | ||||
|         -> RecvFrame<Box<Future<Item = (Option<Frame>, Handle), Error = ()>>> | ||||
|         -> RecvFrame<Box<dyn Future<Item = (Option<Frame>, Handle), Error = ()>>> | ||||
|     where | ||||
|         Self: Sized + 'static, | ||||
|         Self: Future<Item = (frame::Settings, Handle)>, | ||||
| @@ -454,7 +454,7 @@ pub trait HandleFutureExt { | ||||
|             .map(|(settings, handle)| (Some(settings.into()), handle)) | ||||
|             .unwrap(); | ||||
|  | ||||
|         let boxed: Box<Future<Item = (Option<Frame>, Handle), Error = ()>> = | ||||
|         let boxed: Box<dyn Future<Item = (Option<Frame>, Handle), Error = ()>> = | ||||
|             Box::new(map); | ||||
|         RecvFrame { | ||||
|             inner: boxed, | ||||
| @@ -462,7 +462,7 @@ pub trait HandleFutureExt { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn ignore_settings(self) -> Box<Future<Item = Handle, Error = ()>> | ||||
|     fn ignore_settings(self) -> Box<dyn Future<Item = Handle, Error = ()>> | ||||
|     where | ||||
|         Self: Sized + 'static, | ||||
|         Self: Future<Item = (frame::Settings, Handle)>, | ||||
| @@ -497,7 +497,7 @@ pub trait HandleFutureExt { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn send_bytes(self, data: &[u8]) -> Box<Future<Item = Handle, Error = Self::Error>> | ||||
|     fn send_bytes(self, data: &[u8]) -> Box<dyn Future<Item = Handle, Error = Self::Error>> | ||||
|     where | ||||
|         Self: Future<Item = Handle> + Sized + 'static, | ||||
|         Self::Error: fmt::Debug, | ||||
| @@ -536,7 +536,7 @@ pub trait HandleFutureExt { | ||||
|             .recv_frame(frames::ping(payload).pong()) | ||||
|     } | ||||
|  | ||||
|     fn idle_ms(self, ms: usize) -> Box<Future<Item = Handle, Error = Self::Error>> | ||||
|     fn idle_ms(self, ms: usize) -> Box<dyn Future<Item = Handle, Error = Self::Error>> | ||||
|     where | ||||
|         Self: Sized + 'static, | ||||
|         Self: Future<Item = Handle>, | ||||
| @@ -562,7 +562,7 @@ pub trait HandleFutureExt { | ||||
|         })) | ||||
|     } | ||||
|  | ||||
|     fn buffer_bytes(self, num: usize) -> Box<Future<Item = Handle, Error = Self::Error>> | ||||
|     fn buffer_bytes(self, num: usize) -> Box<dyn Future<Item = Handle, Error = Self::Error>> | ||||
|     where Self: Sized + 'static, | ||||
|           Self: Future<Item = Handle>, | ||||
|           Self::Error: fmt::Debug, | ||||
| @@ -596,7 +596,7 @@ pub trait HandleFutureExt { | ||||
|         })) | ||||
|     } | ||||
|  | ||||
|     fn unbounded_bytes(self) -> Box<Future<Item = Handle, Error = Self::Error>> | ||||
|     fn unbounded_bytes(self) -> Box<dyn Future<Item = Handle, Error = Self::Error>> | ||||
|     where Self: Sized + 'static, | ||||
|           Self: Future<Item = Handle>, | ||||
|           Self::Error: fmt::Debug, | ||||
| @@ -615,7 +615,7 @@ pub trait HandleFutureExt { | ||||
|         })) | ||||
|     } | ||||
|  | ||||
|     fn then_notify(self, tx: oneshot::Sender<()>) -> Box<Future<Item = Handle, Error = Self::Error>> | ||||
|     fn then_notify(self, tx: oneshot::Sender<()>) -> Box<dyn Future<Item = Handle, Error = Self::Error>> | ||||
|     where Self: Sized + 'static, | ||||
|           Self: Future<Item = Handle>, | ||||
|           Self::Error: fmt::Debug, | ||||
| @@ -626,7 +626,7 @@ pub trait HandleFutureExt { | ||||
|         })) | ||||
|     } | ||||
|  | ||||
|     fn wait_for<F>(self, other: F) -> Box<Future<Item = Self::Item, Error = Self::Error>> | ||||
|     fn wait_for<F>(self, other: F) -> Box<dyn Future<Item = Self::Item, Error = Self::Error>> | ||||
|     where | ||||
|         F: Future + 'static, | ||||
|         Self: Future + Sized + 'static | ||||
| @@ -636,7 +636,7 @@ pub trait HandleFutureExt { | ||||
|         })) | ||||
|     } | ||||
|  | ||||
|     fn close(self) -> Box<Future<Item = (), Error = ()>> | ||||
|     fn close(self) -> Box<dyn Future<Item = (), Error = ()>> | ||||
|     where | ||||
|         Self: Future<Error = ()> + Sized + 'static, | ||||
|     { | ||||
| @@ -752,7 +752,7 @@ where | ||||
|     T: Future<Item = Handle> + 'static, | ||||
|     T::Error: fmt::Debug, | ||||
| { | ||||
|     type Future = Box<Future<Item = (Option<Frame>, Handle), Error = ()>>; | ||||
|     type Future = Box<dyn Future<Item = (Option<Frame>, Handle), Error = ()>>; | ||||
|  | ||||
|     fn into_recv_frame(self, frame: Option<Frame>) -> RecvFrame<Self::Future> { | ||||
|         let into_fut = Box::new( | ||||
|   | ||||
| @@ -1,69 +0,0 @@ | ||||
| //! Utilities to support tests. | ||||
|  | ||||
| #[cfg(not(feature = "unstable"))] | ||||
| compile_error!( | ||||
|     "Tests depend on the 'unstable' feature on h2. \ | ||||
|     Retry with `cargo test --features unstable`" | ||||
| ); | ||||
|  | ||||
| pub extern crate bytes; | ||||
| pub extern crate env_logger; | ||||
| pub extern crate futures; | ||||
| pub extern crate h2; | ||||
| pub extern crate http; | ||||
| pub extern crate string; | ||||
| pub extern crate tokio_io; | ||||
|  | ||||
| // Kind of annoying, but we can't use macros from crates that aren't specified | ||||
| // at the root. | ||||
| macro_rules! try_ready { | ||||
|     ($e:expr) => ({ | ||||
|         use $crate::support::futures::Async; | ||||
|         match $e { | ||||
|             Ok(Async::Ready(t)) => t, | ||||
|             Ok(Async::NotReady) => return Ok(Async::NotReady), | ||||
|             Err(e) => return Err(From::from(e)), | ||||
|         } | ||||
|     }) | ||||
| } | ||||
|  | ||||
| macro_rules! try_nb { | ||||
|     ($e:expr) => ({ | ||||
|         use ::std::io::ErrorKind::WouldBlock; | ||||
|         use $crate::support::futures::Async; | ||||
|  | ||||
|         match $e { | ||||
|             Ok(t) => t, | ||||
|             Err(ref e) if e.kind() == WouldBlock => { | ||||
|                 return Ok(Async::NotReady) | ||||
|             } | ||||
|             Err(e) => return Err(e.into()), | ||||
|         } | ||||
|     }) | ||||
| } | ||||
|  | ||||
| #[macro_use] | ||||
| mod assert; | ||||
|  | ||||
| #[macro_use] | ||||
| pub mod raw; | ||||
|  | ||||
| pub mod frames; | ||||
| pub mod prelude; | ||||
| pub mod mock; | ||||
| pub mod mock_io; | ||||
| pub mod notify; | ||||
| pub mod util; | ||||
|  | ||||
| mod future_ext; | ||||
|  | ||||
| pub use self::future_ext::{FutureExt, Unwrap}; | ||||
|  | ||||
| pub type WindowSize = usize; | ||||
| pub const DEFAULT_WINDOW_SIZE: WindowSize = (1 << 16) - 1; | ||||
|  | ||||
| // This is our test Codec type | ||||
| pub type Codec<T> = h2::Codec<T, ::std::io::Cursor<::bytes::Bytes>>; | ||||
|  | ||||
| // This is the frame type that is sent | ||||
| pub type SendFrame = h2::frame::Frame<::std::io::Cursor<::bytes::Bytes>>; | ||||
| @@ -31,6 +31,9 @@ pub use self::futures::{Future, IntoFuture, Sink, Stream}; | ||||
| // And our Future extensions | ||||
| pub use super::future_ext::{FutureExt, Unwrap}; | ||||
|  | ||||
| // Our client_ext helpers | ||||
| pub use super::client_ext::{SendRequestExt}; | ||||
|  | ||||
| // Re-export HTTP types | ||||
| pub use self::http::{uri, HeaderMap, Method, Request, Response, StatusCode, Version}; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user