Files
natsdotnet/tests/NATS.Server.Raft.Tests/Raft/RaftSubjectsTests.cs
Joseph Doherty edf9ed770e refactor: extract NATS.Server.Raft.Tests project
Move 43 Raft consensus test files (8 root-level + 35 in Raft/ subfolder)
from NATS.Server.Tests into a dedicated NATS.Server.Raft.Tests project.
Update namespaces, add InternalsVisibleTo, and fix timing/exception
handling issues in moved test files.
2026-03-12 15:36:02 -04:00

156 lines
5.2 KiB
C#

using NATS.Server.Raft;
namespace NATS.Server.Raft.Tests.Raft;
/// <summary>
/// Verifies that RaftSubjects produces the exact $NRG.* subject strings
/// defined in Go's raft.go constants.
///
/// Go reference: golang/nats-server/server/raft.go:2161-2169
/// raftAllSubj = "$NRG.>"
/// raftVoteSubj = "$NRG.V.%s"
/// raftAppendSubj = "$NRG.AE.%s"
/// raftPropSubj = "$NRG.P.%s"
/// raftRemovePeerSubj = "$NRG.RP.%s"
/// raftReply = "$NRG.R.%s"
/// raftCatchupReply = "$NRG.CR.%s"
/// </summary>
public class RaftSubjectsTests
{
// Go: server/raft.go:2162 — raftAllSubj = "$NRG.>"
[Fact]
public void All_constant_matches_go_raftAllSubj()
{
RaftSubjects.All.ShouldBe("$NRG.>");
}
// Go: server/raft.go:2163 — raftVoteSubj = "$NRG.V.%s"
[Fact]
public void Vote_formats_subject_with_group()
{
RaftSubjects.Vote("mygroup").ShouldBe("$NRG.V.mygroup");
}
// Go: server/raft.go:2163 — fmt.Sprintf(raftVoteSubj, n.group)
[Fact]
public void Vote_uses_group_verbatim()
{
RaftSubjects.Vote("meta").ShouldBe("$NRG.V.meta");
RaftSubjects.Vote("stream-A").ShouldBe("$NRG.V.stream-A");
RaftSubjects.Vote("_raft_").ShouldBe("$NRG.V._raft_");
}
// Go: server/raft.go:2164 — raftAppendSubj = "$NRG.AE.%s"
[Fact]
public void AppendEntry_formats_subject_with_group()
{
RaftSubjects.AppendEntry("mygroup").ShouldBe("$NRG.AE.mygroup");
}
// Go: server/raft.go:2164 — fmt.Sprintf(raftAppendSubj, n.group)
[Fact]
public void AppendEntry_uses_group_verbatim()
{
RaftSubjects.AppendEntry("meta").ShouldBe("$NRG.AE.meta");
RaftSubjects.AppendEntry("stream-B").ShouldBe("$NRG.AE.stream-B");
}
// Go: server/raft.go:2165 — raftPropSubj = "$NRG.P.%s"
[Fact]
public void Proposal_formats_subject_with_group()
{
RaftSubjects.Proposal("mygroup").ShouldBe("$NRG.P.mygroup");
}
// Go: server/raft.go:2165 — fmt.Sprintf(raftPropSubj, n.group)
[Fact]
public void Proposal_uses_group_verbatim()
{
RaftSubjects.Proposal("meta").ShouldBe("$NRG.P.meta");
RaftSubjects.Proposal("consumer-1").ShouldBe("$NRG.P.consumer-1");
}
// Go: server/raft.go:2166 — raftRemovePeerSubj = "$NRG.RP.%s"
[Fact]
public void RemovePeer_formats_subject_with_group()
{
RaftSubjects.RemovePeer("mygroup").ShouldBe("$NRG.RP.mygroup");
}
// Go: server/raft.go:2166 — fmt.Sprintf(raftRemovePeerSubj, n.group)
[Fact]
public void RemovePeer_uses_group_verbatim()
{
RaftSubjects.RemovePeer("meta").ShouldBe("$NRG.RP.meta");
RaftSubjects.RemovePeer("stream-C").ShouldBe("$NRG.RP.stream-C");
}
// Go: server/raft.go:2167 — raftReply = "$NRG.R.%s"
[Fact]
public void Reply_formats_subject_with_id()
{
RaftSubjects.Reply("abc123").ShouldBe("$NRG.R.abc123");
}
// Go: server/raft.go:2167 — fmt.Sprintf(raftReply, b[:])
[Fact]
public void Reply_uses_id_verbatim()
{
RaftSubjects.Reply("ABCDEFGH").ShouldBe("$NRG.R.ABCDEFGH");
RaftSubjects.Reply("00000001").ShouldBe("$NRG.R.00000001");
}
// Go: server/raft.go:2168 — raftCatchupReply = "$NRG.CR.%s"
[Fact]
public void CatchupReply_formats_subject_with_id()
{
RaftSubjects.CatchupReply("xyz789").ShouldBe("$NRG.CR.xyz789");
}
// Go: server/raft.go:2168 — fmt.Sprintf(raftCatchupReply, b[:])
[Fact]
public void CatchupReply_uses_id_verbatim()
{
RaftSubjects.CatchupReply("ABCDEFGH").ShouldBe("$NRG.CR.ABCDEFGH");
RaftSubjects.CatchupReply("00000001").ShouldBe("$NRG.CR.00000001");
}
// Verify that subjects for different groups are distinct (no collisions)
[Fact]
public void Subjects_for_different_groups_are_distinct()
{
RaftSubjects.Vote("group1").ShouldNotBe(RaftSubjects.Vote("group2"));
RaftSubjects.AppendEntry("group1").ShouldNotBe(RaftSubjects.AppendEntry("group2"));
RaftSubjects.Proposal("group1").ShouldNotBe(RaftSubjects.Proposal("group2"));
RaftSubjects.RemovePeer("group1").ShouldNotBe(RaftSubjects.RemovePeer("group2"));
}
// Verify that different verb subjects for the same group are distinct
[Fact]
public void Different_verbs_for_same_group_are_distinct()
{
var group = "meta";
var subjects = new[]
{
RaftSubjects.Vote(group),
RaftSubjects.AppendEntry(group),
RaftSubjects.Proposal(group),
RaftSubjects.RemovePeer(group),
};
subjects.Distinct().Count().ShouldBe(subjects.Length);
}
// All group subjects must be sub-subjects of the wildcard $NRG.>
[Fact]
public void All_group_subjects_are_under_NRG_namespace()
{
var group = "g";
RaftSubjects.Vote(group).ShouldStartWith("$NRG.");
RaftSubjects.AppendEntry(group).ShouldStartWith("$NRG.");
RaftSubjects.Proposal(group).ShouldStartWith("$NRG.");
RaftSubjects.RemovePeer(group).ShouldStartWith("$NRG.");
RaftSubjects.Reply("id").ShouldStartWith("$NRG.");
RaftSubjects.CatchupReply("id").ShouldStartWith("$NRG.");
}
}