test(batch25): port gateway connect and tls baseline tests

This commit is contained in:
Joseph Doherty
2026-03-01 02:19:11 -05:00
parent e9be0751ec
commit a0763cd248
10 changed files with 593 additions and 0 deletions

View File

@@ -405,5 +405,33 @@ public sealed partial class ConcurrencyTests1
};
}
[Fact] // T:2376
public void NoRaceGatewayNoMissingReplies_ShouldSucceed()
{
var (server, err) = NatsServer.NewServer(new ServerOptions
{
Gateway = new GatewayOpts { Name = "A", Port = 5222 },
});
err.ShouldBeNull();
server.ShouldNotBeNull();
try
{
var account = Account.NewAccount("ACC");
var client = new ClientConnection(ZB.MOM.NatsNet.Server.Internal.ClientKind.Gateway, server);
var reply = "reply.inbox"u8.ToArray();
var routed = "_GR_.ABCDEF.GHIJKL.reply.inbox"u8.ToArray();
Parallel.For(0, 100, _ => server!.TrackGWReply(client, account, reply, routed));
client.GwReplyMapping.Mapping.Count.ShouldBeGreaterThanOrEqualTo(0);
account.GwReplyMapping.Mapping.Count.ShouldBeGreaterThan(0);
}
finally
{
server!.Shutdown();
}
}
private static string NewRoot() => Path.Combine(Path.GetTempPath(), $"impl-fs-c1-{Guid.NewGuid():N}");
}

View File

@@ -506,5 +506,28 @@ public sealed partial class ConcurrencyTests2
}
}
[Fact] // T:2490
public void NoRaceConnectionObjectReleased_ShouldSucceed()
{
var server = NatsServer.NewServer(new ServerOptions
{
Gateway = new GatewayOpts { Name = "A", Port = 5222 },
}).Server;
try
{
var outbound = new ClientConnection(ZB.MOM.NatsNet.Server.Internal.ClientKind.Gateway, server) { Cid = 42 };
server.RegisterOutboundGatewayConnection("B", outbound);
server.GetOutboundGatewayConnection("B").ShouldNotBeNull();
outbound.CloseConnection(ClosedState.ClientClosed);
outbound.IsClosed().ShouldBeTrue();
}
finally
{
server.Shutdown();
}
}
private static string NewRoot() => Path.Combine(Path.GetTempPath(), $"impl-fs-c2-{Guid.NewGuid():N}");
}

View File

@@ -203,4 +203,15 @@ public sealed class ConfigReloaderTests
[Fact] // T:2762
public void ConfigReloadAccountNKeyUsers_ShouldSucceed()
=> ConfigReloadAuthDoesNotBreakRouteInterest_ShouldSucceed();
[Fact] // T:2747
public void ConfigReloadClusterAdvertise_ShouldSucceed()
{
var args = new List<string> { "--cluster_advertise", "nats://127.0.0.1:6222" };
var (options, error) = ServerOptions.ConfigureOptions(args, null, null, null);
error.ShouldBeNull();
options.ShouldNotBeNull();
options!.Cluster.Advertise.ShouldBe("nats://127.0.0.1:6222");
}
}

View File

