Files
natsdotnet/tests/NATS.Server.Tests/Gateways/GatewayConnectionDirectionParityBatch2Tests.cs
Joseph Doherty c30e67a69d Fix E2E test gaps and add comprehensive E2E + parity test suites
- Fix pull consumer fetch: send original stream subject in HMSG (not inbox)
  so NATS client distinguishes data messages from control messages
- Fix MaxAge expiry: add background timer in StreamManager for periodic pruning
- Fix JetStream wire format: Go-compatible anonymous objects with string enums,
  proper offset-based pagination for stream/consumer list APIs
- Add 42 E2E black-box tests (core messaging, auth, TLS, accounts, JetStream)
- Add ~1000 parity tests across all subsystems (gaps closure)
- Update gap inventory docs to reflect implementation status
2026-03-12 14:09:23 -04:00

96 lines
3.1 KiB
C#

using Microsoft.Extensions.Logging.Abstractions;
using NATS.Server.Configuration;
namespace NATS.Server.Tests.Gateways;
public class GatewayConnectionDirectionParityBatch2Tests
{
[Fact]
public async Task Gateway_manager_tracks_inbound_and_outbound_connection_sets()
{
var a = await StartServerAsync(MakeGatewayOptions("GW-A"));
var b = await StartServerAsync(MakeGatewayOptions("GW-B", a.Server.GatewayListen));
try
{
await WaitForCondition(() =>
a.Server.NumInboundGateways() == 1 &&
b.Server.NumOutboundGateways() == 1,
10000);
a.Server.NumInboundGateways().ShouldBe(1);
a.Server.NumOutboundGateways().ShouldBe(0);
b.Server.NumOutboundGateways().ShouldBe(1);
b.Server.NumInboundGateways().ShouldBe(0);
var aManager = a.Server.GatewayManager;
var bManager = b.Server.GatewayManager;
aManager.ShouldNotBeNull();
bManager.ShouldNotBeNull();
aManager!.HasInbound(b.Server.ServerId).ShouldBeTrue();
bManager!.HasInbound(a.Server.ServerId).ShouldBeFalse();
bManager.GetOutboundGatewayConnection(a.Server.ServerId).ShouldNotBeNull();
bManager.GetOutboundGatewayConnection("does-not-exist").ShouldBeNull();
aManager.GetInboundGatewayConnections().Count.ShouldBe(1);
aManager.GetOutboundGatewayConnections().Count.ShouldBe(0);
bManager.GetOutboundGatewayConnections().Count.ShouldBe(1);
bManager.GetInboundGatewayConnections().Count.ShouldBe(0);
}
finally
{
await DisposeServers(a, b);
}
}
private static NatsOptions MakeGatewayOptions(string gatewayName, string? remote = null)
{
return new NatsOptions
{
Host = "127.0.0.1",
Port = 0,
Gateway = new GatewayOptions
{
Name = gatewayName,
Host = "127.0.0.1",
Port = 0,
Remotes = remote is null ? [] : [remote],
},
};
}
private static async Task<(NatsServer Server, CancellationTokenSource Cts)> StartServerAsync(NatsOptions opts)
{
var server = new NatsServer(opts, NullLoggerFactory.Instance);
var cts = new CancellationTokenSource();
_ = server.StartAsync(cts.Token);
await server.WaitForReadyAsync();
return (server, cts);
}
private static async Task DisposeServers(params (NatsServer Server, CancellationTokenSource Cts)[] servers)
{
foreach (var (server, cts) in servers)
{
await cts.CancelAsync();
server.Dispose();
cts.Dispose();
}
}
private static async Task WaitForCondition(Func<bool> predicate, int timeoutMs)
{
using var cts = new CancellationTokenSource(timeoutMs);
while (!cts.IsCancellationRequested)
{
if (predicate())
return;
await Task.Yield();
}
throw new TimeoutException("Condition not met.");
}
}