Skip to content

Commit 79f970c

Browse files
committed
test(benches): clean up end_to_end benchmark configuration
1 parent b20971c commit 79f970c

File tree

1 file changed

+116
-96
lines changed

1 file changed

+116
-96
lines changed

benches/end_to_end.rs

Lines changed: 116 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -11,144 +11,164 @@ use std::net::SocketAddr;
1111

1212
use futures::{Future, Stream};
1313
use tokio::runtime::current_thread::Runtime;
14-
use tokio::net::TcpListener;
1514

16-
use hyper::{Body, Method, Request, Response, Version};
15+
use hyper::{Body, Method, Request, Response, Server};
1716
use hyper::client::HttpConnector;
18-
use hyper::server::conn::Http;
1917

2018
#[bench]
2119
fn http1_get(b: &mut test::Bencher) {
22-
bench_with(b, Version::HTTP_11, || {
23-
Request::new(Body::empty())
24-
});
20+
opts()
21+
.bench(b)
2522
}
2623

2724
#[bench]
2825
fn http1_post(b: &mut test::Bencher) {
29-
bench_with(b, Version::HTTP_11, || {
30-
let mut req = Request::new("foo bar baz quux".into());
31-
*req.method_mut() = Method::POST;
32-
req
33-
});
26+
opts()
27+
.method(Method::POST)
28+
.request_body(b"foo bar baz quux")
29+
.bench(b)
3430
}
3531

3632
#[bench]
3733
fn http1_get_parallel(b: &mut test::Bencher) {
38-
bench_parallel_with(b, Version::HTTP_11, || {
39-
Request::new(Body::empty())
40-
});
34+
opts()
35+
.parallel(10)
36+
.bench(b)
4137
}
4238

4339
#[bench]
4440
fn http2_get(b: &mut test::Bencher) {
45-
bench_with(b, Version::HTTP_2, || {
46-
Request::new(Body::empty())
47-
});
41+
opts()
42+
.http2()
43+
.bench(b)
4844
}
4945

5046
#[bench]
5147
fn http2_post(b: &mut test::Bencher) {
52-
bench_with(b, Version::HTTP_2, || {
53-
let mut req = Request::new("foo bar baz quux".into());
54-
*req.method_mut() = Method::POST;
55-
req
56-
});
48+
opts()
49+
.http2()
50+
.method(Method::POST)
51+
.request_body(b"foo bar baz quux")
52+
.bench(b)
5753
}
5854

5955
#[bench]
6056
fn http2_get_parallel(b: &mut test::Bencher) {
61-
bench_parallel_with(b, Version::HTTP_2, || {
62-
Request::new(Body::empty())
63-
});
57+
opts()
58+
.http2()
59+
.parallel(10)
60+
.bench(b)
6461
}
6562

