// Copyright 2012-2026 The NATS Authors // Licensed under the Apache License, Version 2.0 using Shouldly; namespace ZB.MOM.NatsNet.Server.Tests.JetStream; public sealed class RaftNodeCoreTests { [Fact] public void SnapshotHelpers_WhenEncodedAndLoaded_ShouldRoundTrip() { var storeDir = Path.Combine(Path.GetTempPath(), $"raft-node-core-{Guid.NewGuid():N}"); var raft = new Raft { StoreDir = storeDir, Term_ = 3, Applied_ = 9, PApplied = 7, Wps = [1, 2, 3], }; try { var checkpoint = raft.CreateSnapshotCheckpointLocked(force: true); checkpoint.ShouldNotBeNull(); var snapshot = new Snapshot { LastTerm = 3, LastIndex = 9, PeerState = [7, 8], Data = [9, 10, 11], }; raft.InstallSnapshotInternal(snapshot).ShouldBeNull(); var (loaded, error) = raft.LoadLastSnapshot(); error.ShouldBeNull(); loaded.ShouldNotBeNull(); loaded!.LastTerm.ShouldBe(3UL); loaded.LastIndex.ShouldBe(9UL); loaded.PeerState.ShouldBe([7, 8]); loaded.Data.ShouldBe([9, 10, 11]); raft.SetupLastSnapshot().ShouldBeNull(); raft.PIndex.ShouldBe(9UL); raft.PTerm.ShouldBe(3UL); } finally { if (Directory.Exists(storeDir)) { Directory.Delete(storeDir, recursive: true); } } } [Fact] public void LeadershipHelpers_WhenSteppingDownAndSelectingLeader_ShouldUpdateState() { var raft = new Raft { Id = "N1", StateValue = (int)RaftState.Candidate, Peers_ = new Dictionary { ["N2"] = new() { Li = 3 }, ["N3"] = new() { Li = 7 }, }, }; raft.StepdownLocked("N3"); raft.State().ShouldBe(RaftState.Follower); raft.LeaderId.ShouldBe("N3"); raft.SelectNextLeader().ShouldBe("N3"); } [Fact] public void CampaignHelpers_WhenLeaderOrFollower_ShouldReturnExpectedOutcome() { var raft = new Raft { StateValue = (int)RaftState.Leader, }; raft.CampaignInternal(TimeSpan.FromMilliseconds(200)).ShouldNotBeNull(); raft.XferCampaign().ShouldNotBeNull(); raft.StateValue = (int)RaftState.Follower; raft.CampaignInternal(TimeSpan.FromMilliseconds(200)).ShouldBeNull(); raft.State().ShouldBe(RaftState.Candidate); } [Fact] public void ProgressHelpers_WhenCatchupAndKnownPeersChange_ShouldTrackFlags() { var raft = new Raft { Commit = 10, Applied_ = 8, Catchup = new CatchupState(), }; raft.IsCatchingUp().ShouldBeTrue(); raft.IsCurrent(includeForwardProgress: true).ShouldBeFalse(); raft.Catchup = null; raft.UpdateKnownPeersLocked(["N2", "N3"]); raft.Peers_.Count.ShouldBe(2); raft.RandCampaignTimeout().ShouldBeGreaterThan(TimeSpan.Zero); } }