57 lines
2.3 KiB
Rust
57 lines
2.3 KiB
Rust
|
|
use simulation::distribution::sim::{
|
||
|
|
run_simulation_with_nodes, DistributionSimConfig, SimAction,
|
||
|
|
};
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn debug_tombstone_propagation() {
|
||
|
|
let config = DistributionSimConfig {
|
||
|
|
name: "debug-tombstone".into(),
|
||
|
|
num_nodes: 5,
|
||
|
|
num_rounds: 80,
|
||
|
|
ticks_per_round: 3,
|
||
|
|
actors_per_node: 0,
|
||
|
|
action_schedule: vec![
|
||
|
|
(5, SimAction::RegisterName { node_idx: 0, name: "svc".into() }),
|
||
|
|
],
|
||
|
|
kill_schedule: vec![(15, 0)],
|
||
|
|
..DistributionSimConfig::default()
|
||
|
|
};
|
||
|
|
|
||
|
|
let (trace, nodes) = run_simulation_with_nodes(config);
|
||
|
|
|
||
|
|
// Check snapshots at various rounds
|
||
|
|
for round_idx in [4, 9, 14, 19, 24, 39, 59, 79] {
|
||
|
|
if round_idx < trace.snapshots_per_round.len() {
|
||
|
|
let snaps = &trace.snapshots_per_round[round_idx];
|
||
|
|
let reg_sizes: Vec<usize> = snaps.iter().map(|(_, s)| s.registry_size).collect();
|
||
|
|
let tomb_counts: Vec<usize> = snaps.iter().map(|(_, s)| s.registry_tombstone_count).collect();
|
||
|
|
let alive: Vec<bool> = snaps.iter().map(|(_, s)| s.is_alive).collect();
|
||
|
|
let members: Vec<usize> = snaps.iter().map(|(_, s)| s.member_count).collect();
|
||
|
|
eprintln!("Round {}: alive={alive:?} members={members:?} registry={reg_sizes:?} tombstones={tomb_counts:?}", round_idx + 1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check membership change events
|
||
|
|
let dead_events: Vec<_> = trace.events.iter()
|
||
|
|
.filter(|e| matches!(&e.kind, simulation::distribution::trace::DistributionEventKind::MembershipChanged { new_state, .. } if new_state == "Dead"))
|
||
|
|
.collect();
|
||
|
|
eprintln!("Dead events: {}", dead_events.len());
|
||
|
|
for e in &dead_events {
|
||
|
|
if let simulation::distribution::trace::DistributionEventKind::MembershipChanged { target, new_state } = &e.kind {
|
||
|
|
eprintln!(" tick={} node={} declared {target} as {new_state}", e.tick, e.node_name);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check final nodes' resolve_name
|
||
|
|
for (i, node) in nodes.iter().enumerate() {
|
||
|
|
match node {
|
||
|
|
Some(n) => {
|
||
|
|
let res = n.resolve_name("svc");
|
||
|
|
eprintln!("Node {i}: resolve_name('svc') = {res:?}, registry_size={}, tombstones={}",
|
||
|
|
n.registry().len(), n.registry().tombstone_count());
|
||
|
|
}
|
||
|
|
None => eprintln!("Node {i}: DEAD"),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|