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