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.
136 lines
4.3 KiB
C#
136 lines
4.3 KiB
C#
// 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 test helpers: RunServer, GetFreePort, etc. from server/test_test.go.
|
|
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using Xunit.Abstractions;
|
|
using ZB.MOM.NatsNet.Server;
|
|
|
|
namespace ZB.MOM.NatsNet.Server.IntegrationTests.Helpers;
|
|
|
|
/// <summary>
|
|
/// Server lifecycle helpers for integration tests.
|
|
/// Mirrors Go patterns from server/test_test.go: RunServer, GetFreePort, etc.
|
|
/// </summary>
|
|
internal static class TestServerHelper
|
|
{
|
|
/// <summary>
|
|
/// Returns true if a NatsServer can be instantiated with basic options.
|
|
/// Used as a Skip guard — if the server can't boot, all integration tests skip gracefully.
|
|
/// </summary>
|
|
public static bool CanBoot()
|
|
{
|
|
try
|
|
{
|
|
var opts = new ServerOptions
|
|
{
|
|
Host = "127.0.0.1",
|
|
Port = -1,
|
|
NoLog = true,
|
|
NoSigs = true,
|
|
};
|
|
var (server, err) = NatsServer.NewServer(opts);
|
|
if (err != null || server == null)
|
|
return false;
|
|
|
|
server.Shutdown();
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates and starts a NatsServer with the given options.
|
|
/// Returns the running server and the options used.
|
|
/// Mirrors Go <c>RunServer</c>.
|
|
/// </summary>
|
|
public static (NatsServer Server, ServerOptions Options) RunServer(ServerOptions opts)
|
|
{
|
|
var (server, err) = NatsServer.NewServer(opts);
|
|
if (err != null)
|
|
throw new InvalidOperationException($"Failed to create server: {err.Message}", err);
|
|
if (server == null)
|
|
throw new InvalidOperationException("Failed to create server: NewServer returned null.");
|
|
|
|
server.Start();
|
|
return (server, opts);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates and starts a NatsServer with JetStream enabled and a temp store directory.
|
|
/// Mirrors Go <c>RunServer</c> with JetStream options.
|
|
/// </summary>
|
|
public static NatsServer RunBasicJetStreamServer(ITestOutputHelper? output = null)
|
|
{
|
|
var storeDir = CreateTempDir("js-store-");
|
|
var opts = new ServerOptions
|
|
{
|
|
Host = "127.0.0.1",
|
|
Port = -1,
|
|
NoLog = true,
|
|
NoSigs = true,
|
|
JetStream = true,
|
|
StoreDir = storeDir,
|
|
};
|
|
|
|
var (server, _) = RunServer(opts);
|
|
return server;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates and starts a NatsServer using the options parsed from a config file path.
|
|
/// The config file content is read and minimal parsing extracts key options.
|
|
/// Returns the running server and the options.
|
|
/// </summary>
|
|
public static (NatsServer Server, ServerOptions Options) RunServerWithConfig(string configFile)
|
|
{
|
|
var opts = new ServerOptions
|
|
{
|
|
ConfigFile = configFile,
|
|
NoLog = true,
|
|
NoSigs = true,
|
|
};
|
|
|
|
return RunServer(opts);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finds a free TCP port on loopback.
|
|
/// Mirrors Go <c>GetFreePort</c>.
|
|
/// </summary>
|
|
public static int GetFreePort()
|
|
{
|
|
var listener = new TcpListener(IPAddress.Loopback, 0);
|
|
listener.Start();
|
|
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
|
|
listener.Stop();
|
|
return port;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a uniquely named temp directory with the given prefix.
|
|
/// The caller is responsible for deleting it when done.
|
|
/// </summary>
|
|
public static string CreateTempDir(string prefix = "nats-test-")
|
|
{
|
|
var path = Path.Combine(Path.GetTempPath(), prefix + Guid.NewGuid().ToString("N")[..8]);
|
|
Directory.CreateDirectory(path);
|
|
return path;
|
|
}
|
|
}
|