using NATS.Server.Raft; namespace NATS.Server.Tests.Raft; /// /// 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" /// 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."); } }