feat: add gateway connection registration with state tracking (Gap 11.7)
Adds GatewayConnectionState enum, GatewayRegistration record with atomic message counters, and a full registry API on GatewayManager: RegisterGateway, UpdateState, GetRegistration, GetAllRegistrations, UnregisterGateway, GetConnectedGatewayCount, IncrementMessagesSent, IncrementMessagesReceived. Covers 11 new tests in GatewayRegistrationTests.cs (all passing).
This commit is contained in:
163
tests/NATS.Server.Tests/Gateways/GatewayRegistrationTests.cs
Normal file
163
tests/NATS.Server.Tests/Gateways/GatewayRegistrationTests.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using NATS.Server.Configuration;
|
||||
using NATS.Server.Gateways;
|
||||
using Shouldly;
|
||||
|
||||
namespace NATS.Server.Tests.Gateways;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for gateway connection registration and state tracking (Gap 11.7).
|
||||
/// Go reference: server/gateway.go srvGateway / outboundGateway struct and gwConnState transitions.
|
||||
/// </summary>
|
||||
public class GatewayRegistrationTests
|
||||
{
|
||||
// Go: server/gateway.go solicitGateway creates an outbound entry before dialling.
|
||||
[Fact]
|
||||
public void RegisterGateway_creates_registration()
|
||||
{
|
||||
var manager = BuildManager();
|
||||
|
||||
manager.RegisterGateway("gw-east");
|
||||
|
||||
manager.GetRegistration("gw-east").ShouldNotBeNull();
|
||||
}
|
||||
|
||||
// Go: server/gateway.go initial gwConnState is gwConnecting before the dial completes.
|
||||
[Fact]
|
||||
public void RegisterGateway_starts_in_connecting_state()
|
||||
{
|
||||
var manager = BuildManager();
|
||||
|
||||
manager.RegisterGateway("gw-east");
|
||||
var reg = manager.GetRegistration("gw-east")!;
|
||||
|
||||
reg.State.ShouldBe(GatewayConnectionState.Connecting);
|
||||
}
|
||||
|
||||
// Go: server/gateway.go gwConnState transitions (Connecting → Connected, Connected → Disconnected, etc.).
|
||||
[Fact]
|
||||
public void UpdateState_changes_state()
|
||||
{
|
||||
var manager = BuildManager();
|
||||
manager.RegisterGateway("gw-east");
|
||||
|
||||
manager.UpdateState("gw-east", GatewayConnectionState.Connected);
|
||||
|
||||
manager.GetRegistration("gw-east")!.State.ShouldBe(GatewayConnectionState.Connected);
|
||||
}
|
||||
|
||||
// Go: server/gateway.go getOutboundGatewayConnection returns nil for unknown names.
|
||||
[Fact]
|
||||
public void GetRegistration_returns_null_for_unknown()
|
||||
{
|
||||
var manager = BuildManager();
|
||||
|
||||
manager.GetRegistration("does-not-exist").ShouldBeNull();
|
||||
}
|
||||
|
||||
// Go: server/gateway.go server.gateways map stores all configured outbound gateways.
|
||||
[Fact]
|
||||
public void GetAllRegistrations_returns_all()
|
||||
{
|
||||
var manager = BuildManager();
|
||||
manager.RegisterGateway("gw-east");
|
||||
manager.RegisterGateway("gw-west");
|
||||
|
||||
var all = manager.GetAllRegistrations();
|
||||
|
||||
all.Count.ShouldBe(2);
|
||||
all.Select(r => r.Name).ShouldContain("gw-east");
|
||||
all.Select(r => r.Name).ShouldContain("gw-west");
|
||||
}
|
||||
|
||||
// Go: server/gateway.go outboundGateway teardown removes entry from server.gateways.
|
||||
[Fact]
|
||||
public void UnregisterGateway_removes_registration()
|
||||
{
|
||||
var manager = BuildManager();
|
||||
manager.RegisterGateway("gw-east");
|
||||
|
||||
manager.UnregisterGateway("gw-east");
|
||||
|
||||
manager.GetRegistration("gw-east").ShouldBeNull();
|
||||
}
|
||||
|
||||
// Go: server/gateway.go numOutboundGatewayConnections counts only fully-connected entries.
|
||||
[Fact]
|
||||
public void GetConnectedGatewayCount_counts_connected_only()
|
||||
{
|
||||
var manager = BuildManager();
|
||||
manager.RegisterGateway("gw-east"); // Connecting
|
||||
manager.RegisterGateway("gw-west"); // Connecting
|
||||
manager.RegisterGateway("gw-south"); // → Connected
|
||||
|
||||
manager.UpdateState("gw-south", GatewayConnectionState.Connected);
|
||||
|
||||
manager.GetConnectedGatewayCount().ShouldBe(1);
|
||||
}
|
||||
|
||||
// Go: server/gateway.go outboundGateway.msgs.outMsgs incremented per forwarded message.
|
||||
[Fact]
|
||||
public void IncrementMessagesSent_increments()
|
||||
{
|
||||
var manager = BuildManager();
|
||||
manager.RegisterGateway("gw-east");
|
||||
|
||||
manager.IncrementMessagesSent("gw-east");
|
||||
manager.IncrementMessagesSent("gw-east");
|
||||
manager.IncrementMessagesSent("gw-east");
|
||||
|
||||
manager.GetRegistration("gw-east")!.MessagesSent.ShouldBe(3L);
|
||||
}
|
||||
|
||||
// Go: server/gateway.go inboundGateway.msgs.inMsgs incremented per received message.
|
||||
[Fact]
|
||||
public void IncrementMessagesReceived_increments()
|
||||
{
|
||||
var manager = BuildManager();
|
||||
manager.RegisterGateway("gw-east");
|
||||
|
||||
manager.IncrementMessagesReceived("gw-east");
|
||||
manager.IncrementMessagesReceived("gw-east");
|
||||
|
||||
manager.GetRegistration("gw-east")!.MessagesReceived.ShouldBe(2L);
|
||||
}
|
||||
|
||||
// Go: server/gateway.go outboundGateway.remoteName / remoteIP stored for monitoring.
|
||||
[Fact]
|
||||
public void Registration_stores_remote_address()
|
||||
{
|
||||
var manager = BuildManager();
|
||||
|
||||
manager.RegisterGateway("gw-east", remoteAddress: "10.0.0.1:7222");
|
||||
|
||||
manager.GetRegistration("gw-east")!.RemoteAddress.ShouldBe("10.0.0.1:7222");
|
||||
}
|
||||
|
||||
// Go: server/gateway.go gwConnState Connected transition stamps connected-at time.
|
||||
[Fact]
|
||||
public void UpdateState_to_connected_stamps_ConnectedAtUtc()
|
||||
{
|
||||
var manager = BuildManager();
|
||||
manager.RegisterGateway("gw-east");
|
||||
var before = DateTime.UtcNow;
|
||||
|
||||
manager.UpdateState("gw-east", GatewayConnectionState.Connected);
|
||||
|
||||
var after = DateTime.UtcNow;
|
||||
var stamp = manager.GetRegistration("gw-east")!.ConnectedAtUtc;
|
||||
stamp.ShouldBeGreaterThanOrEqualTo(before);
|
||||
stamp.ShouldBeLessThanOrEqualTo(after);
|
||||
}
|
||||
|
||||
// ── Helpers ──────────────────────────────────────────────────────────────
|
||||
|
||||
private static GatewayManager BuildManager() =>
|
||||
new GatewayManager(
|
||||
new GatewayOptions { Name = "TEST", Host = "127.0.0.1", Port = 0 },
|
||||
new ServerStats(),
|
||||
"S1",
|
||||
_ => { },
|
||||
_ => { },
|
||||
NullLogger<GatewayManager>.Instance);
|
||||
}
|
||||
Reference in New Issue
Block a user