use anyhow::Result;
use std::sync::Arc;
use tokio::sync::RwLock;
pub mod config;
pub mod generators;
pub mod metrics;
pub mod protocols;
pub mod reporter;
pub mod scenarios;
pub mod workload;
pub use config::LoadTestConfig;
pub use metrics::{LatencyStats, LoadTestMetrics};
pub use scenarios::{LoadTestScenario, ScenarioRunner};
pub struct LoadTester {
config: LoadTestConfig,
metrics: Arc<RwLock<LoadTestMetrics>>,
}
impl LoadTester {
pub fn new(config: LoadTestConfig) -> Self {
Self {
config,
metrics: Arc::new(RwLock::new(LoadTestMetrics::new())),
}
}
pub async fn run(&self) -> Result<LoadTestMetrics> {
tracing::info!("Starting load test with config: {:?}", self.config);
let scenario = self.config.scenario.create_runner(&self.config);
scenario.run(self.metrics.clone()).await?;
let final_metrics = self.metrics.read().await.clone();
Ok(final_metrics)
}
pub async fn get_metrics(&self) -> LoadTestMetrics {
self.metrics.read().await.clone()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_loadtester_creation() {
let config = LoadTestConfig::default();
let tester = LoadTester::new(config);
assert!(Arc::strong_count(&tester.metrics) >= 1);
}
#[tokio::test]
async fn test_loadtester_metrics() {
let config = LoadTestConfig::default();
let tester = LoadTester::new(config);
let metrics = tester.get_metrics().await;
assert_eq!(metrics.total_requests, 0);
}
}