use super::{TestScenario, TestResult, TestMetrics};
use anyhow::Result;
use std::fmt;
pub struct TestHarness {
scenarios: Vec<Box<dyn TestScenario>>,
test_nodes: Vec<TestNode>,
}
impl fmt::Debug for TestHarness {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TestHarness")
.field("scenarios_count", &self.scenarios.len())
.field("test_nodes", &self.test_nodes)
.finish()
}
}
#[derive(Debug)]
pub struct TestNode {
#[allow(dead_code)]
pub id: String,
#[allow(dead_code)]
pub address: String,
}
impl TestHarness {
pub fn new() -> Self {
Self {
scenarios: Vec::new(),
test_nodes: Vec::new(),
}
}
pub fn add_scenario(&mut self, scenario: Box<dyn TestScenario>) {
self.scenarios.push(scenario);
}
pub async fn spawn_nodes(&mut self, count: usize) -> Result<()> {
for i in 0..count {
let node = TestNode {
id: format!("test-node-{}", i),
address: format!("test-{}-{}-{}", i, i, i),
};
self.test_nodes.push(node);
}
Ok(())
}
pub async fn run_all(&mut self) -> Result<Vec<TestResult>> {
let mut results = Vec::new();
for scenario in &mut self.scenarios {
println!("Running scenario: {}", scenario.name());
scenario.setup()?;
let start = std::time::Instant::now();
let result = match scenario.execute() {
Ok(mut result) => {
result.duration_ms = start.elapsed().as_millis() as u64;
result
}
Err(e) => TestResult {
passed: false,
duration_ms: start.elapsed().as_millis() as u64,
error: Some(e.to_string()),
metrics: TestMetrics::default(),
}
};
let _ = scenario.teardown();
results.push(result);
}
Ok(results)
}
}