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.
156 lines
5.2 KiB
C#
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.");
|
|
}
|
|
}
|