use tracing_test::traced_test;
use super::*;
#[tokio::test]
#[traced_test]
async fn test_record_failure_increments_count() {
let (monitor, _rx) = RaftHealthMonitor::new(3);
let node_id = 42;
monitor.record_failure(node_id).await;
monitor.record_failure(node_id).await;
let count = monitor.failure_counts.get(&node_id).map(|v| *v).unwrap_or(0);
assert_eq!(count, 2);
}
#[tokio::test]
#[traced_test]
async fn test_record_success_resets_count() {
let (monitor, _rx) = RaftHealthMonitor::new(3);
let node_id = 7;
monitor.record_failure(node_id).await;
monitor.record_failure(node_id).await;
monitor.record_success(node_id).await;
let count = monitor.failure_counts.get(&node_id);
assert!(count.is_none());
}
#[tokio::test]
#[traced_test]
async fn test_zombie_signal_fires_at_threshold() {
let (monitor, mut rx) = RaftHealthMonitor::new(2);
let node1 = 1;
let node2 = 2;
monitor.record_failure(node1).await;
assert!(rx.try_recv().is_err(), "no signal before threshold");
monitor.record_failure(node2).await;
assert!(rx.try_recv().is_err(), "no signal before threshold");
monitor.record_failure(node1).await;
let detected = rx.try_recv().expect("signal must fire at threshold");
assert_eq!(detected, node1);
monitor.record_failure(node1).await;
assert!(
rx.try_recv().is_err(),
"no duplicate signal after threshold"
);
}
#[tokio::test]
#[traced_test]
async fn test_record_success_clears_failure_count() {
let (monitor, mut rx) = RaftHealthMonitor::new(2);
let node_id = 7;
monitor.record_failure(node_id).await;
monitor.record_success(node_id).await;
monitor.record_failure(node_id).await;
assert!(rx.try_recv().is_err(), "counter reset by success");
}
#[tokio::test]
#[traced_test]
async fn test_zombie_signal_re_triggers_after_signal_lost() {
let (monitor, mut rx) = RaftHealthMonitor::new(2);
let node_id = 1;
monitor.record_failure(node_id).await;
monitor.record_failure(node_id).await;
assert_eq!(rx.try_recv().ok(), Some(node_id), "first signal must fire");
monitor.record_failure(node_id).await;
monitor.record_failure(node_id).await;
assert_eq!(
rx.try_recv().ok(),
Some(node_id),
"zombie signal must re-trigger after counter reset — peer is still failing"
);
}
#[tokio::test]
#[traced_test]
async fn test_zombie_revoked_by_recovery() {
let (monitor, mut rx) = RaftHealthMonitor::new(2);
let node_id = 1;
monitor.record_failure(node_id).await;
monitor.record_failure(node_id).await;
assert_eq!(rx.try_recv().ok(), Some(node_id), "signal must be queued");
monitor.record_success(node_id).await;
assert!(
!monitor.is_zombie_valid(node_id),
"zombie must be revoked by record_success — bridge task must not forward it"
);
}