66-
fn bench_with<F>(b: &mut test::Bencher, version: Version, make_request: F)
67-
where
68-
F: Fn() -> Request<Body>,
69-
{
70-
let _ = pretty_env_logger::try_init();
71-
let mut rt = Runtime::new().unwrap();
72-
let body = b"Hello";
73-
let addr = spawn_hello(&mut rt, body);
74-
75-
let connector = HttpConnector::new(1);
76-
let client = hyper::Client::builder()
77-
.http2_only(version == Version::HTTP_2)
78-
.build::<_, Body>(connector);
79-
80-
let url: hyper::Uri = format!("http://{}/hello", addr).parse().unwrap();
81-
82-
b.bytes = body.len() as u64;
83-
b.iter(move || {
84-
let mut req = make_request();
85-
*req.uri_mut() = url.clone();
86-
rt.block_on(client.request(req).and_then(|res| {
87-
res.into_body().for_each(|_chunk| {
88-
Ok(())
89-
})
90-
})).expect("client wait");
91-
});
63+
// ==== Benchmark Options =====
64+
65+
struct Opts {
66+
http2: bool,
67+
parallel_cnt: u32,
68+
request_method: Method,
69+
request_body: Option<&'static [u8]>,
70+
response_body: &'static [u8],
71+
}
72+
73+
fn opts() -> Opts {
74+
Opts {
75+
http2: false,
76+
parallel_cnt: 1,
77+
request_method: Method::GET,
78+
request_body: None,
79+
response_body: b"Hello",
80+
}
9281
}
9382

94-
fn bench_parallel_with<F>(b: &mut test::Bencher, version: Version, make_request: F)
95-
where
96-
F: Fn() -> Request<Body>,
97-
{
98-
let _ = pretty_env_logger::try_init();
99-
let mut rt = Runtime::new().unwrap();
100-
let body = b"Hello";
101-
let addr = spawn_hello(&mut rt, body);
102-
103-
let connector = HttpConnector::new(1);
104-
let client = hyper::Client::builder()
105-
.http2_only(version == Version::HTTP_2)
106-
.build::<_, Body>(connector);
107-
108-
let url: hyper::Uri = format!("http://{}/hello", addr).parse().unwrap();
109-
110-
b.bytes = body.len() as u64;
111-
b.iter(move || {
112-
let futs = (0..10)
113-
.into_iter()
114-
.map(|_| {
83+
impl Opts {
84+
fn http2(mut self) -> Self {
85+
self.http2 = true;
86+
self
87+
}
88+
89+
fn method(mut self, m: Method) -> Self {
90+
self.request_method = m;
91+
self
92+
}
93+
94+
fn request_body(mut self, body: &'static [u8]) -> Self {
95+
self.request_body = Some(body);
96+
self
97+
}
98+
99+
fn parallel(mut self, cnt: u32) -> Self {
100+
assert!(cnt > 0, "parallel count must be larger than 0");
101+
self.parallel_cnt = cnt;
102+
self
103+
}
104+
105+
fn bench(self, b: &mut test::Bencher) {
106+
let _ = pretty_env_logger::try_init();
107+
let mut rt = Runtime::new().unwrap();
108+
let addr = spawn_hello(&mut rt, self.response_body);
109+
110+
let connector = HttpConnector::new(1);
111+
let client = hyper::Client::builder()
112+
.http2_only(self.http2)
113+
.build::<_, Body>(connector);
114+
115+
let url: hyper::Uri = format!("http://{}/hello", addr).parse().unwrap();
116+
117+
let make_request = || {
118+
let body = self
119+
.request_body
120+
.map(Body::from)
121+
.unwrap_or_else(|| Body::empty());
122+
let mut req = Request::new(body);
123+
*req.method_mut() = self.request_method.clone();
124+
req
125+
};
126+
127+
if self.parallel_cnt == 1 {
128+
b.iter(move || {
115129
let mut req = make_request();
116130
*req.uri_mut() = url.clone();
117-
client.request(req).and_then(|res| {
131+
rt.block_on(client.request(req).and_then(|res| {
118132
res.into_body().for_each(|_chunk| {
119133
Ok(())
120134
})
121-
}).map_err(|_e| ())
135+
})).expect("client wait");
122136
});
123-
let _ = rt.block_on(::futures::future::join_all(futs));
124-
});
137+
} else {
138+
b.iter(|| {
139+
let futs = (0..self.parallel_cnt)
140+
.into_iter()
141+
.map(|_| {
142+
let mut req = make_request();
143+
*req.uri_mut() = url.clone();
144+
client.request(req).and_then(|res| {
145+
res.into_body().for_each(|_chunk| {
146+
Ok(())
147+
})
148+
}).map_err(|e| panic!("client error: {}", e))
149+
});
150+
let _ = rt.block_on(::futures::future::join_all(futs));
151+
});
152+
}
153+
}
125154
}
126155

127156
fn spawn_hello(rt: &mut Runtime, body: &'static [u8]) -> SocketAddr {
128157
use hyper::service::{service_fn};
129158
let addr = "127.0.0.1:0".parse().unwrap();
130-
let listener = TcpListener::bind(&addr).unwrap();
131-
let addr = listener.local_addr().unwrap();
132-
133-
let http = Http::new();
134159

135-
let service = service_fn(move |req: Request<Body>| {
136-
req.into_body()
137-
.concat2()
138-
.map(move |_| {
139-
Response::new(Body::from(body))
160+
let srv = Server::bind(&addr)
161+
.serve(move || {
162+
service_fn(move |req: Request<Body>| {
163+
req.into_body()
164+
.concat2()
165+
.map(move |_| {
166+
Response::new(Body::from(body))
167+
})
140168
})
141-
});
142-
143-
// Specifically only accept 1 connection.
144-
let srv = listener.incoming()
145-
.into_future()
146-
.map_err(|(e, _inc)| panic!("accept error: {}", e))
147-
.and_then(move |(accepted, _inc)| {
148-
let socket = accepted.expect("accepted socket");
149-
http.serve_connection(socket, service)
150-
.map_err(|_| ())
151169
});
152-
rt.spawn(srv);
170+
let addr = srv.local_addr();
171+
let fut = srv.map_err(|err| panic!("server error: {}", err));
172+
rt.spawn(fut);
153173
return addr
154174
}

0 commit comments

Comments
 (0)