Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
250
vendor/ruvector/crates/cognitum-gate-kernel/tests_disabled/evidence_tests.rs
vendored
Normal file
250
vendor/ruvector/crates/cognitum-gate-kernel/tests_disabled/evidence_tests.rs
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
//! Comprehensive tests for E-value accumulator
|
||||
//!
|
||||
//! Tests cover:
|
||||
//! - E-value bounds (E[e] <= 1 under null)
|
||||
//! - Overflow/underflow protection
|
||||
//! - Update rules (Product, Average, ExponentialMoving, Maximum)
|
||||
//! - Stopping rules
|
||||
|
||||
use cognitum_gate_kernel::evidence::{
|
||||
EValueAccumulator, EValueError, StoppingDecision, StoppingRule, UpdateRule,
|
||||
E_VALUE_MAX, E_VALUE_MIN,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod basic_operations {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_accumulator_creation() {
|
||||
let acc = EValueAccumulator::new();
|
||||
assert_eq!(acc.current_value(), 1.0);
|
||||
assert_eq!(acc.observation_count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_observe_updates_count() {
|
||||
let mut acc = EValueAccumulator::new();
|
||||
acc.observe(0.5);
|
||||
assert_eq!(acc.observation_count(), 1);
|
||||
acc.observe(0.7);
|
||||
assert_eq!(acc.observation_count(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reset() {
|
||||
let mut acc = EValueAccumulator::new();
|
||||
acc.observe(0.5);
|
||||
acc.reset();
|
||||
assert_eq!(acc.current_value(), 1.0);
|
||||
assert_eq!(acc.observation_count(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod update_rules {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_product_rule() {
|
||||
let mut acc = EValueAccumulator::with_rule(UpdateRule::Product);
|
||||
acc.observe_evalue(2.0);
|
||||
assert!((acc.current_value() - 2.0).abs() < 0.001);
|
||||
acc.observe_evalue(3.0);
|
||||
assert!((acc.current_value() - 6.0).abs() < 0.001);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_average_rule() {
|
||||
let mut acc = EValueAccumulator::with_rule(UpdateRule::Average);
|
||||
acc.observe_evalue(2.0);
|
||||
acc.observe_evalue(4.0);
|
||||
assert!((acc.current_value() - 3.0).abs() < 0.001);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exponential_moving() {
|
||||
let mut acc = EValueAccumulator::with_rule(UpdateRule::ExponentialMoving { lambda: 0.5 });
|
||||
acc.observe_evalue(2.0);
|
||||
acc.observe_evalue(4.0);
|
||||
assert!((acc.current_value() - 3.0).abs() < 0.001);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_maximum_rule() {
|
||||
let mut acc = EValueAccumulator::with_rule(UpdateRule::Maximum);
|
||||
acc.observe_evalue(2.0);
|
||||
acc.observe_evalue(5.0);
|
||||
acc.observe_evalue(3.0);
|
||||
assert_eq!(acc.current_value(), 5.0);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod bounds_and_overflow {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_e_value_clamping_high() {
|
||||
let mut acc = EValueAccumulator::with_rule(UpdateRule::Product);
|
||||
acc.observe_evalue(1e20);
|
||||
assert!(acc.current_value() <= E_VALUE_MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_e_value_clamping_low() {
|
||||
let mut acc = EValueAccumulator::with_rule(UpdateRule::Product);
|
||||
acc.observe_evalue(1e-20);
|
||||
assert!(acc.current_value() >= E_VALUE_MIN);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_product_overflow_protection() {
|
||||
let mut acc = EValueAccumulator::with_rule(UpdateRule::Product);
|
||||
for _ in 0..100 {
|
||||
acc.observe_evalue(100.0);
|
||||
}
|
||||
assert!(acc.current_value() <= E_VALUE_MAX);
|
||||
assert!(acc.current_value().is_finite());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod likelihood_ratio {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_valid_likelihood_ratio() {
|
||||
let result = EValueAccumulator::from_likelihood_ratio(0.9, 0.1);
|
||||
assert!(result.is_ok());
|
||||
assert!((result.unwrap() - 9.0).abs() < 0.001);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero_denominator() {
|
||||
let result = EValueAccumulator::from_likelihood_ratio(0.5, 0.0);
|
||||
assert_eq!(result, Err(EValueError::DivisionByZero));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nan_input() {
|
||||
let result = EValueAccumulator::from_likelihood_ratio(f64::NAN, 0.5);
|
||||
assert_eq!(result, Err(EValueError::InvalidInput));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod mixture_evalue {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_uniform_mixture() {
|
||||
let components = [2.0, 4.0, 6.0];
|
||||
let weights = [1.0, 1.0, 1.0];
|
||||
let result = EValueAccumulator::mixture(&components, &weights);
|
||||
assert!(result.is_ok());
|
||||
assert!((result.unwrap() - 4.0).abs() < 0.001);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_mixture() {
|
||||
let result = EValueAccumulator::mixture(&[], &[]);
|
||||
assert_eq!(result, Err(EValueError::InvalidInput));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod stopping_rules {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_continue_decision() {
|
||||
let rule = StoppingRule::new(100.0);
|
||||
let acc = EValueAccumulator::new();
|
||||
assert_eq!(rule.check(&acc), StoppingDecision::Continue);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_accept_decision() {
|
||||
let rule = StoppingRule::new(100.0);
|
||||
let mut acc = EValueAccumulator::with_rule(UpdateRule::Product);
|
||||
for _ in 0..10 {
|
||||
acc.observe_evalue(2.0);
|
||||
}
|
||||
assert!(acc.current_value() > 100.0);
|
||||
assert_eq!(rule.check(&acc), StoppingDecision::Accept);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reject_decision() {
|
||||
let rule = StoppingRule::with_accept(100.0, 0.01);
|
||||
let mut acc = EValueAccumulator::with_rule(UpdateRule::Product);
|
||||
for _ in 0..10 {
|
||||
acc.observe_evalue(0.1);
|
||||
}
|
||||
assert!(acc.current_value() < 0.01);
|
||||
assert_eq!(rule.check(&acc), StoppingDecision::Reject);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_confidence_calculation() {
|
||||
let rule = StoppingRule::default();
|
||||
let mut acc = EValueAccumulator::new();
|
||||
assert_eq!(rule.confidence(&acc), 0.0);
|
||||
acc.observe_evalue(2.0);
|
||||
assert!((rule.confidence(&acc) - 0.5).abs() < 0.001);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod combine_evalues {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_combine_basic() {
|
||||
let combined = EValueAccumulator::combine(2.0, 3.0);
|
||||
assert_eq!(combined, 6.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_combine_overflow_clamped() {
|
||||
let combined = EValueAccumulator::combine(1e10, 1e10);
|
||||
assert!(combined <= E_VALUE_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod property_tests {
|
||||
use super::*;
|
||||
use proptest::prelude::*;
|
||||
|
||||
proptest! {
|
||||
#[test]
|
||||
fn prop_e_value_always_positive(score in 0.0f64..1.0) {
|
||||
let acc = EValueAccumulator::new();
|
||||
let e = acc.compute_e_value(score);
|
||||
assert!(e > 0.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prop_e_value_bounded(score in 0.0f64..1.0) {
|
||||
let acc = EValueAccumulator::new();
|
||||
let e = acc.compute_e_value(score);
|
||||
assert!(e >= E_VALUE_MIN);
|
||||
assert!(e <= E_VALUE_MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prop_maximum_never_decreases(observations in proptest::collection::vec(0.1f64..10.0, 1..20)) {
|
||||
let mut acc = EValueAccumulator::with_rule(UpdateRule::Maximum);
|
||||
let mut max_seen = 0.0f64;
|
||||
|
||||
for o in observations {
|
||||
acc.observe_evalue(o);
|
||||
let current = acc.current_value();
|
||||
assert!(current >= max_seen);
|
||||
max_seen = current;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
302
vendor/ruvector/crates/cognitum-gate-kernel/tests_disabled/integration.rs
vendored
Normal file
302
vendor/ruvector/crates/cognitum-gate-kernel/tests_disabled/integration.rs
vendored
Normal file
@@ -0,0 +1,302 @@
|
||||
//! Integration tests for full tick cycle
|
||||
//!
|
||||
//! Tests cover:
|
||||
//! - Complete WorkerTileState lifecycle
|
||||
//! - Delta processing sequences
|
||||
//! - Tick report generation
|
||||
//! - Multiple tile coordination scenarios
|
||||
|
||||
use cognitum_gate_kernel::{
|
||||
Delta, DeltaError, WorkerTileState,
|
||||
shard::{Edge, EdgeId, VertexId, Weight},
|
||||
report::{TileReport, TileStatus},
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod worker_tile_lifecycle {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_tile_creation() {
|
||||
let tile = WorkerTileState::new(42);
|
||||
assert_eq!(tile.tile_id, 42);
|
||||
assert_eq!(tile.coherence, 0);
|
||||
assert_eq!(tile.tick, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_initial_report() {
|
||||
let mut tile = WorkerTileState::new(5);
|
||||
let report = tile.tick(1000);
|
||||
assert_eq!(report.tile_id, 5);
|
||||
assert_eq!(report.status, TileStatus::Active);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod delta_processing {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_edge_add_delta() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
let edge = Edge::new(VertexId(0), VertexId(1));
|
||||
let delta = Delta::EdgeAdd { edge, weight: Weight(100) };
|
||||
|
||||
assert!(tile.ingest_delta(&delta).is_ok());
|
||||
assert_eq!(tile.graph_shard.edge_count(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edge_remove_delta() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
let edge = Edge::new(VertexId(0), VertexId(1));
|
||||
|
||||
tile.ingest_delta(&Delta::EdgeAdd { edge, weight: Weight(100) }).unwrap();
|
||||
tile.ingest_delta(&Delta::EdgeRemove { edge: EdgeId(0) }).unwrap();
|
||||
|
||||
assert_eq!(tile.graph_shard.edge_count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_weight_update_delta() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
let edge = Edge::new(VertexId(0), VertexId(1));
|
||||
|
||||
tile.ingest_delta(&Delta::EdgeAdd { edge, weight: Weight(100) }).unwrap();
|
||||
tile.ingest_delta(&Delta::WeightUpdate { edge: EdgeId(0), weight: Weight(200) }).unwrap();
|
||||
|
||||
assert_eq!(tile.graph_shard.get_weight(EdgeId(0)), Some(Weight(200)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_observation_delta() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
tile.ingest_delta(&Delta::Observation { score: 0.8 }).unwrap();
|
||||
assert_eq!(tile.e_accumulator.observation_count(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_self_loop_rejected() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
let edge = Edge::new(VertexId(5), VertexId(5));
|
||||
let delta = Delta::EdgeAdd { edge, weight: Weight(100) };
|
||||
assert_eq!(tile.ingest_delta(&delta), Err(DeltaError::InvalidEdge));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tick_cycle {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_single_tick() {
|
||||
let mut tile = WorkerTileState::new(10);
|
||||
let report = tile.tick(1000);
|
||||
assert_eq!(report.tile_id, 10);
|
||||
assert_eq!(tile.tick, 1000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tick_updates_timestamp() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
tile.tick(1000);
|
||||
assert_eq!(tile.tick, 1000);
|
||||
tile.tick(2000);
|
||||
assert_eq!(tile.tick, 2000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tick_after_deltas() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
|
||||
tile.ingest_delta(&Delta::EdgeAdd {
|
||||
edge: Edge::new(VertexId(0), VertexId(1)),
|
||||
weight: Weight(100),
|
||||
}).unwrap();
|
||||
tile.ingest_delta(&Delta::Observation { score: 0.9 }).unwrap();
|
||||
|
||||
let report = tile.tick(1000);
|
||||
assert!(report.is_healthy());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_tick_cycles() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
|
||||
for i in 0..10 {
|
||||
tile.ingest_delta(&Delta::EdgeAdd {
|
||||
edge: Edge::new(VertexId(i as u8), VertexId((i + 1) as u8)),
|
||||
weight: Weight(100),
|
||||
}).unwrap();
|
||||
tile.ingest_delta(&Delta::Observation { score: 0.8 }).unwrap();
|
||||
let report = tile.tick((i + 1) * 1000);
|
||||
assert!(report.is_healthy());
|
||||
}
|
||||
|
||||
assert_eq!(tile.graph_shard.edge_count(), 10);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod e_value_accumulation {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_e_value_in_report() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
|
||||
for _ in 0..5 {
|
||||
tile.ingest_delta(&Delta::Observation { score: 0.9 }).unwrap();
|
||||
}
|
||||
|
||||
let report = tile.tick(1000);
|
||||
assert!(report.e_value > 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod multi_tile_scenario {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_deterministic_across_tiles() {
|
||||
let deltas = [
|
||||
Delta::EdgeAdd { edge: Edge::new(VertexId(0), VertexId(1)), weight: Weight(100) },
|
||||
Delta::EdgeAdd { edge: Edge::new(VertexId(1), VertexId(2)), weight: Weight(150) },
|
||||
Delta::Observation { score: 0.9 },
|
||||
];
|
||||
|
||||
let mut tile1 = WorkerTileState::new(0);
|
||||
let mut tile2 = WorkerTileState::new(0);
|
||||
|
||||
for delta in &deltas {
|
||||
tile1.ingest_delta(delta).unwrap();
|
||||
tile2.ingest_delta(delta).unwrap();
|
||||
}
|
||||
|
||||
let report1 = tile1.tick(1000);
|
||||
let report2 = tile2.tick(1000);
|
||||
|
||||
assert_eq!(report1.coherence, report2.coherence);
|
||||
assert!((report1.e_value - report2.e_value).abs() < 0.001);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tile_network() {
|
||||
let mut tiles: Vec<WorkerTileState> = (0..10)
|
||||
.map(|id| WorkerTileState::new(id))
|
||||
.collect();
|
||||
|
||||
for (tile_idx, tile) in tiles.iter_mut().enumerate() {
|
||||
let base = (tile_idx * 10) as u8;
|
||||
for i in 0..5u8 {
|
||||
let _ = tile.ingest_delta(&Delta::EdgeAdd {
|
||||
edge: Edge::new(VertexId(base + i), VertexId(base + i + 1)),
|
||||
weight: Weight(100),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let reports: Vec<TileReport> = tiles
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.map(|(idx, tile)| tile.tick((idx as u64) * 100))
|
||||
.collect();
|
||||
|
||||
for report in &reports {
|
||||
assert!(report.is_healthy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod edge_cases {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_empty_tile_tick() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
let report = tile.tick(1000);
|
||||
assert!(report.is_healthy());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tile_with_only_observations() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
|
||||
for _ in 0..100 {
|
||||
tile.ingest_delta(&Delta::Observation { score: 0.5 }).unwrap();
|
||||
}
|
||||
|
||||
let report = tile.tick(1000);
|
||||
assert!(report.is_healthy());
|
||||
assert_eq!(tile.graph_shard.edge_count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tick_at_max() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
let report = tile.tick(u64::MAX);
|
||||
assert_eq!(tile.tick, u64::MAX);
|
||||
assert!(report.is_healthy());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_alternating_add_remove() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
|
||||
for _ in 0..100 {
|
||||
tile.ingest_delta(&Delta::EdgeAdd {
|
||||
edge: Edge::new(VertexId(0), VertexId(1)),
|
||||
weight: Weight(100),
|
||||
}).unwrap();
|
||||
tile.ingest_delta(&Delta::EdgeRemove { edge: EdgeId(0) }).unwrap();
|
||||
}
|
||||
|
||||
assert!(tile.tick(1000).is_healthy());
|
||||
assert_eq!(tile.graph_shard.edge_count(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod stress_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_high_volume_deltas() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
|
||||
for i in 0..1000 {
|
||||
let src = (i % 200) as u8;
|
||||
let dst = ((i + 1) % 200) as u8;
|
||||
|
||||
if src != dst {
|
||||
let _ = tile.ingest_delta(&Delta::EdgeAdd {
|
||||
edge: Edge::new(VertexId(src), VertexId(dst)),
|
||||
weight: Weight(100),
|
||||
});
|
||||
}
|
||||
|
||||
if i % 10 == 0 {
|
||||
let _ = tile.ingest_delta(&Delta::Observation { score: 0.8 });
|
||||
}
|
||||
}
|
||||
|
||||
assert!(tile.tick(10000).is_healthy());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rapid_tick_cycles() {
|
||||
let mut tile = WorkerTileState::new(0);
|
||||
|
||||
tile.ingest_delta(&Delta::EdgeAdd {
|
||||
edge: Edge::new(VertexId(0), VertexId(1)),
|
||||
weight: Weight(100),
|
||||
}).unwrap();
|
||||
|
||||
for i in 0..1000u64 {
|
||||
assert!(tile.tick(i).is_healthy());
|
||||
}
|
||||
}
|
||||
}
|
||||
249
vendor/ruvector/crates/cognitum-gate-kernel/tests_disabled/report_tests.rs
vendored
Normal file
249
vendor/ruvector/crates/cognitum-gate-kernel/tests_disabled/report_tests.rs
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
//! Comprehensive tests for TileReport generation and serialization
|
||||
//!
|
||||
//! Tests cover:
|
||||
//! - Report creation and initialization
|
||||
//! - Serialization/deserialization roundtrips
|
||||
//! - Checksum verification
|
||||
//! - WitnessFragment operations
|
||||
|
||||
use cognitum_gate_kernel::report::{TileReport, TileStatus, WitnessFragment};
|
||||
use cognitum_gate_kernel::shard::EdgeId;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tile_status {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_status_values() {
|
||||
assert_eq!(TileStatus::Active as u8, 0);
|
||||
assert_eq!(TileStatus::Idle as u8, 1);
|
||||
assert_eq!(TileStatus::Recovery as u8, 2);
|
||||
assert_eq!(TileStatus::Error as u8, 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_status_from_u8() {
|
||||
assert_eq!(TileStatus::from_u8(0), Some(TileStatus::Active));
|
||||
assert_eq!(TileStatus::from_u8(1), Some(TileStatus::Idle));
|
||||
assert_eq!(TileStatus::from_u8(255), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_healthy() {
|
||||
assert!(TileStatus::Active.is_healthy());
|
||||
assert!(TileStatus::Idle.is_healthy());
|
||||
assert!(!TileStatus::Error.is_healthy());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod witness_fragment {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_fragment_creation() {
|
||||
let frag = WitnessFragment::new(42);
|
||||
assert_eq!(frag.tile_id, 42);
|
||||
assert_eq!(frag.min_cut_value, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_fragile() {
|
||||
let mut frag = WitnessFragment::new(0);
|
||||
frag.min_cut_value = 5;
|
||||
assert!(frag.is_fragile(10));
|
||||
assert!(!frag.is_fragile(5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fragment_hash_deterministic() {
|
||||
let frag = WitnessFragment::new(5);
|
||||
assert_eq!(frag.compute_hash(), frag.compute_hash());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fragment_hash_unique() {
|
||||
let frag1 = WitnessFragment::new(1);
|
||||
let frag2 = WitnessFragment::new(2);
|
||||
assert_ne!(frag1.compute_hash(), frag2.compute_hash());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tile_report_creation {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_new_report() {
|
||||
let report = TileReport::new(5);
|
||||
assert_eq!(report.tile_id, 5);
|
||||
assert_eq!(report.status, TileStatus::Active);
|
||||
assert!(report.is_healthy());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_error_report() {
|
||||
let report = TileReport::error(10);
|
||||
assert_eq!(report.status, TileStatus::Error);
|
||||
assert!(!report.is_healthy());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_idle_report() {
|
||||
let report = TileReport::idle(15);
|
||||
assert_eq!(report.status, TileStatus::Idle);
|
||||
assert!(report.is_healthy());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod report_health_checks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_needs_attention_boundary_moved() {
|
||||
let mut report = TileReport::new(0);
|
||||
assert!(!report.needs_attention());
|
||||
report.boundary_moved = true;
|
||||
assert!(report.needs_attention());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_needs_attention_negative_coherence() {
|
||||
let mut report = TileReport::new(0);
|
||||
report.coherence = -100;
|
||||
assert!(report.needs_attention());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod coherence_conversion {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_coherence_f32_values() {
|
||||
let mut report = TileReport::new(0);
|
||||
|
||||
report.coherence = 0;
|
||||
assert!((report.coherence_f32() - 0.0).abs() < 0.001);
|
||||
|
||||
report.coherence = 256;
|
||||
assert!((report.coherence_f32() - 1.0).abs() < 0.01);
|
||||
|
||||
report.coherence = -128;
|
||||
assert!((report.coherence_f32() - (-0.5)).abs() < 0.01);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod serialization {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_to_bytes_size() {
|
||||
let report = TileReport::new(0);
|
||||
let bytes = report.to_bytes();
|
||||
assert_eq!(bytes.len(), 64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_roundtrip_basic() {
|
||||
let report = TileReport::new(42);
|
||||
let bytes = report.to_bytes();
|
||||
let restored = TileReport::from_bytes(&bytes).unwrap();
|
||||
assert_eq!(report.tile_id, restored.tile_id);
|
||||
assert_eq!(report.status, restored.status);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_roundtrip_with_data() {
|
||||
let mut report = TileReport::new(100);
|
||||
report.coherence = 512;
|
||||
report.e_value = 2.5;
|
||||
report.boundary_moved = true;
|
||||
report.suspicious_edges[0] = EdgeId(100);
|
||||
|
||||
let bytes = report.to_bytes();
|
||||
let restored = TileReport::from_bytes(&bytes).unwrap();
|
||||
|
||||
assert_eq!(restored.coherence, 512);
|
||||
assert!((restored.e_value - 2.5).abs() < 0.001);
|
||||
assert!(restored.boundary_moved);
|
||||
assert_eq!(restored.suspicious_edges[0], EdgeId(100));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod checksum {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_checksum_deterministic() {
|
||||
let report = TileReport::new(42);
|
||||
assert_eq!(report.checksum(), report.checksum());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_checksum_different_reports() {
|
||||
let r1 = TileReport::new(1);
|
||||
let r2 = TileReport::new(2);
|
||||
assert_ne!(r1.checksum(), r2.checksum());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verify_checksum() {
|
||||
let report = TileReport::new(42);
|
||||
let cs = report.checksum();
|
||||
assert!(report.verify_checksum(cs));
|
||||
assert!(!report.verify_checksum(0));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod report_size {
|
||||
use super::*;
|
||||
use std::mem::size_of;
|
||||
|
||||
#[test]
|
||||
fn test_report_fits_cache_line() {
|
||||
assert!(size_of::<TileReport>() <= 64);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod property_tests {
|
||||
use super::*;
|
||||
use proptest::prelude::*;
|
||||
|
||||
proptest! {
|
||||
#[test]
|
||||
fn prop_serialization_roundtrip(
|
||||
tile_id in 0u8..255,
|
||||
coherence in i16::MIN..i16::MAX,
|
||||
e_value in 0.0f32..100.0,
|
||||
boundary_moved: bool
|
||||
) {
|
||||
let mut report = TileReport::new(tile_id);
|
||||
report.coherence = coherence;
|
||||
report.e_value = e_value;
|
||||
report.boundary_moved = boundary_moved;
|
||||
|
||||
let bytes = report.to_bytes();
|
||||
let restored = TileReport::from_bytes(&bytes).unwrap();
|
||||
|
||||
assert_eq!(report.tile_id, restored.tile_id);
|
||||
assert_eq!(report.coherence, restored.coherence);
|
||||
assert_eq!(report.boundary_moved, restored.boundary_moved);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prop_checksum_changes_with_data(a: i16, b: i16) {
|
||||
prop_assume!(a != b);
|
||||
let mut r1 = TileReport::new(0);
|
||||
let mut r2 = TileReport::new(0);
|
||||
r1.coherence = a;
|
||||
r2.coherence = b;
|
||||
assert_ne!(r1.checksum(), r2.checksum());
|
||||
}
|
||||
}
|
||||
}
|
||||
299
vendor/ruvector/crates/cognitum-gate-kernel/tests_disabled/shard_tests.rs
vendored
Normal file
299
vendor/ruvector/crates/cognitum-gate-kernel/tests_disabled/shard_tests.rs
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
//! Comprehensive tests for CompactGraph operations
|
||||
//!
|
||||
//! Tests cover:
|
||||
//! - Edge add/remove operations
|
||||
//! - Weight updates
|
||||
//! - Boundary edge management
|
||||
//! - Edge cases (empty graph, max capacity, boundary conditions)
|
||||
//! - Property-based tests for invariant verification
|
||||
|
||||
use cognitum_gate_kernel::shard::{CompactGraph, Edge, EdgeId, VertexId, Weight};
|
||||
use cognitum_gate_kernel::{DeltaError, MAX_EDGES, MAX_VERTICES};
|
||||
|
||||
#[cfg(test)]
|
||||
mod basic_operations {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_empty_graph() {
|
||||
let graph = CompactGraph::new();
|
||||
assert!(graph.is_empty());
|
||||
assert_eq!(graph.edge_count(), 0);
|
||||
assert_eq!(graph.vertex_count(), 0);
|
||||
assert!(!graph.is_full());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_single_edge() {
|
||||
let mut graph = CompactGraph::new();
|
||||
let edge = Edge::new(VertexId(0), VertexId(1));
|
||||
let weight = Weight(100);
|
||||
|
||||
let result = graph.add_edge(edge, weight);
|
||||
assert!(result.is_ok());
|
||||
|
||||
let edge_id = result.unwrap();
|
||||
assert_eq!(graph.edge_count(), 1);
|
||||
assert_eq!(graph.vertex_count(), 2);
|
||||
assert_eq!(graph.get_weight(edge_id), Some(weight));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_multiple_edges() {
|
||||
let mut graph = CompactGraph::new();
|
||||
|
||||
let edges = [
|
||||
(Edge::new(VertexId(0), VertexId(1)), Weight(100)),
|
||||
(Edge::new(VertexId(1), VertexId(2)), Weight(200)),
|
||||
(Edge::new(VertexId(2), VertexId(3)), Weight(300)),
|
||||
];
|
||||
|
||||
for (edge, weight) in edges {
|
||||
let result = graph.add_edge(edge, weight);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
assert_eq!(graph.edge_count(), 3);
|
||||
assert_eq!(graph.vertex_count(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_edge() {
|
||||
let mut graph = CompactGraph::new();
|
||||
let edge = Edge::new(VertexId(0), VertexId(1));
|
||||
let edge_id = graph.add_edge(edge, Weight(100)).unwrap();
|
||||
|
||||
let result = graph.remove_edge(edge_id);
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(graph.edge_count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_nonexistent_edge() {
|
||||
let mut graph = CompactGraph::new();
|
||||
let result = graph.remove_edge(EdgeId(999));
|
||||
assert_eq!(result, Err(DeltaError::EdgeNotFound));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_weight() {
|
||||
let mut graph = CompactGraph::new();
|
||||
let edge = Edge::new(VertexId(0), VertexId(1));
|
||||
let edge_id = graph.add_edge(edge, Weight(100)).unwrap();
|
||||
|
||||
let result = graph.update_weight(edge_id, Weight(500));
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(graph.get_weight(edge_id), Some(Weight(500)));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod edge_canonicalization {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_canonical_ordering() {
|
||||
let e1 = Edge::new(VertexId(5), VertexId(3));
|
||||
let e2 = Edge::new(VertexId(3), VertexId(5));
|
||||
|
||||
assert_eq!(e1.canonical(), e2.canonical());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_self_loop_rejected() {
|
||||
let mut graph = CompactGraph::new();
|
||||
let edge = Edge::new(VertexId(5), VertexId(5));
|
||||
|
||||
let result = graph.add_edge(edge, Weight(100));
|
||||
assert_eq!(result, Err(DeltaError::InvalidEdge));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_duplicate_edge_updates_weight() {
|
||||
let mut graph = CompactGraph::new();
|
||||
let e1 = Edge::new(VertexId(0), VertexId(1));
|
||||
let e2 = Edge::new(VertexId(1), VertexId(0));
|
||||
|
||||
let id1 = graph.add_edge(e1, Weight(100)).unwrap();
|
||||
let id2 = graph.add_edge(e2, Weight(200)).unwrap();
|
||||
|
||||
assert_eq!(id1, id2);
|
||||
assert_eq!(graph.edge_count(), 1);
|
||||
assert_eq!(graph.get_weight(id1), Some(Weight(200)));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod boundary_edges {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_mark_boundary() {
|
||||
let mut graph = CompactGraph::new();
|
||||
let edge = Edge::new(VertexId(0), VertexId(1));
|
||||
let edge_id = graph.add_edge(edge, Weight(100)).unwrap();
|
||||
|
||||
assert_eq!(graph.total_internal_weight(), 100);
|
||||
assert_eq!(graph.total_boundary_weight(), 0);
|
||||
|
||||
graph.mark_boundary(edge_id).unwrap();
|
||||
|
||||
assert_eq!(graph.total_internal_weight(), 0);
|
||||
assert_eq!(graph.total_boundary_weight(), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unmark_boundary() {
|
||||
let mut graph = CompactGraph::new();
|
||||
let edge = Edge::new(VertexId(0), VertexId(1));
|
||||
let edge_id = graph.add_edge(edge, Weight(100)).unwrap();
|
||||
|
||||
graph.mark_boundary(edge_id).unwrap();
|
||||
graph.unmark_boundary(edge_id).unwrap();
|
||||
|
||||
assert_eq!(graph.total_boundary_weight(), 0);
|
||||
assert_eq!(graph.total_internal_weight(), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boundary_changed_flag() {
|
||||
let mut graph = CompactGraph::new();
|
||||
let edge = Edge::new(VertexId(0), VertexId(1));
|
||||
let edge_id = graph.add_edge(edge, Weight(100)).unwrap();
|
||||
|
||||
graph.clear_boundary_changed();
|
||||
assert!(!graph.boundary_changed_since_last_update());
|
||||
|
||||
graph.mark_boundary(edge_id).unwrap();
|
||||
assert!(graph.boundary_changed_since_last_update());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod weight_operations {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_weight_from_f32() {
|
||||
let w = Weight::from_f32(1.0);
|
||||
assert_eq!(w.0, 256);
|
||||
|
||||
let w2 = Weight::from_f32(2.0);
|
||||
assert_eq!(w2.0, 512);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_weight_to_f32() {
|
||||
let w = Weight(256);
|
||||
assert!((w.to_f32() - 1.0).abs() < 0.01);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_weight_saturating_operations() {
|
||||
let w1 = Weight(u16::MAX - 10);
|
||||
let w2 = Weight(100);
|
||||
let sum = w1.saturating_add(w2);
|
||||
assert_eq!(sum, Weight::MAX);
|
||||
|
||||
let w3 = Weight(10);
|
||||
let diff = w3.saturating_sub(w2);
|
||||
assert_eq!(diff, Weight::ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod vertex_degree {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_vertex_degree_after_add() {
|
||||
let mut graph = CompactGraph::new();
|
||||
|
||||
graph.add_edge(Edge::new(VertexId(0), VertexId(1)), Weight(100)).unwrap();
|
||||
graph.add_edge(Edge::new(VertexId(0), VertexId(2)), Weight(100)).unwrap();
|
||||
graph.add_edge(Edge::new(VertexId(0), VertexId(3)), Weight(100)).unwrap();
|
||||
|
||||
assert_eq!(graph.vertex_degree(VertexId(0)), 3);
|
||||
assert_eq!(graph.vertex_degree(VertexId(1)), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vertex_degree_after_remove() {
|
||||
let mut graph = CompactGraph::new();
|
||||
|
||||
let id1 = graph.add_edge(Edge::new(VertexId(0), VertexId(1)), Weight(100)).unwrap();
|
||||
graph.add_edge(Edge::new(VertexId(0), VertexId(2)), Weight(100)).unwrap();
|
||||
|
||||
graph.remove_edge(id1).unwrap();
|
||||
assert_eq!(graph.vertex_degree(VertexId(0)), 1);
|
||||
assert_eq!(graph.vertex_degree(VertexId(1)), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod min_cut_estimation {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_min_cut_empty_graph() {
|
||||
let graph = CompactGraph::new();
|
||||
assert_eq!(graph.local_min_cut(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_min_cut_single_edge() {
|
||||
let mut graph = CompactGraph::new();
|
||||
graph.add_edge(Edge::new(VertexId(0), VertexId(1)), Weight(100)).unwrap();
|
||||
assert_eq!(graph.local_min_cut(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_min_cut_clique() {
|
||||
let mut graph = CompactGraph::new();
|
||||
|
||||
for i in 0..4u8 {
|
||||
for j in (i + 1)..4 {
|
||||
graph.add_edge(Edge::new(VertexId(i), VertexId(j)), Weight(100)).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(graph.local_min_cut(), 3);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod property_tests {
|
||||
use super::*;
|
||||
use proptest::prelude::*;
|
||||
|
||||
proptest! {
|
||||
#[test]
|
||||
fn prop_add_remove_invariant(src in 0u8..250, dst in 0u8..250, weight in 1u16..1000) {
|
||||
prop_assume!(src != dst);
|
||||
|
||||
let mut graph = CompactGraph::new();
|
||||
let edge = Edge::new(VertexId(src), VertexId(dst));
|
||||
let id = graph.add_edge(edge, Weight(weight)).unwrap();
|
||||
|
||||
assert_eq!(graph.edge_count(), 1);
|
||||
graph.remove_edge(id).unwrap();
|
||||
assert_eq!(graph.edge_count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prop_canonical_symmetry(a in 0u8..250, b in 0u8..250) {
|
||||
prop_assume!(a != b);
|
||||
|
||||
let e1 = Edge::new(VertexId(a), VertexId(b));
|
||||
let e2 = Edge::new(VertexId(b), VertexId(a));
|
||||
assert_eq!(e1.canonical(), e2.canonical());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prop_weight_roundtrip(f in 0.0f32..200.0) {
|
||||
let weight = Weight::from_f32(f);
|
||||
let back = weight.to_f32();
|
||||
assert!((f - back).abs() < 0.01 || back >= 255.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user