Files
wifi-densepose/crates/cognitum-gate-tilezero/tests_disabled/replay_tests.rs
ruv d803bfe2b1 Squashed 'vendor/ruvector/' content from commit b64c2172
git-subtree-dir: vendor/ruvector
git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
2026-02-28 14:39:40 -05:00

666 lines
20 KiB
Rust

//! Comprehensive tests for deterministic replay
//!
//! Tests cover:
//! - Replay engine creation and configuration
//! - Checkpoint management
//! - Decision replay and verification
//! - Security tests (ensuring determinism)
use cognitum_gate_tilezero::replay::{
ReplayDifference, ReplayEngine, ReplayError, ReplayResult, SequenceVerification,
StateSnapshot, TileSnapshot,
};
use cognitum_gate_tilezero::receipt::{
EvidentialWitness, PredictiveWitness, StructuralWitness, TimestampProof, WitnessReceipt,
WitnessSummary,
};
use cognitum_gate_tilezero::permit::PermitToken;
use cognitum_gate_tilezero::GateDecision;
use std::collections::HashMap;
fn create_test_receipt(
sequence: u64,
decision: GateDecision,
witness: WitnessSummary,
) -> WitnessReceipt {
WitnessReceipt {
sequence,
token: PermitToken {
decision,
action_id: format!("action-{}", sequence),
timestamp: 1000000000 + sequence * 1000,
ttl_ns: 60_000_000_000,
witness_hash: [0u8; 32],
sequence,
signature: [0u8; 64],
},
previous_hash: [0u8; 32],
witness_summary: witness,
timestamp_proof: TimestampProof {
timestamp: 1000000000 + sequence * 1000,
previous_receipt_hash: [0u8; 32],
merkle_root: [0u8; 32],
},
}
}
fn create_permit_witness() -> WitnessSummary {
WitnessSummary {
structural: StructuralWitness {
cut_value: 10.0,
partition: "stable".to_string(),
critical_edges: 2,
boundary: vec![],
},
predictive: PredictiveWitness {
set_size: 5,
coverage: 0.9,
},
evidential: EvidentialWitness {
e_value: 150.0,
verdict: "accept".to_string(),
},
}
}
fn create_defer_witness() -> WitnessSummary {
WitnessSummary {
structural: StructuralWitness {
cut_value: 10.0,
partition: "stable".to_string(),
critical_edges: 5,
boundary: vec![],
},
predictive: PredictiveWitness {
set_size: 25, // Large set size -> defer
coverage: 0.9,
},
evidential: EvidentialWitness {
e_value: 50.0,
verdict: "continue".to_string(),
},
}
}
fn create_deny_witness() -> WitnessSummary {
WitnessSummary {
structural: StructuralWitness {
cut_value: 2.0,
partition: "fragile".to_string(), // Fragile -> deny
critical_edges: 10,
boundary: vec![],
},
predictive: PredictiveWitness {
set_size: 5,
coverage: 0.9,
},
evidential: EvidentialWitness {
e_value: 0.001,
verdict: "reject".to_string(),
},
}
}
#[cfg(test)]
mod engine_creation {
use super::*;
#[test]
fn test_default_engine() {
let engine = ReplayEngine::default();
assert_eq!(engine.checkpoint_count(), 0);
}
#[test]
fn test_engine_with_interval() {
let engine = ReplayEngine::new(50);
assert_eq!(engine.checkpoint_count(), 0);
}
}
#[cfg(test)]
mod checkpoint_management {
use super::*;
#[test]
fn test_save_checkpoint() {
let mut engine = ReplayEngine::new(10);
let snapshot = StateSnapshot {
sequence: 0,
timestamp: 1000,
global_min_cut: 10.0,
aggregate_e_value: 100.0,
min_coherence: 256,
tile_states: HashMap::new(),
};
engine.save_checkpoint(0, snapshot);
assert_eq!(engine.checkpoint_count(), 1);
}
#[test]
fn test_checkpoint_at_interval() {
let mut engine = ReplayEngine::new(10);
// Checkpoint at 0, 10, 20 should be saved
for seq in [0, 5, 10, 15, 20] {
let snapshot = StateSnapshot {
sequence: seq,
timestamp: 1000 + seq,
global_min_cut: 10.0,
aggregate_e_value: 100.0,
min_coherence: 256,
tile_states: HashMap::new(),
};
engine.save_checkpoint(seq, snapshot);
}
// Only 0, 10, 20 should be saved (multiples of 10)
assert_eq!(engine.checkpoint_count(), 3);
}
#[test]
fn test_find_nearest_checkpoint() {
let mut engine = ReplayEngine::new(10);
for seq in [0, 10, 20] {
let snapshot = StateSnapshot {
sequence: seq,
timestamp: 1000 + seq,
global_min_cut: seq as f64,
aggregate_e_value: 100.0,
min_coherence: 256,
tile_states: HashMap::new(),
};
engine.save_checkpoint(seq, snapshot);
}
// Find nearest for 15 -> should be 10
let (found_seq, snapshot) = engine.find_nearest_checkpoint(15).unwrap();
assert_eq!(found_seq, 10);
assert_eq!(snapshot.global_min_cut, 10.0);
// Find nearest for 25 -> should be 20
let (found_seq, _) = engine.find_nearest_checkpoint(25).unwrap();
assert_eq!(found_seq, 20);
// Find nearest for 5 -> should be 0
let (found_seq, _) = engine.find_nearest_checkpoint(5).unwrap();
assert_eq!(found_seq, 0);
}
#[test]
fn test_no_checkpoint_found() {
let engine = ReplayEngine::new(10);
assert!(engine.find_nearest_checkpoint(5).is_none());
}
#[test]
fn test_prune_checkpoints() {
let mut engine = ReplayEngine::new(10);
for seq in [0, 10, 20, 30, 40, 50] {
let snapshot = StateSnapshot {
sequence: seq,
timestamp: 1000 + seq,
global_min_cut: 10.0,
aggregate_e_value: 100.0,
min_coherence: 256,
tile_states: HashMap::new(),
};
engine.save_checkpoint(seq, snapshot);
}
assert_eq!(engine.checkpoint_count(), 6);
engine.prune_before(30);
assert_eq!(engine.checkpoint_count(), 3); // 30, 40, 50 remain
assert!(engine.find_nearest_checkpoint(20).is_none());
assert!(engine.find_nearest_checkpoint(30).is_some());
}
}
#[cfg(test)]
mod decision_replay {
use super::*;
#[test]
fn test_replay_permit() {
let engine = ReplayEngine::new(100);
let receipt = create_test_receipt(0, GateDecision::Permit, create_permit_witness());
let result = engine.replay(&receipt);
assert!(result.matched);
assert_eq!(result.decision, GateDecision::Permit);
assert_eq!(result.original_decision, GateDecision::Permit);
assert!(result.differences.is_empty());
}
#[test]
fn test_replay_defer() {
let engine = ReplayEngine::new(100);
let receipt = create_test_receipt(0, GateDecision::Defer, create_defer_witness());
let result = engine.replay(&receipt);
assert!(result.matched);
assert_eq!(result.decision, GateDecision::Defer);
}
#[test]
fn test_replay_deny() {
let engine = ReplayEngine::new(100);
let receipt = create_test_receipt(0, GateDecision::Deny, create_deny_witness());
let result = engine.replay(&receipt);
assert!(result.matched);
assert_eq!(result.decision, GateDecision::Deny);
}
#[test]
fn test_replay_mismatch() {
let engine = ReplayEngine::new(100);
// Create a receipt where the decision doesn't match the witness
// Witness indicates DENY (fragile partition), but token says PERMIT
let receipt = create_test_receipt(0, GateDecision::Permit, create_deny_witness());
let result = engine.replay(&receipt);
assert!(!result.matched);
assert_eq!(result.decision, GateDecision::Deny); // Reconstructed from witness
assert_eq!(result.original_decision, GateDecision::Permit); // From token
assert!(!result.differences.is_empty());
}
#[test]
fn test_replay_preserves_snapshot() {
let engine = ReplayEngine::new(100);
let witness = create_permit_witness();
let receipt = create_test_receipt(0, GateDecision::Permit, witness.clone());
let result = engine.replay(&receipt);
assert_eq!(result.state_snapshot.structural.cut_value, witness.structural.cut_value);
assert_eq!(result.state_snapshot.evidential.e_value, witness.evidential.e_value);
}
}
#[cfg(test)]
mod sequence_verification {
use super::*;
#[test]
fn test_verify_empty_sequence() {
let engine = ReplayEngine::new(100);
let verification = engine.verify_sequence(&[]);
assert_eq!(verification.total_receipts, 0);
assert!(verification.all_matched);
assert_eq!(verification.mismatch_count(), 0);
}
#[test]
fn test_verify_single_receipt() {
let engine = ReplayEngine::new(100);
let receipts = vec![create_test_receipt(0, GateDecision::Permit, create_permit_witness())];
let verification = engine.verify_sequence(&receipts);
assert_eq!(verification.total_receipts, 1);
assert!(verification.all_matched);
}
#[test]
fn test_verify_multiple_receipts() {
let engine = ReplayEngine::new(100);
let receipts = vec![
create_test_receipt(0, GateDecision::Permit, create_permit_witness()),
create_test_receipt(1, GateDecision::Defer, create_defer_witness()),
create_test_receipt(2, GateDecision::Deny, create_deny_witness()),
];
let verification = engine.verify_sequence(&receipts);
assert_eq!(verification.total_receipts, 3);
assert!(verification.all_matched);
assert_eq!(verification.mismatch_count(), 0);
}
#[test]
fn test_verify_with_mismatches() {
let engine = ReplayEngine::new(100);
let receipts = vec![
create_test_receipt(0, GateDecision::Permit, create_permit_witness()),
create_test_receipt(1, GateDecision::Permit, create_deny_witness()), // Mismatch!
create_test_receipt(2, GateDecision::Deny, create_deny_witness()),
];
let verification = engine.verify_sequence(&receipts);
assert_eq!(verification.total_receipts, 3);
assert!(!verification.all_matched);
assert_eq!(verification.mismatch_count(), 1);
let mismatches: Vec<_> = verification.mismatches().collect();
assert_eq!(mismatches.len(), 1);
assert_eq!(mismatches[0].0, 1); // Sequence 1 mismatched
}
#[test]
fn test_mismatches_iterator() {
let engine = ReplayEngine::new(100);
let receipts = vec![
create_test_receipt(0, GateDecision::Permit, create_deny_witness()), // Mismatch
create_test_receipt(1, GateDecision::Permit, create_permit_witness()),
create_test_receipt(2, GateDecision::Defer, create_deny_witness()), // Mismatch
];
let verification = engine.verify_sequence(&receipts);
let mismatches: Vec<_> = verification.mismatches().collect();
assert_eq!(mismatches.len(), 2);
}
}
#[cfg(test)]
mod checkpoint_export_import {
use super::*;
#[test]
fn test_export_checkpoint() {
let mut engine = ReplayEngine::new(10);
let snapshot = StateSnapshot {
sequence: 0,
timestamp: 1000,
global_min_cut: 15.0,
aggregate_e_value: 200.0,
min_coherence: 512,
tile_states: HashMap::new(),
};
engine.save_checkpoint(0, snapshot);
let exported = engine.export_checkpoint(0);
assert!(exported.is_some());
let data = exported.unwrap();
assert!(!data.is_empty());
}
#[test]
fn test_export_nonexistent() {
let engine = ReplayEngine::new(10);
assert!(engine.export_checkpoint(0).is_none());
}
#[test]
fn test_import_checkpoint() {
let mut engine1 = ReplayEngine::new(10);
let snapshot = StateSnapshot {
sequence: 0,
timestamp: 1000,
global_min_cut: 25.0,
aggregate_e_value: 300.0,
min_coherence: 768,
tile_states: HashMap::new(),
};
engine1.save_checkpoint(0, snapshot);
let exported = engine1.export_checkpoint(0).unwrap();
let mut engine2 = ReplayEngine::new(10);
assert!(engine2.import_checkpoint(0, &exported).is_ok());
assert_eq!(engine2.checkpoint_count(), 1);
let (_, imported) = engine2.find_nearest_checkpoint(0).unwrap();
assert_eq!(imported.global_min_cut, 25.0);
}
#[test]
fn test_import_invalid_data() {
let mut engine = ReplayEngine::new(10);
let result = engine.import_checkpoint(0, b"invalid json");
assert!(matches!(result, Err(ReplayError::InvalidCheckpoint)));
}
}
#[cfg(test)]
mod tile_snapshot {
use super::*;
#[test]
fn test_tile_snapshot_in_state() {
let mut tile_states = HashMap::new();
tile_states.insert(
1,
TileSnapshot {
tile_id: 1,
coherence: 256,
e_value: 10.0,
boundary_edges: 5,
},
);
tile_states.insert(
2,
TileSnapshot {
tile_id: 2,
coherence: 512,
e_value: 20.0,
boundary_edges: 3,
},
);
let snapshot = StateSnapshot {
sequence: 0,
timestamp: 1000,
global_min_cut: 10.0,
aggregate_e_value: 100.0,
min_coherence: 256,
tile_states,
};
assert_eq!(snapshot.tile_states.len(), 2);
assert_eq!(snapshot.tile_states.get(&1).unwrap().coherence, 256);
assert_eq!(snapshot.tile_states.get(&2).unwrap().e_value, 20.0);
}
}
#[cfg(test)]
mod replay_difference {
use super::*;
#[test]
fn test_difference_structure() {
let diff = ReplayDifference {
field: "decision".to_string(),
original: "permit".to_string(),
replayed: "deny".to_string(),
};
assert_eq!(diff.field, "decision");
assert_eq!(diff.original, "permit");
assert_eq!(diff.replayed, "deny");
}
}
#[cfg(test)]
mod determinism {
use super::*;
/// Test that replaying the same receipt always produces the same result
#[test]
fn test_replay_deterministic() {
let engine = ReplayEngine::new(100);
let receipt = create_test_receipt(0, GateDecision::Permit, create_permit_witness());
let result1 = engine.replay(&receipt);
let result2 = engine.replay(&receipt);
assert_eq!(result1.decision, result2.decision);
assert_eq!(result1.matched, result2.matched);
assert_eq!(result1.differences.len(), result2.differences.len());
}
/// Test that different engines produce same results
#[test]
fn test_cross_engine_determinism() {
let engine1 = ReplayEngine::new(100);
let engine2 = ReplayEngine::new(50); // Different checkpoint interval
let receipt = create_test_receipt(0, GateDecision::Defer, create_defer_witness());
let result1 = engine1.replay(&receipt);
let result2 = engine2.replay(&receipt);
assert_eq!(result1.decision, result2.decision);
assert_eq!(result1.matched, result2.matched);
}
/// Test sequence verification is deterministic
#[test]
fn test_sequence_verification_deterministic() {
let engine = ReplayEngine::new(100);
let receipts = vec![
create_test_receipt(0, GateDecision::Permit, create_permit_witness()),
create_test_receipt(1, GateDecision::Deny, create_deny_witness()),
];
let v1 = engine.verify_sequence(&receipts);
let v2 = engine.verify_sequence(&receipts);
assert_eq!(v1.total_receipts, v2.total_receipts);
assert_eq!(v1.all_matched, v2.all_matched);
assert_eq!(v1.mismatch_count(), v2.mismatch_count());
}
}
#[cfg(test)]
mod security_tests {
use super::*;
/// Test that modified witness produces different replay result
#[test]
fn test_witness_tampering_detected() {
let engine = ReplayEngine::new(100);
let original = create_test_receipt(0, GateDecision::Permit, create_permit_witness());
let original_result = engine.replay(&original);
// Create tampered receipt with modified witness
let mut tampered_witness = create_permit_witness();
tampered_witness.structural.partition = "fragile".to_string();
let tampered = create_test_receipt(0, GateDecision::Permit, tampered_witness);
let tampered_result = engine.replay(&tampered);
// Tampered one should fail replay
assert!(original_result.matched);
assert!(!tampered_result.matched);
}
/// Test audit trail completeness
#[test]
fn test_audit_trail() {
let engine = ReplayEngine::new(100);
let mut receipts = Vec::new();
// Build a sequence of decisions
for i in 0..10 {
let witness = if i % 3 == 0 {
create_permit_witness()
} else if i % 3 == 1 {
create_defer_witness()
} else {
create_deny_witness()
};
let decision = if i % 3 == 0 {
GateDecision::Permit
} else if i % 3 == 1 {
GateDecision::Defer
} else {
GateDecision::Deny
};
receipts.push(create_test_receipt(i, decision, witness));
}
let verification = engine.verify_sequence(&receipts);
// All should match since we built them consistently
assert!(verification.all_matched);
assert_eq!(verification.total_receipts, 10);
}
}
// Property-based tests
#[cfg(test)]
mod property_tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn prop_replay_always_produces_result(sequence in 0u64..1000) {
let engine = ReplayEngine::new(100);
let receipt = create_test_receipt(
sequence,
GateDecision::Permit,
create_permit_witness()
);
let result = engine.replay(&receipt);
// Should always produce a valid result
assert!(result.decision == GateDecision::Permit ||
result.decision == GateDecision::Defer ||
result.decision == GateDecision::Deny);
}
#[test]
fn prop_checkpoint_interval_works(interval in 1u64..100) {
let mut engine = ReplayEngine::new(interval);
for seq in 0..interval * 3 {
let snapshot = StateSnapshot {
sequence: seq,
timestamp: 1000 + seq,
global_min_cut: 10.0,
aggregate_e_value: 100.0,
min_coherence: 256,
tile_states: HashMap::new(),
};
engine.save_checkpoint(seq, snapshot);
}
// Should have saved at least 3 checkpoints
assert!(engine.checkpoint_count() >= 3);
}
#[test]
fn prop_matching_decisions_have_empty_differences(seq in 0u64..100) {
let engine = ReplayEngine::new(100);
// Create receipts where decision matches witness
let receipts = vec![
(GateDecision::Permit, create_permit_witness()),
(GateDecision::Defer, create_defer_witness()),
(GateDecision::Deny, create_deny_witness()),
];
for (decision, witness) in receipts {
let receipt = create_test_receipt(seq, decision, witness);
let result = engine.replay(&receipt);
if result.matched {
assert!(result.differences.is_empty());
}
}
}
}
}