test(batch19): port accounts core mapped tests

This commit is contained in:
Joseph Doherty
2026-02-28 20:28:13 -05:00
parent e53b4aa17a
commit 8d00012ba8
5 changed files with 190 additions and 0 deletions

View File

@@ -246,6 +246,62 @@ public sealed class AccountTests
system.CheckServiceExportApproved(global, "$SYS.REQ.INFO", null).ShouldBeTrue();
}
[Fact] // T:81
public void MultipleStreamImportsWithSameSubjectDifferentPrefix_ShouldSucceed()
{
var fooAccount = Account.NewAccount("foo");
var barAccount = Account.NewAccount("bar");
var importAccount = Account.NewAccount("import");
fooAccount.AddStreamExport("test", null).ShouldBeNull();
barAccount.AddStreamExport("test", null).ShouldBeNull();
importAccount.AddStreamImport(fooAccount, "test", "foo").ShouldBeNull();
importAccount.AddStreamImport(barAccount, "test", "bar").ShouldBeNull();
importAccount.Imports.Streams.ShouldNotBeNull();
importAccount.Imports.Streams!.Count.ShouldBe(2);
importAccount.Imports.Streams.Select(si => si.To).OrderBy(static t => t).ToArray()
.ShouldBe(["bar.test", "foo.test"]);
}
[Fact] // T:82
public void MultipleStreamImportsWithSameSubject_ShouldSucceed()
{
var fooAccount = Account.NewAccount("foo");
var barAccount = Account.NewAccount("bar");
var importAccount = Account.NewAccount("import");
fooAccount.AddStreamExport("test", null).ShouldBeNull();
barAccount.AddStreamExport("test", null).ShouldBeNull();
importAccount.AddStreamImport(fooAccount, "test", string.Empty).ShouldBeNull();
importAccount.AddStreamImport(fooAccount, "test", string.Empty).ShouldBe(ServerErrors.ErrStreamImportDuplicate);
importAccount.AddStreamImport(barAccount, "test", string.Empty).ShouldBeNull();
importAccount.Imports.Streams.ShouldNotBeNull();
importAccount.Imports.Streams!.Count.ShouldBe(2);
importAccount.Imports.Streams.Select(si => si.Account?.Name).OrderBy(static n => n).ToArray()
.ShouldBe(["bar", "foo"]);
}
[Fact] // T:95
public void BenchmarkNewRouteReply()
{
var globalAccount = Account.NewAccount("$G");
var first = globalAccount.NewServiceReply(tracking: false);
var second = globalAccount.NewServiceReply(tracking: false);
var tracked = globalAccount.NewServiceReply(tracking: true);
first.Length.ShouldBeGreaterThan(20);
second.Length.ShouldBeGreaterThan(20);
first.SequenceEqual(second).ShouldBeFalse();
var trackedText = Encoding.ASCII.GetString(tracked);
trackedText.EndsWith(".T", StringComparison.Ordinal).ShouldBeTrue();
}
[Fact] // T:98
public void ImportSubscriptionPartialOverlapWithPrefix_ShouldSucceed()
{

View File

@@ -1,4 +1,5 @@
using System.Diagnostics;
using System.Linq;
using Shouldly;
using ZB.MOM.NatsNet.Server;
using ZB.MOM.NatsNet.Server.Internal;
@@ -122,6 +123,53 @@ public sealed partial class GatewayHandlerTests
NatsServer.ValidateCluster(conflict).ShouldBe(ServerErrors.ErrClusterNameConfigConflict);
}
[Fact] // T:658
public void GatewaySendReplyAcrossGatewaysServiceImport_ShouldSucceed()
{
var fooAccount = Account.NewAccount("$foo");
var barAccount = Account.NewAccount("$bar");
fooAccount.AddServiceExport("foo.request", null).ShouldBeNull();
barAccount.AddServiceImport(fooAccount, "bar.request", "foo.request").ShouldBeNull();
var serviceImport = barAccount.Imports.Services!["bar.request"].Single();
var responseImport = barAccount.AddRespServiceImport(fooAccount, "reply", serviceImport, tracking: false, header: null);
responseImport.From.ShouldNotBe("reply");
responseImport.To.ShouldBe("reply");
barAccount.Exports.Responses.ShouldNotBeNull();
barAccount.Exports.Responses!.ShouldContainKey(responseImport.From);
fooAccount.Imports.ReverseResponseMap.ShouldNotBeNull();
fooAccount.Imports.ReverseResponseMap!.ShouldContainKey("reply");
fooAccount.Imports.ReverseResponseMap["reply"].Any(e => e.MappedSubject == responseImport.From).ShouldBeTrue();
barAccount.ProcessServiceImportResponse(responseImport.From, "ok"u8.ToArray());
responseImport.DidDeliver.ShouldBeTrue();
}
[Fact] // T:666
public void GatewayNoAccountUnsubWhenServiceReplyInUse_ShouldSucceed()
{
var fooAccount = Account.NewAccount("$foo");
var barAccount = Account.NewAccount("$bar");
fooAccount.AddServiceExport("test.request", null).ShouldBeNull();
barAccount.AddServiceImport(fooAccount, "foo.request", "test.request").ShouldBeNull();
var serviceImport = barAccount.Imports.Services!["foo.request"].Single();
var responseImport1 = barAccount.AddRespServiceImport(fooAccount, "reply", serviceImport, tracking: false, header: null);
var responseImport2 = barAccount.AddRespServiceImport(fooAccount, "reply", serviceImport, tracking: false, header: null);
fooAccount.Imports.ReverseResponseMap.ShouldNotBeNull();
fooAccount.Imports.ReverseResponseMap!["reply"].Count.ShouldBe(2);
fooAccount.CheckForReverseEntry("reply", responseImport1, checkInterest: false);
fooAccount.Imports.ReverseResponseMap["reply"].Count.ShouldBe(1);
fooAccount.Imports.ReverseResponseMap["reply"].Single().MappedSubject.ShouldBe(responseImport2.From);
}
private static NatsServer CreateServer(ServerOptions? opts = null)
{
var (server, err) = NatsServer.NewServer(opts ?? new ServerOptions());

View File

@@ -1,5 +1,6 @@
using Shouldly;
using ZB.MOM.NatsNet.Server;
using ZB.MOM.NatsNet.Server.Internal;
namespace ZB.MOM.NatsNet.Server.Tests.ImplBacklog;
@@ -71,4 +72,54 @@ public sealed partial class LeafNodeHandlerTests
remotes[1].FirstInfoTimeout.ShouldBe(TimeSpan.FromSeconds(3));
remotes[1].Urls[0].Scheme.ShouldBe("ws");
}
[Fact] // T:1935
public void LeafNodeNoDuplicateWithinCluster_ShouldSucceed()
{
var account = Account.NewAccount("$G");
var leaf1 = new ClientConnection(ClientKind.Leaf);
var leaf2 = new ClientConnection(ClientKind.Leaf);
((INatsAccount)account).AddClient(leaf1);
((INatsAccount)account).AddClient(leaf2);
account.RegisterLeafNodeCluster("xyz");
account.RegisterLeafNodeCluster("xyz");
account.NumLocalLeafNodes().ShouldBe(2);
account.HasLeafNodeCluster("xyz").ShouldBeTrue();
account.IsLeafNodeClusterIsolated("xyz").ShouldBeTrue();
account.RegisterLeafNodeCluster("abc");
account.IsLeafNodeClusterIsolated("xyz").ShouldBeFalse();
}
[Fact] // T:1952
public void LeafNodeStreamImport_ShouldSucceed()
{
var exporter = Account.NewAccount("B");
var importer = Account.NewAccount("C");
exporter.AddStreamExport(">", null).ShouldBeNull();
importer.AddStreamImport(exporter, ">", string.Empty).ShouldBeNull();
importer.Imports.Streams.ShouldNotBeNull();
importer.Imports.Streams!.Count.ShouldBe(1);
importer.Imports.Streams[0].From.ShouldBe(">");
importer.Imports.Streams[0].To.ShouldBe(">");
exporter.CheckStreamExportApproved(importer, "a", null).ShouldBeTrue();
}
[Fact] // T:1955
public void LeafNodeUnsubOnRouteDisconnect_ShouldSucceed()
{
var account = Account.NewAccount("$G");
var leaf = new ClientConnection(ClientKind.Leaf);
((INatsAccount)account).AddClient(leaf);
account.NumLocalLeafNodes().ShouldBe(1);
((INatsAccount)account).RemoveClient(leaf);
account.NumLocalLeafNodes().ShouldBe(0);
}
}

