refactor: rename remaining tests to NATS.Server.Core.Tests
- Rename tests/NATS.Server.Tests -> tests/NATS.Server.Core.Tests - Update solution file, InternalsVisibleTo, and csproj references - Remove JETSTREAM_INTEGRATION_MATRIX and NATS.NKeys from csproj (moved to JetStream.Tests and Auth.Tests) - Update all namespaces from NATS.Server.Tests.* to NATS.Server.Core.Tests.* - Replace private GetFreePort/ReadUntilAsync helpers with TestUtilities calls - Fix stale namespace in Transport.Tests/NetworkingGoParityTests.cs
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using NATS.Server.Server;
|
||||
|
||||
namespace NATS.Server.Core.Tests;
|
||||
|
||||
public class AcceptLoopErrorCallbackTests
|
||||
{
|
||||
[Fact]
|
||||
public void Accept_loop_reports_error_via_callback_hook()
|
||||
{
|
||||
var server = new NatsServer(new NatsOptions
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
Port = 0,
|
||||
}, NullLoggerFactory.Instance);
|
||||
|
||||
Exception? capturedError = null;
|
||||
EndPoint? capturedEndpoint = null;
|
||||
var capturedDelay = TimeSpan.Zero;
|
||||
|
||||
var handler = new AcceptLoopErrorHandler((ex, endpoint, delay) =>
|
||||
{
|
||||
capturedError = ex;
|
||||
capturedEndpoint = endpoint;
|
||||
capturedDelay = delay;
|
||||
});
|
||||
|
||||
server.SetAcceptLoopErrorHandlerForTest(handler);
|
||||
|
||||
var endpoint = new IPEndPoint(IPAddress.Loopback, 4222);
|
||||
var error = new SocketException((int)SocketError.ConnectionReset);
|
||||
var delay = TimeSpan.FromMilliseconds(20);
|
||||
server.NotifyAcceptErrorForTest(error, endpoint, delay);
|
||||
|
||||
capturedError.ShouldBe(error);
|
||||
capturedEndpoint.ShouldBe(endpoint);
|
||||
capturedDelay.ShouldBe(delay);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace NATS.Server.Core.Tests;
|
||||
|
||||
public class AcceptLoopReloadLockTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Accept_loop_blocks_client_creation_while_reload_lock_is_held()
|
||||
{
|
||||
await using var fx = await AcceptLoopFixture.StartAsync();
|
||||
await fx.HoldReloadLockAsync();
|
||||
(await fx.TryConnectClientAsync(timeoutMs: 150)).ShouldBeFalse();
|
||||
fx.ReleaseReloadLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class AcceptLoopFixture : IAsyncDisposable
|
||||
{
|
||||
private readonly NatsServer _server;
|
||||
private readonly CancellationTokenSource _cts;
|
||||
private bool _reloadHeld;
|
||||
|
||||
private AcceptLoopFixture(NatsServer server, CancellationTokenSource cts)
|
||||
{
|
||||
_server = server;
|
||||
_cts = cts;
|
||||
}
|
||||
|
||||
public static async Task<AcceptLoopFixture> StartAsync()
|
||||
{
|
||||
var server = new NatsServer(new NatsOptions
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
Port = 0,
|
||||
}, NullLoggerFactory.Instance);
|
||||
var cts = new CancellationTokenSource();
|
||||
_ = server.StartAsync(cts.Token);
|
||||
await server.WaitForReadyAsync();
|
||||
return new AcceptLoopFixture(server, cts);
|
||||
}
|
||||
|
||||
public async Task HoldReloadLockAsync()
|
||||
{
|
||||
await _server.AcquireReloadLockForTestAsync();
|
||||
_reloadHeld = true;
|
||||
}
|
||||
|
||||
public void ReleaseReloadLock()
|
||||
{
|
||||
if (_reloadHeld)
|
||||
{
|
||||
_server.ReleaseReloadLockForTest();
|
||||
_reloadHeld = false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> TryConnectClientAsync(int timeoutMs)
|
||||
{
|
||||
using var client = new TcpClient();
|
||||
using var timeout = new CancellationTokenSource(timeoutMs);
|
||||
await client.ConnectAsync(IPAddress.Loopback, _server.Port, timeout.Token);
|
||||
await using var stream = client.GetStream();
|
||||
var buffer = new byte[1];
|
||||
try
|
||||
{
|
||||
var read = await stream.ReadAsync(buffer.AsMemory(0, 1), timeout.Token);
|
||||
return read > 0;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
ReleaseReloadLock();
|
||||
await _cts.CancelAsync();
|
||||
_server.Dispose();
|
||||
_cts.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using System.Net.Sockets;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using NATS.Server.Auth;
|
||||
using NATS.Server.Protocol;
|
||||
|
||||
namespace NATS.Server.Core.Tests.Server;
|
||||
|
||||
public class CoreServerClientAccessorsParityBatch2Tests
|
||||
{
|
||||
[Fact]
|
||||
public void Client_protocol_constants_match_go_values()
|
||||
{
|
||||
ClientProtocolVersion.ClientProtoZero.ShouldBe(0);
|
||||
ClientProtocolVersion.ClientProtoInfo.ShouldBe(1);
|
||||
|
||||
((int)ClientConnectionType.NonClient).ShouldBe(0);
|
||||
((int)ClientConnectionType.Nats).ShouldBe(1);
|
||||
((int)ClientConnectionType.Mqtt).ShouldBe(2);
|
||||
((int)ClientConnectionType.WebSocket).ShouldBe(3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NatsClient_getters_and_client_type_behave_as_expected()
|
||||
{
|
||||
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
using var stream = new MemoryStream();
|
||||
|
||||
var opts = new NatsOptions();
|
||||
var info = new ServerInfo
|
||||
{
|
||||
ServerId = "srv1",
|
||||
ServerName = "srv",
|
||||
Version = "1.0.0",
|
||||
Host = "127.0.0.1",
|
||||
Port = 4222,
|
||||
};
|
||||
var auth = AuthService.Build(opts);
|
||||
var nonce = new byte[] { 1, 2, 3 };
|
||||
var stats = new ServerStats();
|
||||
|
||||
using var client = new NatsClient(
|
||||
id: 42,
|
||||
stream: stream,
|
||||
socket: socket,
|
||||
options: opts,
|
||||
serverInfo: info,
|
||||
authService: auth,
|
||||
nonce: nonce,
|
||||
logger: NullLogger.Instance,
|
||||
serverStats: stats);
|
||||
|
||||
client.ClientType().ShouldBe(ClientConnectionType.Nats);
|
||||
client.IsWebSocket = true;
|
||||
client.ClientType().ShouldBe(ClientConnectionType.WebSocket);
|
||||
client.IsWebSocket = false;
|
||||
client.IsMqtt = true;
|
||||
client.ClientType().ShouldBe(ClientConnectionType.Mqtt);
|
||||
client.GetName().ShouldBe(string.Empty);
|
||||
client.GetNonce().ShouldBe(nonce);
|
||||
client.ToString().ShouldContain("cid=42");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NatsClient_client_type_non_client_when_kind_is_not_client()
|
||||
{
|
||||
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
using var stream = new MemoryStream();
|
||||
|
||||
var opts = new NatsOptions();
|
||||
var info = new ServerInfo
|
||||
{
|
||||
ServerId = "srv1",
|
||||
ServerName = "srv",
|
||||
Version = "1.0.0",
|
||||
Host = "127.0.0.1",
|
||||
Port = 4222,
|
||||
};
|
||||
var auth = AuthService.Build(opts);
|
||||
var stats = new ServerStats();
|
||||
|
||||
using var routeClient = new NatsClient(
|
||||
id: 7,
|
||||
stream: stream,
|
||||
socket: socket,
|
||||
options: opts,
|
||||
serverInfo: info,
|
||||
authService: auth,
|
||||
nonce: null,
|
||||
logger: NullLogger.Instance,
|
||||
serverStats: stats,
|
||||
kind: ClientKind.Router);
|
||||
|
||||
routeClient.ClientType().ShouldBe(ClientConnectionType.NonClient);
|
||||
}
|
||||
}
|
||||
269
tests/NATS.Server.Core.Tests/Server/CoreServerGapParityTests.cs
Normal file
269
tests/NATS.Server.Core.Tests/Server/CoreServerGapParityTests.cs
Normal file
@@ -0,0 +1,269 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using NATS.Server;
|
||||
using NATS.Server.Configuration;
|
||||
using NATS.Server.TestUtilities;
|
||||
|
||||
namespace NATS.Server.Core.Tests.Server;
|
||||
|
||||
public class CoreServerGapParityTests
|
||||
{
|
||||
[Fact]
|
||||
public void ClientURL_uses_advertise_when_present()
|
||||
{
|
||||
using var server = new NatsServer(
|
||||
new NatsOptions { Host = "0.0.0.0", Port = 4222, ClientAdvertise = "demo.example.net:4333" },
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
server.ClientURL().ShouldBe("nats://demo.example.net:4333");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ClientURL_uses_loopback_for_wildcard_host()
|
||||
{
|
||||
using var server = new NatsServer(
|
||||
new NatsOptions { Host = "0.0.0.0", Port = 4222 },
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
server.ClientURL().ShouldBe("nats://127.0.0.1:4222");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebsocketURL_uses_default_host_port_when_enabled()
|
||||
{
|
||||
using var server = new NatsServer(
|
||||
new NatsOptions
|
||||
{
|
||||
WebSocket = new WebSocketOptions
|
||||
{
|
||||
Host = "0.0.0.0",
|
||||
Port = 8080,
|
||||
NoTls = true,
|
||||
},
|
||||
},
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
server.WebsocketURL().ShouldBe("ws://127.0.0.1:8080");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebsocketURL_returns_null_when_disabled()
|
||||
{
|
||||
using var server = new NatsServer(new NatsOptions(), NullLoggerFactory.Instance);
|
||||
|
||||
server.WebsocketURL().ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Account_count_methods_reflect_loaded_and_active_accounts()
|
||||
{
|
||||
using var server = new NatsServer(new NatsOptions(), NullLoggerFactory.Instance);
|
||||
|
||||
server.NumLoadedAccounts().ShouldBe(2); // $G + $SYS
|
||||
server.NumActiveAccounts().ShouldBe(0);
|
||||
|
||||
var app = server.GetOrCreateAccount("APP");
|
||||
server.NumLoadedAccounts().ShouldBe(3);
|
||||
|
||||
app.AddClient(42);
|
||||
server.NumActiveAccounts().ShouldBe(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Address_and_counter_methods_are_derived_from_options_and_stats()
|
||||
{
|
||||
using var server = new NatsServer(
|
||||
new NatsOptions
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
Port = 4222,
|
||||
MonitorHost = "127.0.0.1",
|
||||
MonitorPort = 8222,
|
||||
ProfPort = 6060,
|
||||
},
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
server.Stats.Routes = 2;
|
||||
server.Stats.Gateways = 1;
|
||||
server.Stats.Leafs = 3;
|
||||
|
||||
server.Addr().ShouldBe("127.0.0.1:4222");
|
||||
server.MonitorAddr().ShouldBe("127.0.0.1:8222");
|
||||
server.ProfilerAddr().ShouldBe("127.0.0.1:6060");
|
||||
server.NumRoutes().ShouldBe(2);
|
||||
server.NumLeafNodes().ShouldBe(3);
|
||||
server.NumRemotes().ShouldBe(6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToString_includes_identity_and_address()
|
||||
{
|
||||
using var server = new NatsServer(
|
||||
new NatsOptions { ServerName = "test-node", Host = "127.0.0.1", Port = 4222 },
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var value = server.ToString();
|
||||
|
||||
value.ShouldContain("NatsServer(");
|
||||
value.ShouldContain("Name=test-node");
|
||||
value.ShouldContain("Addr=127.0.0.1:4222");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PortsInfo_returns_configured_listen_endpoints()
|
||||
{
|
||||
using var server = new NatsServer(
|
||||
new NatsOptions
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
Port = 4222,
|
||||
MonitorHost = "127.0.0.1",
|
||||
MonitorPort = 8222,
|
||||
ProfPort = 6060,
|
||||
WebSocket = new WebSocketOptions { Host = "127.0.0.1", Port = 8443 },
|
||||
Cluster = new ClusterOptions { Host = "127.0.0.1", Port = 6222 },
|
||||
LeafNode = new LeafNodeOptions { Host = "127.0.0.1", Port = 7422 },
|
||||
},
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var ports = server.PortsInfo();
|
||||
|
||||
ports.Nats.ShouldContain("127.0.0.1:4222");
|
||||
ports.Monitoring.ShouldContain("127.0.0.1:8222");
|
||||
ports.Profile.ShouldContain("127.0.0.1:6060");
|
||||
ports.WebSocket.ShouldContain("127.0.0.1:8443");
|
||||
ports.Cluster.ShouldContain("127.0.0.1:6222");
|
||||
ports.LeafNodes.ShouldContain("127.0.0.1:7422");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Profiler_and_peer_accessors_have_parity_surface()
|
||||
{
|
||||
using var server = new NatsServer(
|
||||
new NatsOptions { Port = 4222, ProfPort = 6060 },
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
server.StartProfiler().ShouldBeTrue();
|
||||
server.ActivePeers().ShouldBeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Connect_urls_helpers_include_non_wildcard_and_cache_refresh()
|
||||
{
|
||||
using var server = new NatsServer(
|
||||
new NatsOptions { Host = "127.0.0.1", Port = 4222 },
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
var urls = server.GetConnectURLs();
|
||||
urls.ShouldContain("nats://127.0.0.1:4222");
|
||||
|
||||
server.UpdateServerINFOAndSendINFOToClients();
|
||||
var info = Encoding.ASCII.GetString(server.CachedInfoLine);
|
||||
info.ShouldContain("\"connect_urls\":[\"nats://127.0.0.1:4222\"]");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DisconnectClientByID_closes_connected_client()
|
||||
{
|
||||
var port = TestPortAllocator.GetFreePort();
|
||||
using var server = new NatsServer(new NatsOptions { Host = "127.0.0.1", Port = port }, NullLoggerFactory.Instance);
|
||||
using var cts = new CancellationTokenSource();
|
||||
_ = server.StartAsync(cts.Token);
|
||||
await server.WaitForReadyAsync();
|
||||
|
||||
using var socket = await ConnectAndHandshakeAsync(port);
|
||||
await WaitUntilAsync(() => server.ClientCount == 1);
|
||||
var clientId = server.GetClients().Single().Id;
|
||||
|
||||
server.DisconnectClientByID(clientId).ShouldBeTrue();
|
||||
await WaitUntilAsync(() => server.ClientCount == 0);
|
||||
|
||||
await server.ShutdownAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LDMClientByID_closes_connected_client()
|
||||
{
|
||||
var port = TestPortAllocator.GetFreePort();
|
||||
using var server = new NatsServer(new NatsOptions { Host = "127.0.0.1", Port = port }, NullLoggerFactory.Instance);
|
||||
using var cts = new CancellationTokenSource();
|
||||
_ = server.StartAsync(cts.Token);
|
||||
await server.WaitForReadyAsync();
|
||||
|
||||
using var socket = await ConnectAndHandshakeAsync(port);
|
||||
await WaitUntilAsync(() => server.ClientCount == 1);
|
||||
var clientId = server.GetClients().Single().Id;
|
||||
|
||||
server.LDMClientByID(clientId).ShouldBeTrue();
|
||||
await WaitUntilAsync(() => server.ClientCount == 0);
|
||||
|
||||
await server.ShutdownAsync();
|
||||
}
|
||||
|
||||
private static async Task<Socket> ConnectAndHandshakeAsync(int port)
|
||||
{
|
||||
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
await socket.ConnectAsync(IPAddress.Loopback, port);
|
||||
|
||||
_ = await ReadLineAsync(socket, CancellationToken.None); // INFO
|
||||
await socket.SendAsync(Encoding.ASCII.GetBytes("CONNECT {}\r\nPING\r\n"), SocketFlags.None);
|
||||
var pong = await ReadUntilContainsAsync(socket, "PONG", CancellationToken.None);
|
||||
pong.ShouldContain("PONG");
|
||||
|
||||
return socket;
|
||||
}
|
||||
|
||||
private static async Task<string> ReadLineAsync(Socket socket, CancellationToken ct)
|
||||
{
|
||||
var buffer = new List<byte>(256);
|
||||
var single = new byte[1];
|
||||
while (true)
|
||||
{
|
||||
var n = await socket.ReceiveAsync(single.AsMemory(0, 1), SocketFlags.None, ct);
|
||||
if (n == 0)
|
||||
break;
|
||||
|
||||
if (single[0] == '\n')
|
||||
break;
|
||||
|
||||
if (single[0] != '\r')
|
||||
buffer.Add(single[0]);
|
||||
}
|
||||
|
||||
return Encoding.ASCII.GetString([.. buffer]);
|
||||
}
|
||||
|
||||
private static async Task<string> ReadUntilContainsAsync(Socket socket, string token, CancellationToken ct)
|
||||
{
|
||||
var end = DateTime.UtcNow.AddSeconds(3);
|
||||
var builder = new StringBuilder();
|
||||
while (DateTime.UtcNow < end)
|
||||
{
|
||||
var line = await ReadLineAsync(socket, ct);
|
||||
if (line.Length == 0)
|
||||
continue;
|
||||
|
||||
builder.AppendLine(line);
|
||||
if (builder.ToString().Contains(token, StringComparison.Ordinal))
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
private static async Task WaitUntilAsync(Func<bool> predicate)
|
||||
{
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
|
||||
while (!cts.IsCancellationRequested)
|
||||
{
|
||||
if (predicate())
|
||||
return;
|
||||
|
||||
await Task.Yield();
|
||||
}
|
||||
|
||||
throw new TimeoutException("Condition was not met in time.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using NATS.Server.Server;
|
||||
|
||||
namespace NATS.Server.Core.Tests.Server;
|
||||
|
||||
public class CoreServerOptionsParityBatch3Tests
|
||||
{
|
||||
[Fact]
|
||||
public void Core_ports_and_compression_types_exist_with_expected_defaults()
|
||||
{
|
||||
var ports = new Ports
|
||||
{
|
||||
Nats = ["nats://127.0.0.1:4222"],
|
||||
Monitoring = ["http://127.0.0.1:8222"],
|
||||
};
|
||||
|
||||
ports.Nats.ShouldHaveSingleItem();
|
||||
ports.Monitoring.ShouldHaveSingleItem();
|
||||
|
||||
CompressionModes.Off.ShouldBe("off");
|
||||
CompressionModes.S2Auto.ShouldBe("s2_auto");
|
||||
|
||||
var opts = new CompressionOpts();
|
||||
opts.Mode.ShouldBe(CompressionModes.Off);
|
||||
opts.RTTThresholds.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RoutesFromStr_parses_comma_delimited_routes()
|
||||
{
|
||||
var routes = NatsOptions.RoutesFromStr(" nats://a:6222, tls://b:7222 ");
|
||||
|
||||
routes.Count.ShouldBe(2);
|
||||
routes[0].ToString().ShouldBe("nats://a:6222/");
|
||||
routes[1].ToString().ShouldBe("tls://b:7222/");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Clone_returns_deep_copy_for_common_collections()
|
||||
{
|
||||
var original = new NatsOptions
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
Port = 4222,
|
||||
Tags = new Dictionary<string, string> { ["a"] = "1" },
|
||||
SubjectMappings = new Dictionary<string, string> { ["foo.*"] = "bar.$1" },
|
||||
TlsPinnedCerts = ["abc"],
|
||||
};
|
||||
original.InCmdLine.Add("host");
|
||||
|
||||
var clone = original.Clone();
|
||||
|
||||
clone.ShouldNotBeSameAs(original);
|
||||
clone.Tags.ShouldNotBeSameAs(original.Tags);
|
||||
clone.SubjectMappings.ShouldNotBeSameAs(original.SubjectMappings);
|
||||
clone.TlsPinnedCerts.ShouldNotBeSameAs(original.TlsPinnedCerts);
|
||||
clone.InCmdLine.ShouldNotBeSameAs(original.InCmdLine);
|
||||
clone.InCmdLine.ShouldContain("host");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProcessConfigString_sets_config_digest_and_applies_values()
|
||||
{
|
||||
var opts = new NatsOptions();
|
||||
opts.ProcessConfigString("port: 4333");
|
||||
|
||||
opts.Port.ShouldBe(4333);
|
||||
opts.ConfigDigest().ShouldNotBeNullOrWhiteSpace();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NoErrOnUnknownFields_toggle_is_available()
|
||||
{
|
||||
NatsOptions.NoErrOnUnknownFields(true);
|
||||
var ex = Record.Exception(() => new NatsOptions().ProcessConfigString("totally_unknown_field: 1"));
|
||||
ex.ShouldBeNull();
|
||||
NatsOptions.NoErrOnUnknownFields(false);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Option_parity_types_exist()
|
||||
{
|
||||
var jsLimits = new JSLimitOpts
|
||||
{
|
||||
MaxRequestBatch = 10,
|
||||
MaxAckPending = 20,
|
||||
};
|
||||
jsLimits.MaxRequestBatch.ShouldBe(10);
|
||||
jsLimits.MaxAckPending.ShouldBe(20);
|
||||
|
||||
var callout = new AuthCallout
|
||||
{
|
||||
Issuer = "issuer",
|
||||
Account = "A",
|
||||
AllowedAccounts = ["A", "B"],
|
||||
};
|
||||
callout.Issuer.ShouldBe("issuer");
|
||||
callout.AllowedAccounts.ShouldContain("B");
|
||||
|
||||
var proxies = new ProxiesConfig
|
||||
{
|
||||
Trusted = [new ProxyConfig { Key = "k1" }],
|
||||
};
|
||||
proxies.Trusted.Count.ShouldBe(1);
|
||||
proxies.Trusted[0].Key.ShouldBe("k1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System.Net.Sockets;
|
||||
using NATS.Server.Routes;
|
||||
using NATS.Server.Server;
|
||||
|
||||
namespace NATS.Server.Core.Tests.Server;
|
||||
|
||||
public class UtilitiesAndRateCounterParityBatch1Tests
|
||||
{
|
||||
[Fact]
|
||||
public void ParseHostPort_uses_default_port_for_missing_zero_and_minus_one()
|
||||
{
|
||||
ServerUtilities.ParseHostPort("127.0.0.1", 4222).ShouldBe(("127.0.0.1", 4222));
|
||||
ServerUtilities.ParseHostPort("127.0.0.1:0", 4222).ShouldBe(("127.0.0.1", 4222));
|
||||
ServerUtilities.ParseHostPort("127.0.0.1:-1", 4222).ShouldBe(("127.0.0.1", 4222));
|
||||
ServerUtilities.ParseHostPort(":4333", 4222).ShouldBe(("", 4333));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RedactUrl_helpers_redact_password_for_single_and_list_inputs()
|
||||
{
|
||||
ServerUtilities.RedactUrlString("nats://foo:bar@example.com:4222")
|
||||
.ShouldBe("nats://foo:xxxxx@example.com:4222");
|
||||
ServerUtilities.RedactUrlString("nats://example.com:4222")
|
||||
.ShouldBe("nats://example.com:4222");
|
||||
|
||||
var redacted = ServerUtilities.RedactUrlList(
|
||||
["nats://a:b@one:4222", "nats://noauth:4223"]);
|
||||
redacted[0].ShouldBe("nats://a:xxxxx@one:4222");
|
||||
redacted[1].ShouldBe("nats://noauth:4223");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RateCounter_allow_and_count_blocked_match_go_behavior()
|
||||
{
|
||||
var rc = new RateCounter(2);
|
||||
|
||||
rc.Allow().ShouldBeTrue();
|
||||
rc.Allow().ShouldBeTrue();
|
||||
rc.Allow().ShouldBeFalse();
|
||||
rc.Allow().ShouldBeFalse();
|
||||
|
||||
rc.CountBlocked().ShouldBe((ulong)2);
|
||||
rc.CountBlocked().ShouldBe((ulong)0); // reset on read
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateRouteDialSocket_disables_keepalive()
|
||||
{
|
||||
using var socket = RouteManager.CreateRouteDialSocket();
|
||||
var keepAlive = Convert.ToInt32(socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive));
|
||||
keepAlive.ShouldBe(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using NATS.Server.Server;
|
||||
|
||||
namespace NATS.Server.Core.Tests.Server;
|
||||
|
||||
public class UtilitiesErrorConstantsParityBatch2Tests
|
||||
{
|
||||
[Fact]
|
||||
public void Error_constants_match_go_error_literals_batch2()
|
||||
{
|
||||
ServerErrorConstants.ErrBadQualifier.ShouldBe("bad qualifier");
|
||||
ServerErrorConstants.ErrTooManyAccountConnections.ShouldBe("maximum account active connections exceeded");
|
||||
ServerErrorConstants.ErrTooManySubs.ShouldBe("maximum subscriptions exceeded");
|
||||
ServerErrorConstants.ErrTooManySubTokens.ShouldBe("subject has exceeded number of tokens limit");
|
||||
ServerErrorConstants.ErrReservedAccount.ShouldBe("reserved account");
|
||||
ServerErrorConstants.ErrMissingService.ShouldBe("service missing");
|
||||
ServerErrorConstants.ErrBadServiceType.ShouldBe("bad service response type");
|
||||
ServerErrorConstants.ErrBadSampling.ShouldBe("bad sampling percentage, should be 1-100");
|
||||
ServerErrorConstants.ErrAccountResolverUpdateTooSoon.ShouldBe("account resolver update too soon");
|
||||
ServerErrorConstants.ErrAccountResolverSameClaims.ShouldBe("account resolver no new claims");
|
||||
ServerErrorConstants.ErrStreamImportAuthorization.ShouldBe("stream import not authorized");
|
||||
ServerErrorConstants.ErrStreamImportBadPrefix.ShouldBe("stream import prefix can not contain wildcard tokens");
|
||||
ServerErrorConstants.ErrStreamImportDuplicate.ShouldBe("stream import already exists");
|
||||
ServerErrorConstants.ErrServiceImportAuthorization.ShouldBe("service import not authorized");
|
||||
ServerErrorConstants.ErrImportFormsCycle.ShouldBe("import forms a cycle");
|
||||
ServerErrorConstants.ErrCycleSearchDepth.ShouldBe("search cycle depth exhausted");
|
||||
ServerErrorConstants.ErrNoTransforms.ShouldBe("no matching transforms available");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user