refactor: extract NATS.Server.Monitoring.Tests project
Move 39 monitoring, events, and system endpoint test files from NATS.Server.Tests into a dedicated NATS.Server.Monitoring.Tests project. Update namespaces, replace private GetFreePort/ReadUntilAsync with TestUtilities shared helpers, add InternalsVisibleTo, and register in the solution file. All 439 tests pass.
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
// Go reference: server/monitor.go — closedClients ring buffer, ClosedState tracking.
|
||||
// These tests verify the fixed-size ring buffer used to track recently closed connections
|
||||
// for the /connz?state=closed monitoring endpoint.
|
||||
|
||||
using NATS.Server.Monitoring;
|
||||
|
||||
namespace NATS.Server.Monitoring.Tests.Monitoring;
|
||||
|
||||
public class ClosedConnectionRingBufferTests
|
||||
{
|
||||
// -----------------------------------------------------------------------
|
||||
// Helpers
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
private static ClosedClient MakeEntry(ulong cid, string reason = "normal") => new()
|
||||
{
|
||||
Cid = cid,
|
||||
Ip = "127.0.0.1",
|
||||
Port = 4222,
|
||||
Start = DateTime.UtcNow.AddSeconds(-10),
|
||||
Stop = DateTime.UtcNow,
|
||||
Reason = reason,
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 1. Add_IncreasesCount
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Adding entries should increase Count up to capacity.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Add_IncreasesCount()
|
||||
{
|
||||
var buf = new ClosedConnectionRingBuffer(capacity: 10);
|
||||
|
||||
buf.Count.ShouldBe(0);
|
||||
|
||||
buf.Add(MakeEntry(1));
|
||||
buf.Count.ShouldBe(1);
|
||||
|
||||
buf.Add(MakeEntry(2));
|
||||
buf.Count.ShouldBe(2);
|
||||
|
||||
buf.Add(MakeEntry(3));
|
||||
buf.Count.ShouldBe(3);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 2. Add_RingOverwrite_CapacityNotExceeded
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// When capacity is exceeded the count stays at capacity (oldest entry is overwritten).
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Add_RingOverwrite_CapacityNotExceeded()
|
||||
{
|
||||
const int capacity = 5;
|
||||
var buf = new ClosedConnectionRingBuffer(capacity);
|
||||
|
||||
for (var i = 1; i <= capacity + 3; i++)
|
||||
buf.Add(MakeEntry((ulong)i));
|
||||
|
||||
buf.Count.ShouldBe(capacity);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 3. GetAll_ReturnsNewestFirst
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// GetAll should return entries ordered newest-first.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void GetAll_ReturnsNewestFirst()
|
||||
{
|
||||
var buf = new ClosedConnectionRingBuffer(capacity: 10);
|
||||
|
||||
buf.Add(MakeEntry(1));
|
||||
buf.Add(MakeEntry(2));
|
||||
buf.Add(MakeEntry(3));
|
||||
|
||||
var all = buf.GetAll();
|
||||
|
||||
all.Count.ShouldBe(3);
|
||||
all[0].Cid.ShouldBe(3UL); // newest
|
||||
all[1].Cid.ShouldBe(2UL);
|
||||
all[2].Cid.ShouldBe(1UL); // oldest
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 4. GetAll_EmptyBuffer_ReturnsEmpty
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// GetAll on an empty buffer should return an empty list.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void GetAll_EmptyBuffer_ReturnsEmpty()
|
||||
{
|
||||
var buf = new ClosedConnectionRingBuffer(capacity: 10);
|
||||
|
||||
var all = buf.GetAll();
|
||||
|
||||
all.ShouldBeEmpty();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 5. GetRecent_ReturnsRequestedCount
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// GetRecent(n) where n <= Count should return exactly n entries.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void GetRecent_ReturnsRequestedCount()
|
||||
{
|
||||
var buf = new ClosedConnectionRingBuffer(capacity: 10);
|
||||
for (var i = 1; i <= 8; i++)
|
||||
buf.Add(MakeEntry((ulong)i));
|
||||
|
||||
var recent = buf.GetRecent(3);
|
||||
|
||||
recent.Count.ShouldBe(3);
|
||||
recent[0].Cid.ShouldBe(8UL); // newest
|
||||
recent[1].Cid.ShouldBe(7UL);
|
||||
recent[2].Cid.ShouldBe(6UL);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 6. GetRecent_LessThanAvailable_ReturnsAll
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// GetRecent(n) where n > Count should return all available entries.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void GetRecent_LessThanAvailable_ReturnsAll()
|
||||
{
|
||||
var buf = new ClosedConnectionRingBuffer(capacity: 10);
|
||||
|
||||
buf.Add(MakeEntry(1));
|
||||
buf.Add(MakeEntry(2));
|
||||
|
||||
var recent = buf.GetRecent(100);
|
||||
|
||||
recent.Count.ShouldBe(2);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 7. TotalClosed_TracksAllAdditions
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// TotalClosed should increment for every Add, even after the ring wraps around.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void TotalClosed_TracksAllAdditions()
|
||||
{
|
||||
const int capacity = 4;
|
||||
var buf = new ClosedConnectionRingBuffer(capacity);
|
||||
|
||||
buf.TotalClosed.ShouldBe(0L);
|
||||
|
||||
for (var i = 1; i <= 10; i++)
|
||||
buf.Add(MakeEntry((ulong)i));
|
||||
|
||||
buf.TotalClosed.ShouldBe(10L);
|
||||
buf.Count.ShouldBe(capacity); // buffer is full but total reflects all 10
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 8. Clear_ResetsCountAndBuffer
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Clear should reset Count to zero and GetAll should return an empty list.
|
||||
/// TotalClosed is intentionally not reset because it is a running lifetime counter.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Clear_ResetsCountAndBuffer()
|
||||
{
|
||||
var buf = new ClosedConnectionRingBuffer(capacity: 10);
|
||||
|
||||
buf.Add(MakeEntry(1));
|
||||
buf.Add(MakeEntry(2));
|
||||
buf.Add(MakeEntry(3));
|
||||
buf.TotalClosed.ShouldBe(3L);
|
||||
|
||||
buf.Clear();
|
||||
|
||||
buf.Count.ShouldBe(0);
|
||||
buf.GetAll().ShouldBeEmpty();
|
||||
// TotalClosed is a lifetime counter; it is not reset by Clear.
|
||||
buf.TotalClosed.ShouldBe(3L);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 9. Capacity_ReturnsConfiguredSize
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Capacity should reflect the value passed to the constructor.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Capacity_ReturnsConfiguredSize()
|
||||
{
|
||||
var buf = new ClosedConnectionRingBuffer(capacity: 42);
|
||||
buf.Capacity.ShouldBe(42);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 10. Add_WrapsCorrectly
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// After adding capacity+1 items the oldest entry (cid=1) should no longer be present,
|
||||
/// and the buffer should contain the most recent 'capacity' items.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Add_WrapsCorrectly()
|
||||
{
|
||||
const int capacity = 5;
|
||||
var buf = new ClosedConnectionRingBuffer(capacity);
|
||||
|
||||
for (var i = 1; i <= capacity + 1; i++)
|
||||
buf.Add(MakeEntry((ulong)i));
|
||||
|
||||
var all = buf.GetAll();
|
||||
|
||||
all.Count.ShouldBe(capacity);
|
||||
|
||||
// cid=1 (the oldest) should have been overwritten
|
||||
all.Any(e => e.Cid == 1UL).ShouldBeFalse();
|
||||
|
||||
// The newest entry (cid=capacity+1) should be first
|
||||
all[0].Cid.ShouldBe((ulong)(capacity + 1));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user