mirror of
https://github.com/kristoferssolo/tls-pq-bench.git
synced 2026-03-21 16:26:22 +00:00
feat(runner): add protocol mode to CLI and benchmark config
This commit is contained in:
@@ -43,22 +43,23 @@ cargo build --release
|
||||
Terminal 1 - Start server:
|
||||
|
||||
```bash
|
||||
./target/release/server --mode x25519 --listen 127.0.0.1:4433
|
||||
./target/release/server --mode x25519 --proto raw --listen 127.0.0.1:4433
|
||||
```
|
||||
|
||||
Terminal 2 - Run benchmark:
|
||||
|
||||
```bash
|
||||
./target/release/runner --server 127.0.0.1:4433 --mode x25519 --iters 100 --warmup 10
|
||||
./target/release/runner --server 127.0.0.1:4433 --proto raw --mode x25519 --iters 100 --warmup 10
|
||||
```
|
||||
|
||||
### Run Matrix Benchmarks
|
||||
|
||||
Create a config file (`matrix.toml`):
|
||||
Create a config file (`benchmarks.toml`):
|
||||
|
||||
```toml
|
||||
[[benchmarks]]
|
||||
server = "127.0.0.1:4433"
|
||||
proto = "raw"
|
||||
mode = "x25519"
|
||||
payload = 1024
|
||||
iters = 100
|
||||
@@ -67,6 +68,7 @@ concurrency = 1
|
||||
|
||||
[[benchmarks]]
|
||||
server = "127.0.0.1:4433"
|
||||
proto = "http1"
|
||||
mode = "x25519mlkem768"
|
||||
payload = 1024
|
||||
iters = 100
|
||||
|
||||
@@ -6,7 +6,11 @@ use std::{net::SocketAddr, path::PathBuf};
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(name = "runner", version, about)]
|
||||
pub struct Args {
|
||||
/// Key exchange mode.
|
||||
/// Protocol carrier mode
|
||||
#[arg(long, default_value = "raw")]
|
||||
pub proto: ProtocolMode,
|
||||
|
||||
/// Key exchange mode
|
||||
#[arg(long, default_value = "x25519")]
|
||||
pub mode: KeyExchangeMode,
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ use std::{fs::read_to_string, net::SocketAddr, path::Path};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct BenchmarkConfig {
|
||||
pub proto: ProtocolMode,
|
||||
pub mode: KeyExchangeMode,
|
||||
pub payload: u32,
|
||||
pub iters: u32,
|
||||
@@ -29,48 +30,57 @@ pub struct Config {
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns an error if the file cannot be read or parsed.
|
||||
pub fn load_from_file(path: &Path) -> error::Result<Config> {
|
||||
let content = read_to_string(path).map_err(|source| ConfigError::ReadError {
|
||||
source,
|
||||
path: path.to_owned(),
|
||||
})?;
|
||||
impl TryFrom<&Path> for Config {
|
||||
type Error = error::Error;
|
||||
|
||||
let src = NamedSource::new(path.display().to_string(), content.clone());
|
||||
|
||||
let config = toml::from_str::<Config>(&content).map_err(|source| {
|
||||
let span = source
|
||||
.span()
|
||||
.map(|s| SourceSpan::new(s.start.into(), s.end - s.start));
|
||||
|
||||
ConfigError::TomlParseError {
|
||||
src: src.clone(),
|
||||
span,
|
||||
fn try_from(path: &Path) -> Result<Self, Self::Error> {
|
||||
let content = read_to_string(path).map_err(|source| ConfigError::ReadError {
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
path: path.to_owned(),
|
||||
})?;
|
||||
|
||||
validate_config(&config, &content, path)?;
|
||||
let src = NamedSource::new(path.display().to_string(), content.clone());
|
||||
|
||||
Ok(config)
|
||||
let config = toml::from_str::<Self>(&content).map_err(|source| {
|
||||
let span = source
|
||||
.span()
|
||||
.map(|s| SourceSpan::new(s.start.into(), s.end - s.start));
|
||||
|
||||
ConfigError::TomlParseError {
|
||||
src: src.clone(),
|
||||
span,
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
|
||||
validate_config(&config, &content, path)?;
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create benchmark configuration from CLI arguments.
|
||||
///
|
||||
/// # Errors
|
||||
/// Never returns an error, but returns Result for consistency.
|
||||
pub fn load_from_cli(args: &Args) -> error::Result<Config> {
|
||||
Ok(Config {
|
||||
benchmarks: vec![BenchmarkConfig {
|
||||
mode: args.mode,
|
||||
payload: args.payload_bytes,
|
||||
iters: args.iters,
|
||||
warmup: args.warmup,
|
||||
concurrency: args.concurrency,
|
||||
server: args
|
||||
.server
|
||||
.ok_or_else(|| common::Error::config("--server ir required"))?,
|
||||
}],
|
||||
})
|
||||
/// Returns an error if `--server` was not provided.
|
||||
impl TryFrom<Args> for Config {
|
||||
type Error = error::Error;
|
||||
|
||||
fn try_from(args: Args) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
benchmarks: vec![BenchmarkConfig {
|
||||
proto: args.proto,
|
||||
mode: args.mode,
|
||||
payload: args.payload_bytes,
|
||||
iters: args.iters,
|
||||
warmup: args.warmup,
|
||||
concurrency: args.concurrency,
|
||||
server: args
|
||||
.server
|
||||
.ok_or_else(|| common::Error::config("--server is required"))?,
|
||||
}],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -80,6 +90,7 @@ mod tests {
|
||||
|
||||
const VALID_CONFIG: &str = r#"
|
||||
[[benchmarks]]
|
||||
proto = "raw"
|
||||
mode = "x25519"
|
||||
payload = 1024
|
||||
iters = 100
|
||||
@@ -88,6 +99,7 @@ concurrency = 1
|
||||
server = "127.0.0.1:4433"
|
||||
|
||||
[[benchmarks]]
|
||||
proto = "http1"
|
||||
mode = "x25519mlkem768"
|
||||
payload = 4096
|
||||
iters = 50
|
||||
@@ -104,6 +116,7 @@ server = "127.0.0.1:4433"
|
||||
fn valid_single_benchmark() {
|
||||
let toml = r#"
|
||||
[[benchmarks]]
|
||||
proto = "raw"
|
||||
mode = "x25519"
|
||||
payload = 1024
|
||||
iters = 100
|
||||
@@ -125,10 +138,26 @@ server = "127.0.0.1:4433"
|
||||
assert_eq!(config.benchmarks[1].mode, KeyExchangeMode::X25519Mlkem768);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_proto() {
|
||||
let toml = r#"
|
||||
[[benchmarks]]
|
||||
proto = "invalid_proto"
|
||||
mode = "x25519"
|
||||
payload = 1024
|
||||
iters = 100
|
||||
warmup = 10
|
||||
concurrency = 1
|
||||
server = "127.0.0.1:4433"
|
||||
"#;
|
||||
assert_err!(toml::from_str::<Config>(toml));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_mode() {
|
||||
let toml = r#"
|
||||
[[benchmarks]]
|
||||
proto = "raw"
|
||||
mode = "invalid_mode"
|
||||
payload = 1024
|
||||
iters = 100
|
||||
@@ -143,6 +172,7 @@ server = "127.0.0.1:4433"
|
||||
fn payload_zero_validation() {
|
||||
let toml = r#"
|
||||
[[benchmarks]]
|
||||
proto = "raw"
|
||||
mode = "x25519"
|
||||
payload = 0
|
||||
iters = 100
|
||||
@@ -158,6 +188,7 @@ server = "127.0.0.1:4433"
|
||||
fn iters_zero_validation() {
|
||||
let toml = r#"
|
||||
[[benchmarks]]
|
||||
proto = "raw"
|
||||
mode = "x25519"
|
||||
payload = 1024
|
||||
iters = 0
|
||||
@@ -173,6 +204,7 @@ server = "127.0.0.1:4433"
|
||||
fn concurrency_zero_validation() {
|
||||
let toml = r#"
|
||||
[[benchmarks]]
|
||||
proto = "raw"
|
||||
mode = "x25519"
|
||||
payload = 1024
|
||||
iters = 100
|
||||
@@ -195,6 +227,7 @@ server = "127.0.0.1:4433"
|
||||
fn server_mode_fallback() {
|
||||
let toml = r#"
|
||||
[[benchmarks]]
|
||||
proto = "raw"
|
||||
mode = "x25519"
|
||||
payload = 1024
|
||||
iters = 100
|
||||
@@ -211,6 +244,7 @@ server = "127.0.0.1:4433"
|
||||
fn server_mode_mlkem() {
|
||||
let toml = r#"
|
||||
[[benchmarks]]
|
||||
proto = "raw"
|
||||
mode = "x25519mlkem768"
|
||||
payload = 1024
|
||||
iters = 100
|
||||
|
||||
@@ -12,12 +12,7 @@ mod config;
|
||||
mod error;
|
||||
mod tls;
|
||||
|
||||
use crate::{
|
||||
args::Args,
|
||||
bench::run_benchmark,
|
||||
config::{load_from_cli, load_from_file},
|
||||
tls::build_tls_config,
|
||||
};
|
||||
use crate::{args::Args, bench::run_benchmark, config::Config, tls::build_tls_config};
|
||||
use clap::Parser;
|
||||
use miette::{Context, IntoDiagnostic};
|
||||
use rustls::pki_types::ServerName;
|
||||
@@ -47,12 +42,12 @@ async fn main() -> miette::Result<()> {
|
||||
|
||||
let args = Args::parse();
|
||||
|
||||
let config = if let Some(config_path) = &args.config {
|
||||
let config: Config = if let Some(config_path) = &args.config {
|
||||
info!(config_file = %config_path.display(), "loading config from file");
|
||||
load_from_file(config_path)?
|
||||
config_path.as_path().try_into()?
|
||||
} else {
|
||||
info!("using CLI arguments");
|
||||
load_from_cli(&args)?
|
||||
args.try_into()?
|
||||
};
|
||||
|
||||
let server_name = ServerName::try_from("localhost".to_string())
|
||||
@@ -61,6 +56,7 @@ async fn main() -> miette::Result<()> {
|
||||
|
||||
for benchmark in &config.benchmarks {
|
||||
info!(
|
||||
proto = %benchmark.proto,
|
||||
mode = %benchmark.mode,
|
||||
payload = benchmark.payload,
|
||||
iters = benchmark.iters,
|
||||
|
||||
@@ -24,7 +24,7 @@ struct Args {
|
||||
#[arg(long, default_value = "x25519")]
|
||||
mode: KeyExchangeMode,
|
||||
|
||||
/// Protocol carrier
|
||||
/// Protocol carrier mode
|
||||
#[arg(long, default_value = "raw")]
|
||||
proto: ProtocolMode,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user