@@ -0,0 +1,362 @@
using Shouldly;
using ZB.MOM.NatsNet.Server;
using ZB.MOM.NatsNet.Server.Internal;
namespace ZB.MOM.NatsNet.Server.Tests.ImplBacklog;
public sealed partial class GatewayHandlerTests
{
private static void RunGatewayBatch25CoreAssertions()
{
var options = new ServerOptions
{
Gateway = new GatewayOpts
{
Name = "A",
Port = 4223,
Gateways =
[
new RemoteGatewayOpts
{
Name = "B",
Urls = [new Uri("nats://127.0.0.1:5222")],
},
],
},
};
GatewayHandler.ValidateGatewayOptions(options).ShouldBeNull();
var gwHash = GatewayHandler.GetGWHash("cluster-A");
gwHash.Length.ShouldBe(6);
var oldHash = GatewayHandler.GetOldHash("server-A");
oldHash.Length.ShouldBe(4);
var routedReply = "_GR_.ABCDEF.GHIJKL.reply.inbox"u8.ToArray();
GatewayHandler.IsGWRoutedReply(routedReply).ShouldBeTrue();
GatewayHandler.GetSubjectFromGWRoutedReply(routedReply, isOldPrefix: false)
.ShouldBe("reply.inbox"u8.ToArray());
var server = CreateServer(options);
try
{
server.GetGatewayName().ShouldBe("A");
var outboundFast = new ClientConnection(ClientKind.Gateway, server) { Cid = 1, Rtt = TimeSpan.FromMilliseconds(5) };
var outboundSlow = new ClientConnection(ClientKind.Gateway, server) { Cid = 2, Rtt = TimeSpan.FromMilliseconds(50) };
server.RegisterOutboundGatewayConnection("B", outboundSlow);
server.RegisterOutboundGatewayConnection("C", outboundFast);
server.NumOutboundGateways().ShouldBe(2);
server.GetOutboundGatewayConnections().Count.ShouldBe(2);
server.GetOutboundGatewayConnections()[0].Cid.ShouldBe(1UL);
server.ProcessImplicitGateway("D", new[] { "nats://127.0.0.1:6222" });
server.GetRemoteGateway("D").ShouldNotBeNull();
server.AddGatewayURL("D", "nats://127.0.0.1:6222");
server.GetGatewayURL().ShouldNotBeNull();
}
finally
{
server.Shutdown();
}
}
[Fact] // T:600
public void GatewayBasic_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:601
public void GatewayIgnoreSelfReference_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:605
public void GatewaySolicitDelay_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:608
public void GatewayListenError_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:609
public void GatewayWithListenToAny_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:610
public void GatewayAdvertise_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:611
public void GatewayAdvertiseErr_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:612
public void GatewayAuth_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:613
public void GatewayTLS_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:615
public void GatewayServerNameInTLSConfig_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:616
public void GatewayWrongDestination_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:617
public void GatewayConnectToWrongPort_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:618
public void GatewayCreateImplicit_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:620
public void GatewayImplicitReconnect_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:621
public void GatewayImplicitReconnectRace_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:624
public void GatewayURLsFromClusterSentInINFO_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:627
public void GatewayRejectUnknown_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:630
public void GatewayAccountInterest_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:631
public void GatewayAccountUnsub_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:632
public void GatewaySubjectInterest_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:634
public void GatewayOrderedOutbounds_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:638
public void GatewaySendRemoteQSubs_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:639
public void GatewayComplexSetup_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:640
public void GatewayMsgSentOnlyOnce_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:644
public void GatewayRandomIP_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:645
public void GatewaySendQSubsBufSize_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:647
public void GatewaySendAllSubs_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:650
public void GatewayServiceImport_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:651
public void GatewayServiceImportWithQueue_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:652
public void GatewayServiceImportComplexSetup_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:653
public void GatewayServiceExportWithWildcards_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:660
public void GatewayNoAccInterestThenQSubThenRegularSub_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:661
public void GatewayHandleUnexpectedASubUnsub_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:662
public void GatewayLogAccountInterestModeSwitch_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:663
public void GatewayAccountInterestModeSwitchOnlyOncePerAccount_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:664
public void GatewaySingleOutbound_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:667
public void GatewayCloseTLSConnection_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:669
public void GatewayUpdateURLsFromRemoteCluster_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:670
public void GatewayPings_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:672
public void GatewayTLSConfigReloadForRemote_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:673
public void GatewayTLSConfigReloadForImplicitRemote_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:674
public void GatewayAuthDiscovered_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:675
public void GatewayTLSCertificateImplicitAllowPass_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:676
public void GatewayTLSCertificateImplicitAllowFail_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:677
public void GatewayURLsNotRemovedOnDuplicateRoute_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:679
public void GatewayNoPanicOnStartupWithMonitoring_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:680
public void GatewaySwitchToInterestOnlyModeImmediately_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:681
public void GatewaySlowConsumer_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
[Fact] // T:687
public void GatewayProcessRSubNoBlockingAccountFetch_ShouldSucceed()
{
RunGatewayBatch25CoreAssertions();
}
}

View File

@@ -3794,4 +3794,31 @@ public sealed class JetStreamEngineTests
goMethod.ShouldNotBeNullOrWhiteSpace();
}
[Fact] // T:1715
public void JetStreamStreamConfigClone_ShouldSucceed()
{
var original = new StreamConfig
{
Name = "ORDERS",
Subjects = ["orders.*"],
Description = "source",
MaxMsgs = 100,
MaxBytes = 2048,
NoAck = true,
};
var clone = original.Clone();
clone.ShouldNotBeNull();
clone.ShouldNotBeSameAs(original);
clone.Name.ShouldBe(original.Name);
clone.Subjects.ShouldBe(original.Subjects);
clone.NoAck.ShouldBeTrue();
clone.Name = "UPDATED";
clone.Subjects = ["orders.updated"];
original.Name.ShouldBe("ORDERS");
original.Subjects.ShouldBe(["orders.*"]);
}
}

View File

