test(client): add client benchmarks with mocked IO
This commit is contained in:
		| @@ -207,3 +207,66 @@ fn checkout_win_allows_connect_future_to_be_pooled() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[cfg(feature = "nightly")] | ||||||
|  | #[bench] | ||||||
|  | fn bench_http1_get_0b(b: &mut test::Bencher) { | ||||||
|  |     let _ = pretty_env_logger::try_init(); | ||||||
|  |  | ||||||
|  |     let mut rt = Runtime::new().expect("new rt"); | ||||||
|  |     let mut connector = MockConnector::new(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     let client = Client::builder() | ||||||
|  |         .build::<_, ::Body>(connector.clone()); | ||||||
|  |  | ||||||
|  |     client.pool.no_timer(); | ||||||
|  |  | ||||||
|  |     let uri = Uri::from_static("http://mock.local/a"); | ||||||
|  |  | ||||||
|  |     b.iter(move || { | ||||||
|  |         let sock1 = connector.mock("http://mock.local"); | ||||||
|  |         let res1 = client | ||||||
|  |             .get(uri.clone()) | ||||||
|  |             .and_then(|res| { | ||||||
|  |                 res.into_body().for_each(|_| Ok(())) | ||||||
|  |             }); | ||||||
|  |         let srv1 = poll_fn(|| { | ||||||
|  |             try_ready!(sock1.read(&mut [0u8; 512])); | ||||||
|  |             try_ready!(sock1.write(b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n")); | ||||||
|  |             Ok(Async::Ready(())) | ||||||
|  |         }).map_err(|e: ::std::io::Error| panic!("srv1 poll_fn error: {}", e)); | ||||||
|  |         rt.block_on(res1.join(srv1)).expect("res1"); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[cfg(feature = "nightly")] | ||||||
|  | #[bench] | ||||||
|  | fn bench_http1_get_10b(b: &mut test::Bencher) { | ||||||
|  |     let _ = pretty_env_logger::try_init(); | ||||||
|  |  | ||||||
|  |     let mut rt = Runtime::new().expect("new rt"); | ||||||
|  |     let mut connector = MockConnector::new(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     let client = Client::builder() | ||||||
|  |         .build::<_, ::Body>(connector.clone()); | ||||||
|  |  | ||||||
|  |     client.pool.no_timer(); | ||||||
|  |  | ||||||
|  |     let uri = Uri::from_static("http://mock.local/a"); | ||||||
|  |  | ||||||
|  |     b.iter(move || { | ||||||
|  |         let sock1 = connector.mock("http://mock.local"); | ||||||
|  |         let res1 = client | ||||||
|  |             .get(uri.clone()) | ||||||
|  |             .and_then(|res| { | ||||||
|  |                 res.into_body().for_each(|_| Ok(())) | ||||||
|  |             }); | ||||||
|  |         let srv1 = poll_fn(|| { | ||||||
|  |             try_ready!(sock1.read(&mut [0u8; 512])); | ||||||
|  |             try_ready!(sock1.write(b"HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\n0123456789")); | ||||||
|  |             Ok(Async::Ready(())) | ||||||
|  |         }).map_err(|e: ::std::io::Error| panic!("srv1 poll_fn error: {}", e)); | ||||||
|  |         rt.block_on(res1.join(srv1)).expect("res1"); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								src/mock.rs
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/mock.rs
									
									
									
									
									
								
							| @@ -438,15 +438,19 @@ impl Drop for DuplexHandle { | |||||||
| type BoxedConnectFut = Box<Future<Item=(Duplex, Connected), Error=io::Error> + Send>; | type BoxedConnectFut = Box<Future<Item=(Duplex, Connected), Error=io::Error> + Send>; | ||||||
|  |  | ||||||
| #[cfg(feature = "runtime")] | #[cfg(feature = "runtime")] | ||||||
|  | #[derive(Clone)] | ||||||
| pub struct MockConnector { | pub struct MockConnector { | ||||||
|     mocks: Mutex<HashMap<String, Vec<BoxedConnectFut>>>, |     mocks: Arc<Mutex<MockedConnections>>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[cfg(feature = "runtime")] | ||||||
|  | struct MockedConnections(HashMap<String, Vec<BoxedConnectFut>>); | ||||||
|  |  | ||||||
| #[cfg(feature = "runtime")] | #[cfg(feature = "runtime")] | ||||||
| impl MockConnector { | impl MockConnector { | ||||||
|     pub fn new() -> MockConnector { |     pub fn new() -> MockConnector { | ||||||
|         MockConnector { |         MockConnector { | ||||||
|             mocks: Mutex::new(HashMap::new()), |             mocks: Arc::new(Mutex::new(MockedConnections(HashMap::new()))), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -474,7 +478,7 @@ impl MockConnector { | |||||||
|             trace!("MockConnector mocked fut ready"); |             trace!("MockConnector mocked fut ready"); | ||||||
|             Ok((duplex, connected)) |             Ok((duplex, connected)) | ||||||
|         })); |         })); | ||||||
|         self.mocks.lock().unwrap().entry(key) |         self.mocks.lock().unwrap().0.entry(key) | ||||||
|             .or_insert(Vec::new()) |             .or_insert(Vec::new()) | ||||||
|             .push(fut); |             .push(fut); | ||||||
|  |  | ||||||
| @@ -496,7 +500,7 @@ impl Connect for MockConnector { | |||||||
|             "".to_owned() |             "".to_owned() | ||||||
|         }); |         }); | ||||||
|         let mut mocks = self.mocks.lock().unwrap(); |         let mut mocks = self.mocks.lock().unwrap(); | ||||||
|         let mocks = mocks.get_mut(&key) |         let mocks = mocks.0.get_mut(&key) | ||||||
|             .expect(&format!("unknown mocks uri: {}", key)); |             .expect(&format!("unknown mocks uri: {}", key)); | ||||||
|         assert!(!mocks.is_empty(), "no additional mocks for {}", key); |         assert!(!mocks.is_empty(), "no additional mocks for {}", key); | ||||||
|         mocks.remove(0) |         mocks.remove(0) | ||||||
| @@ -505,11 +509,10 @@ impl Connect for MockConnector { | |||||||
|  |  | ||||||
|  |  | ||||||
| #[cfg(feature = "runtime")] | #[cfg(feature = "runtime")] | ||||||
| impl Drop for MockConnector { | impl Drop for MockedConnections { | ||||||
|     fn drop(&mut self) { |     fn drop(&mut self) { | ||||||
|         if !::std::thread::panicking() { |         if !::std::thread::panicking() { | ||||||
|             let mocks = self.mocks.lock().unwrap(); |             for (key, mocks) in self.0.iter() { | ||||||
|             for (key, mocks) in mocks.iter() { |  | ||||||
|                 assert_eq!( |                 assert_eq!( | ||||||
|                     mocks.len(), |                     mocks.len(), | ||||||
|                     0, |                     0, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user