Skip to content

Commit

Permalink
Merge 2c2eb75 into 4d9b724
Browse files Browse the repository at this point in the history
  • Loading branch information
xnuter committed Jul 22, 2021
2 parents 4d9b724 + 2c2eb75 commit ea45ab6
Show file tree
Hide file tree
Showing 6 changed files with 454 additions and 111 deletions.
25 changes: 18 additions & 7 deletions src/bench_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ pub trait BenchmarkProtocolAdapter {
}

impl BenchRun {
pub fn with_request_limit(
pub fn from_request_limit(
index: usize,
max_requests: usize,
rate_limiter: RateLimiter,
) -> Self {
Self::new(index, Some(max_requests), None, rate_limiter)
}

pub fn with_duration_limit(
pub fn from_duration_limit(
index: usize,
max_duration: Duration,
rate_limiter: RateLimiter,
Expand Down Expand Up @@ -114,7 +114,9 @@ mod tests {
use crate::bench_session::RateLadderBuilder;
use crate::configuration::BenchmarkMode::Http;
use crate::configuration::{BenchmarkConfig, BenchmarkConfigBuilder};
use crate::http_bench_session::HttpBenchAdapterBuilder;
use crate::http_bench_session::{
HttpBenchAdapterBuilder, HttpClientConfigBuilder, HttpRequestBuilder,
};
use crate::metrics::BenchRunMetrics;
use mockito::mock;
use std::time::Instant;
Expand All @@ -135,7 +137,13 @@ mod tests {
let url = mockito::server_url().to_string();
println!("Url: {}", url);
let http_adapter = HttpBenchAdapterBuilder::default()
.url(vec![format!("{}/1", url)])
.request(
HttpRequestBuilder::default()
.url(vec![format!("{}/1", url)])
.build()
.unwrap(),
)
.config(HttpClientConfigBuilder::default().build().unwrap())
.build()
.unwrap();

Expand Down Expand Up @@ -178,8 +186,11 @@ mod tests {

let stats = bench_result.unwrap();

assert_eq!(body.len() * request_count, stats.total_bytes);
assert_eq!(request_count, stats.total_requests);
assert_eq!(stats.summary.get("200 OK"), Some(&(request_count as i32)));
assert_eq!(body.len() * request_count, stats.combined.total_bytes);
assert_eq!(request_count, stats.combined.total_requests);
assert_eq!(
stats.combined.summary.get("200 OK"),
Some(&(request_count as i32))
);
}
}
4 changes: 2 additions & 2 deletions src/bench_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ impl Iterator for BenchSession {
for i in 0..self.concurrency {
let idx = i + self.current_iteration * self.concurrency;
items.push(if let Some(requests) = self.rate_ladder.step_requests {
BenchRun::with_request_limit(
BenchRun::from_request_limit(
idx,
requests,
RateLimiter::build_rate_limiter(rate_per_second),
)
} else if let Some(duration) = self.rate_ladder.step_duration {
BenchRun::with_duration_limit(
BenchRun::from_duration_limit(
idx,
duration,
RateLimiter::build_rate_limiter(rate_per_second),
Expand Down
40 changes: 26 additions & 14 deletions src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use crate::bench_session::{BenchSession, BenchSessionBuilder, RateLadder, RateLa
/// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
/// option. This file may not be copied, modified, or distributed
/// except according to those terms.
use crate::http_bench_session::{HttpBenchAdapter, HttpBenchAdapterBuilder};
use crate::http_bench_session::{
HttpBenchAdapter, HttpBenchAdapterBuilder, HttpClientConfigBuilder, HttpRequestBuilder,
};
use crate::metrics::{DefaultConsoleReporter, ExternalMetricsServiceReporter};
use clap::{clap_app, ArgMatches};
use core::fmt;
Expand Down Expand Up @@ -169,7 +171,7 @@ impl BenchmarkConfig {
panic!("Illegal Prometheus Gateway addr `{}`", prometheus_addr);
}
metrics_destinations.push(Arc::new(PrometheusReporter::new(
test_case_name.clone(),
test_case_name,
prometheus_addr.to_string(),
matches.value_of("PROMETHEUS_JOB"),
)));
Expand All @@ -187,19 +189,29 @@ impl BenchmarkConfig {
}

let http_config = HttpBenchAdapterBuilder::default()
.url(
config
.values_of("TARGET")
.expect("misconfiguration for TARGET")
.map(|s| s.to_string())
.collect(),
.config(
HttpClientConfigBuilder::default()
.ignore_cert(config.is_present("IGNORE_CERT"))
.conn_reuse(config.is_present("CONN_REUSE"))
.http2_only(config.is_present("HTTP2_ONLY"))
.build()
.expect("HttpClientConfigBuilder failed"),
)
.request(
HttpRequestBuilder::default()
.url(
config
.values_of("TARGET")
.expect("misconfiguration for TARGET")
.map(|s| s.to_string())
.collect(),
)
.method(config.value_of("METHOD").unwrap_or("GET").to_string())
.headers(BenchmarkConfig::get_multiple_values(config, "HEADER"))
.body(BenchmarkConfig::generate_body(config))
.build()
.expect("HttpRequestBuilder failed"),
)
.ignore_cert(config.is_present("IGNORE_CERT"))
.conn_reuse(config.is_present("CONN_REUSE"))
.http2_only(config.is_present("HTTP2_ONLY"))
.method(config.value_of("METHOD").unwrap_or("GET").to_string())
.headers(BenchmarkConfig::get_multiple_values(config, "HEADER"))
.body(BenchmarkConfig::generate_body(config))
.build()
.expect("BenchmarkModeBuilder failed");
BenchmarkMode::Http(http_config)
Expand Down
116 changes: 82 additions & 34 deletions src/http_bench_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,19 @@ use std::time::Instant;
use tokio_native_tls::TlsConnector;

#[derive(Builder, Deserialize, Clone, Debug)]
#[builder(build_fn(validate = "Self::validate"))]
pub struct HttpBenchAdapter {
url: Vec<String>,
pub struct HttpClientConfig {
#[builder(default)]
ignore_cert: bool,
#[builder(default)]
conn_reuse: bool,
#[builder(default)]
verbose: bool,
#[builder(default)]
http2_only: bool,
}

#[derive(Builder, Deserialize, Clone, Debug)]
#[builder(build_fn(validate = "Self::validate"))]
pub struct HttpRequest {
url: Vec<String>,
#[builder(default = "\"GET\".to_string()")]
method: String,
#[builder(default)]
Expand All @@ -46,6 +48,12 @@ pub struct HttpBenchAdapter {
body: Vec<u8>,
}

#[derive(Builder, Deserialize, Clone, Debug)]
pub struct HttpBenchAdapter {
config: HttpClientConfig,
request: HttpRequest,
}

#[cfg(feature = "tls")]
type ProtocolConnector = HttpsConnector<HttpConnector>;
#[cfg(not(feature = "tls"))]
Expand Down Expand Up @@ -73,7 +81,7 @@ impl HttpBenchAdapter {
#[cfg(feature = "tls-native")]
fn build_tls_connector(&self) -> TlsConnector {
let mut native_tls_builder = native_tls::TlsConnector::builder();
if self.ignore_cert {
if self.config.ignore_cert {
native_tls_builder.danger_accept_invalid_certs(true);
}

Expand All @@ -100,14 +108,18 @@ impl BenchmarkProtocolAdapter for HttpBenchAdapter {

fn build_client(&self) -> Result<Self::Client, String> {
Ok(hyper::Client::builder()
.http2_only(self.http2_only)
.pool_max_idle_per_host(if !self.conn_reuse { 0 } else { usize::MAX })
.http2_only(self.config.http2_only)
.pool_max_idle_per_host(if !self.config.conn_reuse {
0
} else {
usize::MAX
})
.build(self.build_connector()))
}

async fn send_request(&self, client: &Self::Client) -> RequestStats {
let start = Instant::now();
let request = self.build_request();
let request = self.request.build_request();
let response = client.request(request).await;

match response {
Expand Down Expand Up @@ -146,7 +158,7 @@ impl BenchmarkProtocolAdapter for HttpBenchAdapter {
}
}

impl HttpBenchAdapter {
impl HttpRequest {
fn build_request(&self) -> Request<Body> {
let method =
Method::from_str(&self.method.clone()).expect("Method must be valid at this point");
Expand Down Expand Up @@ -176,7 +188,7 @@ impl HttpBenchAdapter {
}
}

impl HttpBenchAdapterBuilder {
impl HttpRequestBuilder {
/// Validate request is going to be built from the given settings
fn validate(&self) -> Result<(), String> {
if let Some(ref m) = self.method {
Expand All @@ -190,7 +202,9 @@ impl HttpBenchAdapterBuilder {
#[cfg(test)]
mod tests {
use crate::bench_run::BenchmarkProtocolAdapter;
use crate::http_bench_session::{HttpBenchAdapter, HttpBenchAdapterBuilder};
use crate::http_bench_session::{
HttpBenchAdapter, HttpBenchAdapterBuilder, HttpClientConfigBuilder, HttpRequestBuilder,
};
use mockito::mock;
use mockito::Matcher::Exact;
use std::time::Duration;
Expand All @@ -211,11 +225,17 @@ mod tests {
let url = mockito::server_url().to_string();
println!("Url: {}", url);
let http_bench = HttpBenchAdapterBuilder::default()
.url(vec![format!("{}/1", url)])
.headers(vec![
("x-header".to_string(), "value1".to_string()),
("x-another-header".to_string(), "value2".to_string()),
])
.request(
HttpRequestBuilder::default()
.url(vec![format!("{}/1", url)])
.headers(vec![
("x-header".to_string(), "value1".to_string()),
("x-another-header".to_string(), "value2".to_string()),
])
.build()
.unwrap(),
)
.config(HttpClientConfigBuilder::default().build().unwrap())
.build()
.unwrap();

Expand Down Expand Up @@ -243,13 +263,19 @@ mod tests {
let url = mockito::server_url().to_string();
println!("Url: {}", url);
let http_bench = HttpBenchAdapterBuilder::default()
.url(vec![format!("{}/1", url)])
.method("PUT".to_string())
.headers(vec![
("x-header".to_string(), "value1".to_string()),
("x-another-header".to_string(), "value2".to_string()),
])
.body("abcd".as_bytes().to_vec())
.request(
HttpRequestBuilder::default()
.url(vec![format!("{}/1", url)])
.method("PUT".to_string())
.headers(vec![
("x-header".to_string(), "value1".to_string()),
("x-another-header".to_string(), "value2".to_string()),
])
.body("abcd".as_bytes().to_vec())
.build()
.unwrap(),
)
.config(HttpClientConfigBuilder::default().build().unwrap())
.build()
.unwrap();

Expand Down Expand Up @@ -277,13 +303,19 @@ mod tests {
let url = mockito::server_url().to_string();
println!("Url: {}", url);
let http_bench = HttpBenchAdapterBuilder::default()
.url(vec![format!("{}/1", url)])
.method("POST".to_string())
.headers(vec![
("x-header".to_string(), "value1".to_string()),
("x-another-header".to_string(), "value2".to_string()),
])
.body("abcd".as_bytes().to_vec())
.request(
HttpRequestBuilder::default()
.url(vec![format!("{}/1", url)])
.method("POST".to_string())
.headers(vec![
("x-header".to_string(), "value1".to_string()),
("x-another-header".to_string(), "value2".to_string()),
])
.body("abcd".as_bytes().to_vec())
.build()
.unwrap(),
)
.config(HttpClientConfigBuilder::default().build().unwrap())
.build()
.unwrap();

Expand All @@ -308,7 +340,13 @@ mod tests {
let url = mockito::server_url().to_string();
println!("Url: {}", url);
let http_bench = HttpBenchAdapterBuilder::default()
.url(vec![format!("{}/1", url)])
.request(
HttpRequestBuilder::default()
.url(vec![format!("{}/1", url)])
.build()
.unwrap(),
)
.config(HttpClientConfigBuilder::default().build().unwrap())
.build()
.unwrap();

Expand All @@ -333,8 +371,18 @@ mod tests {
let url = mockito::server_url().to_string();
println!("Url: {}", url);
let http_bench: HttpBenchAdapter = HttpBenchAdapterBuilder::default()
.url(vec![format!("{}/1", url)])
.http2_only(true)
.request(
HttpRequestBuilder::default()
.url(vec![format!("{}/1", url)])
.build()
.unwrap(),
)
.config(
HttpClientConfigBuilder::default()
.http2_only(true)
.build()
.unwrap(),
)
.build()
.unwrap();

Expand Down
Loading

0 comments on commit ea45ab6

Please sign in to comment.