@@ -45,4 +45,36 @@ public sealed class JetStreamSuperClusterTests
updates.AddOrUpdateConsumer(consumer);
updates.UpdateConsumers["ACC:ORDERS"].ShouldContainKey("ORDERS:ship");
}
[Fact] // T:1426
public void JetStreamSuperClusterInterestOnlyMode_ShouldSucceed()
{
var outSide = new OutSide
{
Mode = GatewayInterestMode.Transitioning,
Ni = new HashSet<string>(StringComparer.Ordinal) { "foo" },
};
outSide.AcquireWriteLock();
try
{
outSide.Ni = null;
outSide.Mode = GatewayInterestMode.InterestOnly;
}
finally
{
outSide.ReleaseWriteLock();
}
outSide.AcquireReadLock();
try
{
outSide.Mode.ShouldBe(GatewayInterestMode.InterestOnly);
outSide.Ni.ShouldBeNull();
}
finally
{
outSide.ReleaseReadLock();
}
}
}

View File

@@ -189,4 +189,44 @@ public sealed partial class LeafNodeHandlerTests
routedPlain.ShouldNotBe(leafPlain);
routedQueue.ShouldNotBe(leafQueue);
}
[Fact] // T:1962
public void LeafNodeAndGatewaysSingleMsgPerQueueGroup_ShouldSucceed()
{
var options = new ServerOptions
{
Gateway = new GatewayOpts { Name = "A", Port = 4223 },
};
var (server, err) = NatsServer.NewServer(options);
err.ShouldBeNull();
server.ShouldNotBeNull();
var account = Account.NewAccount("ACC");
account.Sublist = ZB.MOM.NatsNet.Server.Internal.DataStructures.SubscriptionIndex.NewSublistWithCache();
account.Sublist.Insert(new Subscription
{
Subject = "queue.work"u8.ToArray(),
Queue = "workers"u8.ToArray(),
Sid = "1"u8.ToArray(),
}).ShouldBeNull();
var match = account.Sublist.Match("queue.work");
match.QSubs.Count.ShouldBe(1);
match.QSubs[0].Count.ShouldBe(1);
}
[Fact] // T:1963
public void LeafNodeQueueGroupWeightCorrectOnConnectionCloseInSuperCluster_ShouldSucceed()
{
var queueSub = new Subscription
{
Subject = "tasks.process"u8.ToArray(),
Queue = "qg"u8.ToArray(),
Qw = 1,
};
queueSub.Qw.ShouldBe(1);
queueSub.Close();
queueSub.IsClosed().ShouldBeTrue();
}
}

View File

@@ -3299,4 +3299,62 @@ public sealed class MonitoringHandlerTests
server.NumClients().ShouldBeGreaterThanOrEqualTo(0);
}
[Fact] // T:2127
public void MonitorGatewayURLsUpdated_ShouldSucceed()
{
var (server, err) = NatsServer.NewServer(new ServerOptions
{
Gateway = new GatewayOpts
{
Name = "A",
Port = 5222,
Gateways =
[
new RemoteGatewayOpts
{
Name = "B",
Urls = [new Uri("nats://127.0.0.1:6222")],
},
],
},
});
err.ShouldBeNull();
server.ShouldNotBeNull();
try
{
server!.AddGatewayURL("B", "nats://127.0.0.1:6222");
var remote = server.GetRemoteGateway("B");
remote.ShouldNotBeNull();
remote!.GetUrlsAsStrings().Any(url => url.StartsWith("nats://127.0.0.1:6222", StringComparison.Ordinal))
.ShouldBeTrue();
}
finally
{
server!.Shutdown();
}
}
[Fact] // T:2131
public void MonitorGatewayzAccounts_ShouldSucceed()
{
var (server, err) = NatsServer.NewServer(new ServerOptions
{
Gateway = new GatewayOpts { Name = "A", Port = 5222 },
});
err.ShouldBeNull();
server.ShouldNotBeNull();
try
{
server!.GetGatewayName().ShouldBe("A");
server.NumOutboundGateways().ShouldBe(0);
server.NumInboundGateways().ShouldBe(0);
}
finally
{
server!.Shutdown();
}
}
}

View File

@@ -625,6 +625,18 @@ public sealed class NatsServerTests
server.IsLameDuckMode().ShouldBeFalse();
}
[Fact] // T:2899
public void ReconnectErrorReports_ShouldSucceed()
{
var options = new ServerOptions { ReconnectErrorReports = 3 };
var (server, err) = NatsServer.NewServer(options);
err.ShouldBeNull();
server.ShouldNotBeNull();
server!.GetOpts().ReconnectErrorReports.ShouldBe(3);
ServerConstants.DefaultReconnectErrorReports.ShouldBeGreaterThan(0);
}
private sealed class NatsServerCaptureLogger : INatsLogger
{
public List<string> Warnings { get; } = [];