use tokio::sync::watch;
use crate::Raft;
use crate::RoleEvent;
use crate::test_utils::MockBuilder;
use crate::test_utils::MockTypeConfig;
#[tokio::test]
async fn test_leader_discovered_event_handling() {
let (_graceful_tx, graceful_rx) = watch::channel(());
let mut raft: Raft<MockTypeConfig> = MockBuilder::new(graceful_rx).build_raft();
let (leader_tx, mut leader_rx) = watch::channel(None);
raft.register_leader_change_listener(leader_tx);
let leader_id = 3;
let term = 5;
raft.handle_role_event(RoleEvent::LeaderDiscovered(leader_id, term))
.await
.expect("Should handle LeaderDiscovered");
leader_rx.changed().await.expect("Should receive change notification");
let leader_info = *leader_rx.borrow();
assert!(leader_info.is_some());
let info = leader_info.unwrap();
assert_eq!(info.leader_id, leader_id);
assert_eq!(info.term, term);
}
#[tokio::test]
async fn test_leader_discovered_no_state_change() {
let (_graceful_tx, graceful_rx) = watch::channel(());
let mut raft: Raft<MockTypeConfig> = MockBuilder::new(graceful_rx).build_raft();
let initial_role = raft.role.as_i32();
raft.handle_role_event(RoleEvent::LeaderDiscovered(3, 5))
.await
.expect("Should handle LeaderDiscovered");
assert_eq!(raft.role.as_i32(), initial_role);
}
#[tokio::test]
async fn test_leader_discovered_multiple_listeners() {
let (_graceful_tx, graceful_rx) = watch::channel(());
let mut raft: Raft<MockTypeConfig> = MockBuilder::new(graceful_rx).build_raft();
let (tx, _rx) = watch::channel(None);
raft.register_leader_change_listener(tx.clone());
let mut rx1 = tx.subscribe();
let mut rx2 = tx.subscribe();
let leader_id = 2;
let term = 10;
raft.handle_role_event(RoleEvent::LeaderDiscovered(leader_id, term))
.await
.expect("Should handle LeaderDiscovered");
rx1.changed().await.expect("Subscriber 1 should receive");
rx2.changed().await.expect("Subscriber 2 should receive");
let info1 = (*rx1.borrow()).unwrap();
let info2 = (*rx2.borrow()).unwrap();
assert_eq!(info1.leader_id, leader_id);
assert_eq!(info1.term, term);
assert_eq!(info2.leader_id, leader_id);
assert_eq!(info2.term, term);
}
#[tokio::test]
async fn test_leader_discovered_with_deduplication() {
let (_graceful_tx, graceful_rx) = watch::channel(());
let mut raft: Raft<MockTypeConfig> = MockBuilder::new(graceful_rx).build_raft();
let (leader_tx, mut leader_rx) = watch::channel(None);
raft.register_leader_change_listener(leader_tx);
raft.handle_role_event(RoleEvent::LeaderDiscovered(2, 5))
.await
.expect("Should handle first");
raft.handle_role_event(RoleEvent::LeaderDiscovered(2, 5))
.await
.expect("Should handle second (duplicate)");
leader_rx.changed().await.expect("Should receive first change");
let info = (*leader_rx.borrow()).unwrap();
assert_eq!(info.leader_id, 2);
assert_eq!(info.term, 5);
tokio::select! {
_ = leader_rx.changed() => {
panic!("Should not receive duplicate notification");
}
_ = tokio::time::sleep(tokio::time::Duration::from_millis(100)) => {
}
}
}
#[test]
fn test_role_event_leader_discovered_creation() {
let leader_id = 5;
let term = 20;
let event = RoleEvent::LeaderDiscovered(leader_id, term);
match event {
RoleEvent::LeaderDiscovered(id, t) => {
assert_eq!(id, leader_id);
assert_eq!(t, term);
}
_ => panic!("Should be LeaderDiscovered variant"),
}
}