View File

@@ -6,6 +6,41 @@ namespace ZB.MOM.NatsNet.Server.Tests.ImplBacklog;
public sealed class MessageTracerTests
{
[Fact] // T:2359
public void MsgTraceParseAccountDestWithSampling_ShouldSucceed()
{
var cases = new[]
{
(Name: "trace sampling no dest", Value: (object)new Dictionary<string, object?> { ["sampling"] = 50 }, Want: 0),
(Name: "trace dest only", Value: (object)new Dictionary<string, object?> { ["dest"] = "foo" }, Want: 100),
(Name: "trace dest with number only", Value: (object)new Dictionary<string, object?> { ["dest"] = "foo", ["sampling"] = 20 }, Want: 20),
(Name: "trace dest with percentage", Value: (object)new Dictionary<string, object?> { ["dest"] = "foo", ["sampling"] = "50%" }, Want: 50),
};
foreach (var testCase in cases)
{
var options = new ServerOptions();
var errors = new List<Exception>();
var warnings = new List<Exception>();
var accounts = new Dictionary<string, object?>
{
["A"] = new Dictionary<string, object?>
{
["msg_trace"] = testCase.Value,
},
};
var parseError = ServerOptions.ParseAccounts(accounts, options, errors, warnings);
parseError.ShouldBeNull(testCase.Name);
errors.ShouldBeEmpty(testCase.Name);
options.Accounts.Count.ShouldBe(1, testCase.Name);
var (_, sampling) = options.Accounts[0].GetTraceDestAndSampling();
sampling.ShouldBe(testCase.Want, testCase.Name);
}
}
[Fact] // T:2331
public void MsgTraceBasic_ShouldSucceed()
{