using NATS.Server.JetStream.Cluster; namespace NATS.Server.JetStream.Tests.JetStream.Cluster; public class JetStreamLeadershipTests { [Fact] public void ProcessLeaderChange_clears_inflight_on_step_down() { var meta = new JetStreamMetaGroup(3); meta.TrackInflightStreamProposal("ACC", new StreamAssignment { StreamName = "s1", Group = new RaftGroup { Name = "rg", Peers = ["n1", "n2", "n3"] }, }); meta.ProcessLeaderChange(isLeader: false); meta.InflightStreamCount.ShouldBe(0); } [Fact] public void ProcessLeaderChange_fires_event_on_become_leader() { var meta = new JetStreamMetaGroup(3); var leaderChanged = false; meta.OnLeaderChange += (isLeader) => leaderChanged = true; meta.ProcessLeaderChange(isLeader: true); leaderChanged.ShouldBeTrue(); } [Fact] public void ProcessLeaderChange_fires_event_on_step_down() { var meta = new JetStreamMetaGroup(3); bool? receivedIsLeader = null; meta.OnLeaderChange += (isLeader) => receivedIsLeader = isLeader; meta.ProcessLeaderChange(isLeader: false); receivedIsLeader.ShouldNotBeNull(); receivedIsLeader.Value.ShouldBeFalse(); } [Fact] public void StepDown_triggers_leader_change_event() { var meta = new JetStreamMetaGroup(3); bool? receivedIsLeader = null; meta.OnLeaderChange += (isLeader) => receivedIsLeader = isLeader; meta.StepDown(); receivedIsLeader.ShouldNotBeNull(); receivedIsLeader.Value.ShouldBeFalse(); } [Fact] public void StepDown_clears_inflight_via_process_leader_change() { var meta = new JetStreamMetaGroup(3); meta.TrackInflightStreamProposal("ACC", new StreamAssignment { StreamName = "s1", Group = new RaftGroup { Name = "rg", Peers = ["n1", "n2", "n3"] }, }); meta.TrackInflightConsumerProposal("ACC", "s1", "c1"); meta.StepDown(); meta.InflightStreamCount.ShouldBe(0); meta.InflightConsumerCount.ShouldBe(0); } [Fact] public void BecomeLeader_makes_IsLeader_true() { var meta = new JetStreamMetaGroup(3); meta.StepDown(); // move leader away from self meta.IsLeader().ShouldBeFalse(); meta.BecomeLeader(); meta.IsLeader().ShouldBeTrue(); } [Fact] public void OnLeaderChange_not_fired_when_no_subscribers() { // Should not throw when no handlers attached var meta = new JetStreamMetaGroup(3); Should.NotThrow(() => meta.ProcessLeaderChange(isLeader: true)); Should.NotThrow(() => meta.ProcessLeaderChange(isLeader: false)); } }