using NATS.Server.Monitoring; namespace NATS.Server.Monitoring.Tests.Monitoring; /// /// Unit tests for ConnzSortOption enum, ConnzSorter.Parse, and ConnzSorter.Sort. /// All tests exercise the types in isolation — no running server required. /// Go reference: monitor_test.go — TestConnzSortedByCid, TestConnzSortedByBytesTo, /// TestConnzSortedByMsgsFrom, TestConnzSortedByStart, monitor_sort_opts.go. /// public class ConnzSortTests { // ----------------------------------------------------------------------- // Helper — build a ConnInfo with specific field values // ----------------------------------------------------------------------- private static ConnInfo MakeConn( ulong cid = 1, long outBytes = 0, long inBytes = 0, long outMsgs = 0, long inMsgs = 0, uint numSubs = 0, int pending = 0, DateTime connectedAt = default, DateTime lastActivity = default) => new() { Cid = cid, OutBytes = outBytes, InBytes = inBytes, OutMsgs = outMsgs, InMsgs = inMsgs, NumSubs = numSubs, Pending = pending, Start = connectedAt == default ? DateTime.UtcNow : connectedAt, LastActivity = lastActivity == default ? DateTime.UtcNow : lastActivity, }; // ----------------------------------------------------------------------- // ConnzSorter.Parse tests // ----------------------------------------------------------------------- [Fact] public void Parse_ConnectionId_Default() { // Go reference: monitor_sort_opts.go — empty/unknown value defaults to CID sort ConnzSorter.Parse(null).ShouldBe(ConnzSortOption.ConnectionId); ConnzSorter.Parse("").ShouldBe(ConnzSortOption.ConnectionId); ConnzSorter.Parse(" ").ShouldBe(ConnzSortOption.ConnectionId); ConnzSorter.Parse("cid").ShouldBe(ConnzSortOption.ConnectionId); } [Fact] public void Parse_BytesTo_Parsed() { // Go reference: monitor_sort_opts.go — "bytes_to" => ByBytesTo ConnzSorter.Parse("bytes_to").ShouldBe(ConnzSortOption.BytesTo); ConnzSorter.Parse("BYTES_TO").ShouldBe(ConnzSortOption.BytesTo); } [Fact] public void Parse_MsgsFrom_Parsed() { // Go reference: monitor_sort_opts.go — "msgs_from" => ByMsgsFrom ConnzSorter.Parse("msgs_from").ShouldBe(ConnzSortOption.MsgsFrom); ConnzSorter.Parse("MSGS_FROM").ShouldBe(ConnzSortOption.MsgsFrom); } [Fact] public void Parse_Start_Parsed() { // Go reference: monitor_sort_opts.go — "start" => ByStart ConnzSorter.Parse("start").ShouldBe(ConnzSortOption.Start); ConnzSorter.Parse("START").ShouldBe(ConnzSortOption.Start); } [Fact] public void Parse_Unknown_ReturnsDefault() { // Go reference: monitor_sort_opts.go — unrecognised string falls back to CID ConnzSorter.Parse("not_a_sort_key").ShouldBe(ConnzSortOption.ConnectionId); ConnzSorter.Parse("xyz").ShouldBe(ConnzSortOption.ConnectionId); ConnzSorter.Parse("RANDOM").ShouldBe(ConnzSortOption.ConnectionId); } // ----------------------------------------------------------------------- // ConnzSorter.Sort tests // ----------------------------------------------------------------------- [Fact] public void Sort_ByConnectionId_Ascending() { // Go reference: monitor_test.go TestConnzSortedByCid — CID ascending is default var conns = new[] { MakeConn(cid: 3), MakeConn(cid: 1), MakeConn(cid: 2), }; var result = ConnzSorter.Sort(conns, ConnzSortOption.ConnectionId); result.Count.ShouldBe(3); result[0].Cid.ShouldBe(1UL); result[1].Cid.ShouldBe(2UL); result[2].Cid.ShouldBe(3UL); } [Fact] public void Sort_ByBytesTo_Descending() { // Go reference: monitor_test.go TestConnzSortedByBytesTo — OutBytes descending var conns = new[] { MakeConn(cid: 1, outBytes: 100), MakeConn(cid: 2, outBytes: 300), MakeConn(cid: 3, outBytes: 200), }; var result = ConnzSorter.Sort(conns, ConnzSortOption.BytesTo); result.Count.ShouldBe(3); result[0].OutBytes.ShouldBe(300); result[1].OutBytes.ShouldBe(200); result[2].OutBytes.ShouldBe(100); } [Fact] public void Sort_ByStart_Ascending() { // Go reference: monitor_test.go TestConnzSortedByStart — ConnectedAt ascending var t0 = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc); var t1 = t0.AddMinutes(1); var t2 = t0.AddMinutes(2); var conns = new[] { MakeConn(cid: 1, connectedAt: t2), MakeConn(cid: 2, connectedAt: t0), MakeConn(cid: 3, connectedAt: t1), }; var result = ConnzSorter.Sort(conns, ConnzSortOption.Start); result.Count.ShouldBe(3); result[0].Start.ShouldBe(t0); result[1].Start.ShouldBe(t1); result[2].Start.ShouldBe(t2); } [Fact] public void Sort_ByMsgsFrom_Descending() { // Go reference: monitor_test.go TestConnzSortedByMsgsFrom — InMsgs descending var conns = new[] { MakeConn(cid: 1, inMsgs: 50), MakeConn(cid: 2, inMsgs: 200), MakeConn(cid: 3, inMsgs: 10), }; var result = ConnzSorter.Sort(conns, ConnzSortOption.MsgsFrom); result.Count.ShouldBe(3); result[0].InMsgs.ShouldBe(200); result[1].InMsgs.ShouldBe(50); result[2].InMsgs.ShouldBe(10); } [Fact] public void Sort_EmptyList_ReturnsEmpty() { // Sorting an empty input should not throw and should return an empty list. var result = ConnzSorter.Sort([], ConnzSortOption.BytesTo); result.ShouldBeEmpty(); } }