blob: c552d86603fc0bec6113aeae98d0f7846564bcd9 [file]
use super::kind::BenchmarkKindCommand;
use super::props::{BenchmarkKindProps, BenchmarkTransportProps};
use super::{defaults::*, transport::BenchmarkTransportCommand};
use clap::error::ErrorKind;
use clap::{CommandFactory, Parser};
use iggy::utils::duration::IggyDuration;
use integration::test_server::Transport;
use std::net::SocketAddr;
use std::path::Path;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct IggyBenchArgs {
/// Benchmark kind
#[command(subcommand)]
pub benchmark_kind: BenchmarkKindCommand,
/// iggy-server executable path
#[arg(long, short='e', default_value = None, value_parser = validate_server_executable_path)]
pub server_executable_path: Option<String>,
/// Shutdown iggy-server and remove server local_data directory after the benchmark is finished
#[arg(long, short='c', default_value_t = DEFAULT_PERFORM_CLEANUP)]
pub cleanup: bool,
/// Server local data directory path, if not provided a temporary directory will be created
#[arg(long, short='s', default_value_t = DEFAULT_SERVER_SYSTEM_PATH.to_owned())]
pub server_system_path: String,
/// Server stdout visibility
#[arg(long, short='v', default_value_t = DEFAULT_SERVER_STDOUT_VISIBILITY)]
pub verbose: bool,
/// Warmup time
#[arg(long, short = 'w', default_value_t = IggyDuration::from(DEFAULT_WARMUP_TIME_SECONDS))]
pub warmup_time: IggyDuration,
/// Skip server start
#[arg(long, short = 'k', default_value_t = DEFAULT_SKIP_SERVER_START)]
pub skip_server_start: bool,
}
fn validate_server_executable_path(v: &str) -> Result<String, String> {
if Path::new(v).exists() {
Ok(v.to_owned())
} else {
Err(format!("Provided server executable '{v}' does not exist."))
}
}
impl IggyBenchArgs {
pub fn transport_command(&self) -> &BenchmarkTransportCommand {
self.benchmark_kind.transport_command()
}
pub fn transport(&self) -> &Transport {
self.benchmark_kind.transport_command().transport()
}
pub fn server_address(&self) -> &str {
self.benchmark_kind
.inner()
.transport_command()
.server_address()
}
pub fn start_stream_id(&self) -> u32 {
self.benchmark_kind.transport_command().start_stream_id()
}
pub fn validate(&self) {
let server_address = self.server_address().parse::<SocketAddr>().unwrap();
if (self.cleanup || self.verbose) && !server_address.ip().is_loopback() {
IggyBenchArgs::command()
.error(
ErrorKind::ArgumentConflict,
format!(
"Cannot use cleanup or verbose flags with a non-loopback server address: {}",
self.server_address()
),
)
.exit();
}
self.benchmark_kind.inner().validate()
}
pub fn messages_per_batch(&self) -> u32 {
self.benchmark_kind.inner().messages_per_batch()
}
pub fn message_batches(&self) -> u32 {
self.benchmark_kind.inner().message_batches()
}
pub fn message_size(&self) -> u32 {
self.benchmark_kind.inner().message_size()
}
pub fn number_of_streams(&self) -> u32 {
self.benchmark_kind.inner().number_of_streams()
}
pub fn consumers(&self) -> u32 {
self.benchmark_kind.inner().consumers()
}
pub fn producers(&self) -> u32 {
self.benchmark_kind.inner().producers()
}
pub fn disable_parallel_producer_streams(&self) -> bool {
self.benchmark_kind
.inner()
.disable_parallel_producer_streams()
}
pub fn disable_parallel_consumer_streams(&self) -> bool {
self.benchmark_kind
.inner()
.disable_parallel_consumer_streams()
}
pub fn warmup_time(&self) -> IggyDuration {
self.warmup_time
}
}