test(batch56): port 66 reload and auth integration tests
Port config hot-reload (44 tests), opts (1 test), account isolation (5 tests), auth callout (5 tests), and JWT validation (11 tests) from Go reload_test.go, opts_test.go, accounts_test.go, auth_callout_test.go, and jwt_test.go as behavioral blackbox integration tests against the .NET NatsServer using ReloadOptions() and the public NATS client API.
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
// Copyright 2012-2026 The NATS Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Mirrors Go checkFor from server/test_test.go.
|
||||
|
||||
using System.Diagnostics;
|
||||
using ZB.MOM.NatsNet.Server;
|
||||
|
||||
namespace ZB.MOM.NatsNet.Server.IntegrationTests.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Retry/polling helpers for integration tests.
|
||||
/// Mirrors Go <c>checkFor</c> from server/test_test.go.
|
||||
/// </summary>
|
||||
internal static class CheckHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Polls <paramref name="check"/> repeatedly until it returns null (success)
|
||||
/// or the timeout expires, in which case the last exception is thrown.
|
||||
/// Mirrors Go <c>checkFor(t, timeout, interval, func() error)</c>.
|
||||
/// </summary>
|
||||
public static void CheckFor(TimeSpan timeout, TimeSpan interval, Func<Exception?> check)
|
||||
{
|
||||
var sw = Stopwatch.StartNew();
|
||||
Exception? last = null;
|
||||
while (sw.Elapsed < timeout)
|
||||
{
|
||||
last = check();
|
||||
if (last == null) return;
|
||||
Thread.Sleep(interval);
|
||||
}
|
||||
|
||||
// One final attempt after the sleep boundary.
|
||||
last = check();
|
||||
if (last == null) return;
|
||||
|
||||
throw new TimeoutException(
|
||||
$"CheckFor timed out after {timeout}: {last.Message}", last);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Async version of <see cref="CheckFor"/>. Uses <c>Task.Delay</c> instead of
|
||||
/// <c>Thread.Sleep</c> to avoid blocking the thread pool.
|
||||
/// </summary>
|
||||
public static async Task CheckForAsync(
|
||||
TimeSpan timeout,
|
||||
TimeSpan interval,
|
||||
Func<Task<Exception?>> check,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var sw = Stopwatch.StartNew();
|
||||
Exception? last = null;
|
||||
while (sw.Elapsed < timeout)
|
||||
{
|
||||
last = await check().ConfigureAwait(false);
|
||||
if (last == null) return;
|
||||
await Task.Delay(interval, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// One final attempt.
|
||||
last = await check().ConfigureAwait(false);
|
||||
if (last == null) return;
|
||||
|
||||
throw new TimeoutException(
|
||||
$"CheckForAsync timed out after {timeout}: {last.Message}", last);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits until all servers in <paramref name="servers"/> have formed a cluster
|
||||
/// (each server sees at least <c>servers.Length - 1</c> routes).
|
||||
/// Uses a 10-second timeout with 100 ms poll interval.
|
||||
/// Mirrors Go <c>checkClusterFormed</c>.
|
||||
/// </summary>
|
||||
public static void CheckClusterFormed(params NatsServer[] servers)
|
||||
{
|
||||
var expected = servers.Length - 1;
|
||||
CheckFor(TimeSpan.FromSeconds(10), TimeSpan.FromMilliseconds(100), () =>
|
||||
{
|
||||
foreach (var s in servers)
|
||||
{
|
||||
var routes = s.NumRoutes();
|
||||
if (routes < expected)
|
||||
return new Exception(
|
||||
$"Server {s.Options.ServerName} has {routes} routes, expected {expected}.");
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits until the given server has at least <paramref name="expected"/>
|
||||
/// leaf node connections.
|
||||
/// Uses a 10-second timeout with 100 ms poll interval.
|
||||
/// Mirrors Go <c>checkLeafNodeConnectedCount</c>.
|
||||
/// </summary>
|
||||
public static void CheckLeafNodeConnectedCount(NatsServer server, int expected)
|
||||
{
|
||||
CheckFor(TimeSpan.FromSeconds(10), TimeSpan.FromMilliseconds(100), () =>
|
||||
{
|
||||
var count = server.NumLeafNodes();
|
||||
if (count < expected)
|
||||
return new Exception(
|
||||
$"Server {server.Options.ServerName} has {count} leaf nodes, expected {expected}.");
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user