#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ProofDimension {
Measured(f64),
NotMeasured,
}
impl ProofDimension {
pub fn value(&self) -> Option<f64> {
match self {
Self::Measured(v) => Some(*v),
Self::NotMeasured => None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct ExpectedConformance {
pub fitness: f64,
pub precision: f64,
pub receipt_coverage: f64,
pub required_stage_coverage: f64,
pub object_lifecycle_validity: f64,
}
impl ExpectedConformance {
pub const fn exact() -> Self {
Self {
fitness: 1.0,
precision: 1.0,
receipt_coverage: 1.0,
required_stage_coverage: 1.0,
object_lifecycle_validity: 1.0,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct ReplayReport {
pub fitness: ProofDimension,
pub precision: ProofDimension,
pub receipt_coverage: ProofDimension,
pub required_stage_coverage: ProofDimension,
pub object_lifecycle_validity: ProofDimension,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AndonPull {
RouteConformanceGap,
IllegalRouteMotion,
MissingReceiptCoverage,
MissingRouteActivity,
ObjectLifecycleViolation,
UnexpectedAuthority,
UnhandledPanic,
TestRouteIncomplete,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AndonPolicy {
PullLine,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ConformanceVerdict {
Passed,
Andon(AndonPull),
}
impl ConformanceVerdict {
pub const fn passed() -> Self {
Self::Passed
}
pub const fn andon(reason: AndonPull) -> Self {
Self::Andon(reason)
}
pub const fn is_passed(&self) -> bool {
matches!(self, Self::Passed)
}
}
pub fn classify_conformance(
report: &ReplayReport,
expected: ExpectedConformance,
) -> ConformanceVerdict {
macro_rules! check {
($dim:expr, $threshold:expr, $andon:expr) => {
match $dim {
ProofDimension::NotMeasured => {
return ConformanceVerdict::andon(AndonPull::TestRouteIncomplete);
}
ProofDimension::Measured(v) if v < $threshold => {
return ConformanceVerdict::andon($andon);
}
_ => {}
}
};
}
check!(
report.fitness,
expected.fitness,
AndonPull::RouteConformanceGap
);
check!(
report.precision,
expected.precision,
AndonPull::IllegalRouteMotion
);
check!(
report.receipt_coverage,
expected.receipt_coverage,
AndonPull::MissingReceiptCoverage
);
check!(
report.required_stage_coverage,
expected.required_stage_coverage,
AndonPull::MissingRouteActivity
);
check!(
report.object_lifecycle_validity,
expected.object_lifecycle_validity,
AndonPull::ObjectLifecycleViolation
);
ConformanceVerdict::passed()
}
#[cfg(test)]
mod tests {
use super::*;
fn exact_report() -> ReplayReport {
ReplayReport {
fitness: ProofDimension::Measured(1.0),
precision: ProofDimension::Measured(1.0),
receipt_coverage: ProofDimension::Measured(1.0),
required_stage_coverage: ProofDimension::Measured(1.0),
object_lifecycle_validity: ProofDimension::Measured(1.0),
}
}
#[test]
fn all_measured_at_1_0_passes() {
assert_eq!(
classify_conformance(&exact_report(), ExpectedConformance::exact()),
ConformanceVerdict::Passed,
);
}
#[test]
fn fitness_gap_gives_route_conformance_gap() {
let report = ReplayReport {
fitness: ProofDimension::Measured(0.999),
..exact_report()
};
assert_eq!(
classify_conformance(&report, ExpectedConformance::exact()),
ConformanceVerdict::Andon(AndonPull::RouteConformanceGap),
);
}
#[test]
fn precision_gap_gives_illegal_route_motion() {
let report = ReplayReport {
precision: ProofDimension::Measured(0.999),
..exact_report()
};
assert_eq!(
classify_conformance(&report, ExpectedConformance::exact()),
ConformanceVerdict::Andon(AndonPull::IllegalRouteMotion),
);
}
#[test]
fn receipt_coverage_gap_gives_missing_receipt_coverage() {
let report = ReplayReport {
receipt_coverage: ProofDimension::Measured(0.999),
..exact_report()
};
assert_eq!(
classify_conformance(&report, ExpectedConformance::exact()),
ConformanceVerdict::Andon(AndonPull::MissingReceiptCoverage),
);
}
#[test]
fn stage_coverage_gap_gives_missing_route_activity() {
let report = ReplayReport {
required_stage_coverage: ProofDimension::Measured(0.999),
..exact_report()
};
assert_eq!(
classify_conformance(&report, ExpectedConformance::exact()),
ConformanceVerdict::Andon(AndonPull::MissingRouteActivity),
);
}
#[test]
fn lifecycle_gap_gives_object_lifecycle_violation() {
let report = ReplayReport {
object_lifecycle_validity: ProofDimension::Measured(0.999),
..exact_report()
};
assert_eq!(
classify_conformance(&report, ExpectedConformance::exact()),
ConformanceVerdict::Andon(AndonPull::ObjectLifecycleViolation),
);
}
#[test]
fn not_measured_fitness_returns_test_route_incomplete() {
let report = ReplayReport {
fitness: ProofDimension::NotMeasured,
..exact_report()
};
assert_eq!(
classify_conformance(&report, ExpectedConformance::exact()),
ConformanceVerdict::Andon(AndonPull::TestRouteIncomplete),
);
}
#[test]
fn not_measured_receipt_coverage_returns_test_route_incomplete() {
let report = ReplayReport {
receipt_coverage: ProofDimension::NotMeasured,
..exact_report()
};
assert_eq!(
classify_conformance(&report, ExpectedConformance::exact()),
ConformanceVerdict::Andon(AndonPull::TestRouteIncomplete),
);
}
#[test]
fn not_measured_object_lifecycle_returns_test_route_incomplete() {
let report = ReplayReport {
object_lifecycle_validity: ProofDimension::NotMeasured,
..exact_report()
};
assert_eq!(
classify_conformance(&report, ExpectedConformance::exact()),
ConformanceVerdict::Andon(AndonPull::TestRouteIncomplete),
);
}
#[test]
fn not_measured_checked_before_threshold() {
let report = ReplayReport {
receipt_coverage: ProofDimension::NotMeasured,
..exact_report()
};
assert_eq!(
classify_conformance(&report, ExpectedConformance::exact()),
ConformanceVerdict::Andon(AndonPull::TestRouteIncomplete),
"NotMeasured must return TestRouteIncomplete, not MissingReceiptCoverage"
);
}
#[test]
fn is_passed_works_for_passed() {
assert!(ConformanceVerdict::Passed.is_passed());
}
#[test]
fn is_passed_works_for_andon() {
assert!(!ConformanceVerdict::Andon(AndonPull::RouteConformanceGap).is_passed());
}
#[test]
fn exact_conformance_returns_all_ones() {
let c = ExpectedConformance::exact();
assert_eq!(c.fitness, 1.0);
assert_eq!(c.precision, 1.0);
assert_eq!(c.receipt_coverage, 1.0);
assert_eq!(c.required_stage_coverage, 1.0);
assert_eq!(c.object_lifecycle_validity, 1.0);
}
#[test]
fn zero_fitness_is_andon() {
let report = ReplayReport {
fitness: ProofDimension::Measured(0.0),
..exact_report()
};
assert_eq!(
classify_conformance(&report, ExpectedConformance::exact()),
ConformanceVerdict::Andon(AndonPull::RouteConformanceGap),
);
}
#[test]
fn priority_order_fitness_checked_first() {
let report = ReplayReport {
fitness: ProofDimension::Measured(0.0),
precision: ProofDimension::Measured(0.0),
receipt_coverage: ProofDimension::Measured(0.0),
required_stage_coverage: ProofDimension::Measured(0.0),
object_lifecycle_validity: ProofDimension::Measured(0.0),
};
assert_eq!(
classify_conformance(&report, ExpectedConformance::exact()),
ConformanceVerdict::Andon(AndonPull::RouteConformanceGap),
);
}
#[test]
fn proof_dimension_value_returns_some_for_measured() {
assert_eq!(ProofDimension::Measured(0.5).value(), Some(0.5));
}
#[test]
fn proof_dimension_value_returns_none_for_not_measured() {
assert_eq!(ProofDimension::NotMeasured.value(), None);
}
}