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>; | ||||
|  | ||||
| #[cfg(feature = "runtime")] | ||||
| #[derive(Clone)] | ||||
| 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")] | ||||
| impl MockConnector { | ||||
|     pub fn new() -> 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"); | ||||
|             Ok((duplex, connected)) | ||||
|         })); | ||||
|         self.mocks.lock().unwrap().entry(key) | ||||
|         self.mocks.lock().unwrap().0.entry(key) | ||||
|             .or_insert(Vec::new()) | ||||
|             .push(fut); | ||||
|  | ||||
| @@ -496,7 +500,7 @@ impl Connect for MockConnector { | ||||
|             "".to_owned() | ||||
|         }); | ||||
|         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)); | ||||
|         assert!(!mocks.is_empty(), "no additional mocks for {}", key); | ||||
|         mocks.remove(0) | ||||
| @@ -505,11 +509,10 @@ impl Connect for MockConnector { | ||||
|  | ||||
|  | ||||
| #[cfg(feature = "runtime")] | ||||
| impl Drop for MockConnector { | ||||
| impl Drop for MockedConnections { | ||||
|     fn drop(&mut self) { | ||||
|         if !::std::thread::panicking() { | ||||
|             let mocks = self.mocks.lock().unwrap(); | ||||
|             for (key, mocks) in mocks.iter() { | ||||
|             for (key, mocks) in self.0.iter() { | ||||
|                 assert_eq!( | ||||
|                     mocks.len(), | ||||
|                     0, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user