using System.Net; using System.Net.Sockets; using Microsoft.Extensions.Logging.Abstractions; using NATS.Server; namespace NATS.Server.Tests; public class ServerStatsTests : IAsyncLifetime { private readonly NatsServer _server; private readonly int _port; private readonly CancellationTokenSource _cts = new(); public ServerStatsTests() { _port = GetFreePort(); _server = new NatsServer(new NatsOptions { Port = _port }, NullLoggerFactory.Instance); } public async Task InitializeAsync() { _ = _server.StartAsync(_cts.Token); await _server.WaitForReadyAsync(); } public Task DisposeAsync() { _cts.Cancel(); _server.Dispose(); return Task.CompletedTask; } [Fact] public void Server_has_start_time() { _server.StartTime.ShouldNotBe(default); _server.StartTime.ShouldBeLessThanOrEqualTo(DateTime.UtcNow); } [Fact] public async Task Server_tracks_total_connections() { using var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); await sock.ConnectAsync(new IPEndPoint(IPAddress.Loopback, _port)); await Task.Delay(100); _server.Stats.TotalConnections.ShouldBeGreaterThanOrEqualTo(1); } [Fact] public async Task Server_stats_track_messages() { using var pub = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); await pub.ConnectAsync(new IPEndPoint(IPAddress.Loopback, _port)); var buf = new byte[4096]; await pub.ReceiveAsync(buf, SocketFlags.None); // INFO await pub.SendAsync("CONNECT {}\r\nSUB test 1\r\nPUB test 5\r\nhello\r\n"u8.ToArray()); await Task.Delay(200); _server.Stats.InMsgs.ShouldBeGreaterThanOrEqualTo(1); _server.Stats.InBytes.ShouldBeGreaterThanOrEqualTo(5); } [Fact] public async Task Client_has_metadata() { using var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); await sock.ConnectAsync(new IPEndPoint(IPAddress.Loopback, _port)); await Task.Delay(100); var client = _server.GetClients().First(); client.RemoteIp.ShouldNotBeNullOrEmpty(); client.RemotePort.ShouldBeGreaterThan(0); client.StartTime.ShouldNotBe(default); } private static int GetFreePort() { using var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sock.Bind(new IPEndPoint(IPAddress.Loopback, 0)); return ((IPEndPoint)sock.LocalEndPoint!).Port; } }