use parlov_core::ProbeDefinition;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum RiskLevel {
Safe,
MethodDestructive,
OperationDestructive,
}
#[derive(Debug, Clone)]
pub struct StrategyMetadata {
pub strategy_id: &'static str,
pub strategy_name: &'static str,
pub risk: RiskLevel,
}
#[derive(Debug, Clone)]
pub struct ProbePair {
pub baseline: ProbeDefinition,
pub probe: ProbeDefinition,
pub metadata: StrategyMetadata,
}
#[derive(Debug, Clone)]
pub struct BurstSpec {
pub baseline: ProbeDefinition,
pub probe: ProbeDefinition,
pub burst_count: usize,
pub metadata: StrategyMetadata,
}
#[derive(Debug, Clone)]
pub enum ProbeSpec {
Pair(ProbePair),
Burst(BurstSpec),
HeaderDiff(ProbePair),
}
#[cfg(test)]
mod tests {
use super::*;
use http::{HeaderMap, Method};
fn make_probe_def(url: &str, method: Method) -> ProbeDefinition {
ProbeDefinition {
url: url.to_owned(),
method,
headers: HeaderMap::new(),
body: None,
}
}
fn make_metadata() -> StrategyMetadata {
StrategyMetadata {
strategy_id: "test-strategy",
strategy_name: "Test Strategy",
risk: RiskLevel::Safe,
}
}
#[test]
fn risk_level_safe_less_than_method_destructive() {
assert!(RiskLevel::Safe < RiskLevel::MethodDestructive);
}
#[test]
fn risk_level_method_destructive_less_than_operation_destructive() {
assert!(RiskLevel::MethodDestructive < RiskLevel::OperationDestructive);
}
#[test]
fn risk_level_safe_less_than_operation_destructive() {
assert!(RiskLevel::Safe < RiskLevel::OperationDestructive);
}
#[test]
fn risk_level_method_destructive_roundtrip() {
let original = RiskLevel::MethodDestructive;
let json = serde_json::to_string(&original).expect("serialize failed");
let deserialized: RiskLevel = serde_json::from_str(&json).expect("deserialize failed");
assert_eq!(deserialized, original);
}
#[test]
fn strategy_metadata_fields_accessible() {
let m = make_metadata();
assert_eq!(m.strategy_id, "test-strategy");
assert_eq!(m.strategy_name, "Test Strategy");
assert_eq!(m.risk, RiskLevel::Safe);
}
#[test]
fn probe_pair_fields_accessible() {
let pair = ProbePair {
baseline: make_probe_def("https://example.com/1", Method::GET),
probe: make_probe_def("https://example.com/999", Method::GET),
metadata: make_metadata(),
};
assert_eq!(pair.baseline.url, "https://example.com/1");
assert_eq!(pair.probe.url, "https://example.com/999");
assert_eq!(pair.metadata.risk, RiskLevel::Safe);
}
#[test]
fn burst_spec_fields_accessible() {
let burst = BurstSpec {
baseline: make_probe_def("https://example.com/1", Method::GET),
probe: make_probe_def("https://example.com/999", Method::GET),
burst_count: 30,
metadata: make_metadata(),
};
assert_eq!(burst.burst_count, 30);
}
#[test]
fn probe_spec_pair_variant_accessible() {
let spec = ProbeSpec::Pair(ProbePair {
baseline: make_probe_def("https://example.com/1", Method::GET),
probe: make_probe_def("https://example.com/999", Method::GET),
metadata: make_metadata(),
});
assert!(matches!(spec, ProbeSpec::Pair(_)));
}
#[test]
fn probe_spec_burst_variant_accessible() {
let spec = ProbeSpec::Burst(BurstSpec {
baseline: make_probe_def("https://example.com/1", Method::GET),
probe: make_probe_def("https://example.com/999", Method::GET),
burst_count: 30,
metadata: make_metadata(),
});
assert!(matches!(spec, ProbeSpec::Burst(_)));
}
#[test]
fn probe_spec_header_diff_variant_accessible() {
let spec = ProbeSpec::HeaderDiff(ProbePair {
baseline: make_probe_def("https://example.com/1", Method::GET),
probe: make_probe_def("https://example.com/999", Method::GET),
metadata: make_metadata(),
});
assert!(matches!(spec, ProbeSpec::HeaderDiff(_)));
}
}