refactor: extract NATS.Server.Gateways.Tests project

Move 25 gateway-related test files from NATS.Server.Tests into a
dedicated NATS.Server.Gateways.Tests project. Update namespaces,
replace private ReadUntilAsync with SocketTestHelper from TestUtilities,
inline TestServerFactory usage, add InternalsVisibleTo, and register
the project in the solution file. All 261 tests pass.
This commit is contained in:
Joseph Doherty
2026-03-12 15:10:50 -04:00
parent a6be5e11ed
commit 9972b74bc3
29 changed files with 101 additions and 58 deletions

View File

@@ -0,0 +1,163 @@
using Microsoft.Extensions.Logging.Abstractions;
using NATS.Server.Configuration;
using NATS.Server.Gateways;
using Shouldly;
namespace NATS.Server.Gateways.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);
}