Files
natsnet/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/RaftNodeCoreTests.cs
2026-02-28 20:09:24 -05:00

112 lines
3.2 KiB
C#

// 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<string, Lps>
{
["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);
}
}