test(batch48): add integration test harness infrastructure

Create 7 helper files under ZB.MOM.NatsNet.Server.IntegrationTests/Helpers/
and add Xunit.SkippableFact package. All tests skip gracefully via
IntegrationTestBase.CanBoot() guard until the .NET server runtime is complete.
This commit is contained in:
Joseph Doherty
2026-03-01 12:06:08 -05:00
parent 41ea272c8a
commit e846cb664a
8 changed files with 1125 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
// 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;
}
}