pub mod consistency;
pub mod partition;
pub mod raft;
pub mod sla;
pub use consistency::certify as run_consistency;
pub use partition::certify as run_partition;
pub use raft::certify as run_raft;
pub use sla::certify as run_sla;
#[derive(Debug, Clone)]
pub struct CertificationConfig {
pub node_count: usize,
pub partition_fraction: f64,
pub sla_read_latency_us: u64,
pub sla_write_latency_us: u64,
pub epochs: usize,
}
impl Default for CertificationConfig {
fn default() -> Self {
CertificationConfig {
node_count: 5,
partition_fraction: 0.4,
sla_read_latency_us: 1_000,
sla_write_latency_us: 5_000,
epochs: 50,
}
}
}
#[derive(Debug, Clone)]
pub struct CheckResult {
pub name: String,
pub passed: bool,
pub detail: String,
}
#[derive(Debug, Clone)]
pub struct ConsistencyResult {
pub passed: bool,
pub checks: Vec<CheckResult>,
pub notes: String,
}
#[derive(Debug, Clone)]
pub struct PartitionResult {
pub passed: bool,
pub checks: Vec<CheckResult>,
pub notes: String,
}
#[derive(Debug, Clone)]
pub struct RaftResult {
pub passed: bool,
pub checks: Vec<CheckResult>,
pub notes: String,
}
#[derive(Debug, Clone)]
pub struct SlaResult {
pub passed: bool,
pub checks: Vec<CheckResult>,
pub notes: String,
}
#[derive(Debug, Clone)]
pub struct CertificationReport {
pub passed: bool,
pub consistency_result: ConsistencyResult,
pub partition_result: PartitionResult,
pub raft_result: RaftResult,
pub sla_result: SlaResult,
pub summary: String,
}
pub struct CertificationSuite {
config: CertificationConfig,
}
impl CertificationSuite {
pub fn new(config: CertificationConfig) -> Self {
CertificationSuite { config }
}
pub fn run(&self) -> CertificationReport {
let consistency_result = consistency::certify(&self.config);
let partition_result = partition::certify(&self.config);
let raft_result = raft::certify(&self.config);
let sla_result = sla::certify(&self.config);
let passed = consistency_result.passed
&& partition_result.passed
&& raft_result.passed
&& sla_result.passed;
let summary = build_summary(
passed,
&consistency_result,
&partition_result,
&raft_result,
&sla_result,
);
CertificationReport {
passed,
consistency_result,
partition_result,
raft_result,
sla_result,
summary,
}
}
}
fn build_summary(
passed: bool,
c: &ConsistencyResult,
p: &PartitionResult,
r: &RaftResult,
s: &SlaResult,
) -> String {
let status = if passed { "PASS" } else { "FAIL" };
let mut parts: Vec<String> = Vec::new();
for (label, result_passed) in [
("consistency", c.passed),
("partition", p.passed),
("raft", r.passed),
("sla", s.passed),
] {
let marker = if result_passed { "[+]" } else { "[-]" };
parts.push(format!("{marker} {label}"));
}
format!("[{status}] Certification: {}", parts.join(" "))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config_fields() {
let cfg = CertificationConfig::default();
assert_eq!(cfg.node_count, 5);
assert!((cfg.partition_fraction - 0.4).abs() < 1e-9);
assert_eq!(cfg.sla_read_latency_us, 1_000);
assert_eq!(cfg.sla_write_latency_us, 5_000);
assert_eq!(cfg.epochs, 50);
}
#[test]
fn test_suite_new_does_not_panic() {
let _suite = CertificationSuite::new(CertificationConfig::default());
}
#[test]
fn test_run_returns_report() {
let suite = CertificationSuite::new(CertificationConfig::default());
let report = suite.run();
assert!(!report.summary.is_empty());
}
#[test]
fn test_report_summary_contains_status() {
let suite = CertificationSuite::new(CertificationConfig::default());
let report = suite.run();
assert!(
report.summary.contains("PASS") || report.summary.contains("FAIL"),
"Summary should contain PASS or FAIL: {}",
report.summary
);
}
#[test]
fn test_report_passed_flag() {
let suite = CertificationSuite::new(CertificationConfig::default());
let report = suite.run();
let all_pass = report.consistency_result.passed
&& report.partition_result.passed
&& report.raft_result.passed
&& report.sla_result.passed;
assert_eq!(report.passed, all_pass);
}
#[test]
fn test_build_summary_all_pass() {
let c = ConsistencyResult {
passed: true,
checks: vec![],
notes: String::new(),
};
let p = PartitionResult {
passed: true,
checks: vec![],
notes: String::new(),
};
let r = RaftResult {
passed: true,
checks: vec![],
notes: String::new(),
};
let s = SlaResult {
passed: true,
checks: vec![],
notes: String::new(),
};
let summary = build_summary(true, &c, &p, &r, &s);
assert!(summary.contains("PASS"), "Expected PASS in: {summary}");
}
#[test]
fn test_build_summary_with_failure() {
let c = ConsistencyResult {
passed: false,
checks: vec![],
notes: String::new(),
};
let p = PartitionResult {
passed: true,
checks: vec![],
notes: String::new(),
};
let r = RaftResult {
passed: true,
checks: vec![],
notes: String::new(),
};
let s = SlaResult {
passed: true,
checks: vec![],
notes: String::new(),
};
let summary = build_summary(false, &c, &p, &r, &s);
assert!(summary.contains("FAIL"), "Expected FAIL in: {summary}");
}
}