-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add rewrk core * Add tests and public interface * Update CI * Update docs * Add timed variants * Reformat * Adjust buffer * Clippy
- Loading branch information
1 parent
9c20f0c
commit d811b98
Showing
24 changed files
with
2,212 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/target | ||
/assets | ||
/.github |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,25 @@ | ||
FROM chillfish8/rust-builder:latest as builder | ||
FROM rust:slim-buster as build | ||
|
||
WORKDIR /home/rust/ | ||
WORKDIR /code | ||
|
||
# Avoid having to install/build all dependencies by copying | ||
# the Cargo files and making a dummy src/main.rs | ||
COPY . . | ||
RUN cargo build --release --target x86_64-unknown-linux-musl | ||
COPY . /code | ||
|
||
# Size optimization | ||
RUN strip target/x86_64-unknown-linux-musl/release/rewrk | ||
RUN apt-get update \ | ||
&& apt-get install -y libssl-dev pkg-config \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
|
||
RUN cargo build --release | ||
|
||
# Copy the binary into a new container for a smaller docker image | ||
FROM debian:buster-slim | ||
|
||
# Start building the final image | ||
FROM scratch | ||
WORKDIR /etc/rewrk | ||
|
||
COPY --from=builder /home/rust/target/x86_64-unknown-linux-musl/release/rewrk . | ||
ENTRYPOINT ["./rewrk"] | ||
USER root | ||
RUN apt-get update \ | ||
&& apt-get install -y ca-certificates \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
|
||
COPY --from=build /code/target/release/rewrk . | ||
|
||
ENTRYPOINT ["./rewrk"] |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
[package] | ||
name = "rewrk-core" | ||
version = "0.1.0" | ||
edition = "2021" | ||
description = "HTTP benchmarking as a library made simple." | ||
license = "MIT" | ||
readme = "README.md" | ||
repository = "https://github.com/lnx-search/rewrk" | ||
keywords = ["tokio", "async"] | ||
categories = ["concurrency", "asynchronous"] | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
anyhow = "1" | ||
futures-util = "0.3" | ||
http = "0.2" | ||
pin-project-lite = "0.2" | ||
flume = "0.10.14" | ||
hdrhistogram = "7" | ||
thiserror = "1" | ||
async-trait = "0.1.64" | ||
tracing = "0.1.37" | ||
num_cpus = "1.15.0" | ||
|
||
hyper = { version = "0.14", features = ["runtime", "client", "http1", "http2"] } | ||
native-tls = { version = "0.2", features = ["alpn"] } | ||
tokio = { version = "1", features = ["rt", "rt-multi-thread", "net"] } | ||
tokio-native-tls = "0.3" | ||
tower = { version = "0.4", features = ["util"] } | ||
|
||
[dev-dependencies] | ||
axum = "0.6.5" | ||
tracing-subscriber = "0.3.16" | ||
|
||
tokio = { version = "1", features = ["full"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# ReWrk Core | ||
HTTP benchmarking as a library made simple. | ||
|
||
ReWrk Core is a easily configurable and extendable framework for benchmarking | ||
HTTP servers providing things like response validation, custom result collectors and | ||
custom request producers. | ||
|
||
It measures some of the key metrics like latency, write IO and read IO and provides you | ||
with a way of grouping results together with the concept of `tags`. | ||
|
||
```rust | ||
use axum::routing::get; | ||
use axum::Router; | ||
use anyhow::Result; | ||
use http::{Method, Request, Uri}; | ||
use hyper::Body; | ||
use rewrk_core::{ | ||
Batch, | ||
HttpProtocol, | ||
Producer, | ||
ReWrkBenchmark, | ||
RequestBatch, | ||
Sample, | ||
SampleCollector, | ||
}; | ||
|
||
static ADDR: &str = "127.0.0.1:8080"; | ||
|
||
#[tokio::test] | ||
async fn test_basic_benchmark() -> Result<()> { | ||
tracing_subscriber::fmt::try_init()?; | ||
|
||
tokio::spawn(run_server()); | ||
|
||
let uri = Uri::builder() | ||
.scheme("http") | ||
.authority(ADDR) | ||
.path_and_query("/") | ||
.build()?; | ||
|
||
let mut benchmarker = ReWrkBenchmark::create( | ||
uri, | ||
1, | ||
HttpProtocol::HTTP1, | ||
BasicProducer::default(), | ||
BasicCollector::default(), | ||
) | ||
.await?; | ||
benchmarker.set_num_workers(1); | ||
benchmarker.run().await; | ||
|
||
let mut collector = benchmarker.consume_collector().await; | ||
let sample = collector.samples.remove(0); | ||
assert_eq!(sample.tag(), 0); | ||
assert_eq!(sample.latency().len(), 1); | ||
assert_eq!(sample.read_transfer().len(), 1); | ||
assert_eq!(sample.write_transfer().len(), 1); | ||
} | ||
|
||
async fn run_server() { | ||
// build our application with a single route | ||
let app = Router::new().route("/", get(|| async { "Hello, World!" })); | ||
|
||
axum::Server::bind(&ADDR.parse().unwrap()) | ||
.serve(app.into_make_service()) | ||
.await | ||
.unwrap(); | ||
} | ||
|
||
#[derive(Default, Clone)] | ||
pub struct BasicProducer { | ||
count: usize, | ||
} | ||
|
||
#[rewrk_core::async_trait] | ||
impl Producer for BasicProducer { | ||
fn ready(&mut self) { | ||
self.count = 1; | ||
} | ||
|
||
async fn create_batch(&mut self) -> Result<RequestBatch> { | ||
if self.count > 0 { | ||
self.count -= 1; | ||
|
||
let uri = Uri::builder().path_and_query("/").build()?; | ||
let request = Request::builder() | ||
.method(Method::GET) | ||
.uri(uri) | ||
.body(Body::empty())?; | ||
Ok(RequestBatch::Batch(Batch { | ||
tag: 0, | ||
requests: vec![request], | ||
})) | ||
} else { | ||
Ok(RequestBatch::End) | ||
} | ||
} | ||
} | ||
|
||
#[derive(Default)] | ||
pub struct BasicCollector { | ||
samples: Vec<Sample>, | ||
} | ||
|
||
#[rewrk_core::async_trait] | ||
impl SampleCollector for BasicCollector { | ||
async fn process_sample(&mut self, sample: Sample) -> Result<()> { | ||
self.samples.push(sample); | ||
Ok(()) | ||
} | ||
} | ||
``` |
Oops, something went wrong.