Add ConnzSortOption enum (ConnectionId, Start, BytesTo, BytesFrom, MsgsTo, MsgsFrom, Subscriptions, Pending, Uptime, Idle, LastActivity) and ConnzSorter static class with Parse(string?) and Sort(IEnumerable<ConnInfo>, ConnzSortOption, bool) methods. Add SortBy and SortDescending properties to ConnzFilterOptions and wire them through ConnzFilterOptions.Parse (?sort= and ?desc= query params). Add 10 unit tests in ConnzSortTests covering Parse defaults, known values, unknown string fallback, and sort ordering for key fields. Go reference: server/monitor_sort_opts.go, server/monitor.go Connz().
180 lines
5.9 KiB
C#
180 lines
5.9 KiB
C#
using NATS.Server.Monitoring;
|
|
|
|
namespace NATS.Server.Tests.Monitoring;
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
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();
|
|
}
|
|
}
|