feat: add benchmark test project for Go vs .NET server comparison

Side-by-side performance benchmarks using NATS.Client.Core against both
servers on ephemeral ports. Includes core pub/sub, request/reply latency,
and JetStream throughput tests with comparison output and
benchmarks_comparison.md results. Also fixes timestamp flakiness in
StoreInterfaceTests by using explicit timestamps.
This commit is contained in:
Joseph Doherty
2026-03-13 01:23:31 -04:00
parent e9c86c51c3
commit 37575dc41c
28 changed files with 2264 additions and 12 deletions

View File

@@ -0,0 +1,47 @@
using NATS.Client.Core;
namespace NATS.Server.Benchmark.Tests.Infrastructure;
/// <summary>
/// Starts both a Go and .NET NATS server for core pub/sub benchmarks.
/// Shared across all tests in the "Benchmark-Core" collection.
/// </summary>
public sealed class CoreServerPairFixture : IAsyncLifetime
{
private GoServerProcess? _goServer;
private DotNetServerProcess? _dotNetServer;
public int GoPort => _goServer?.Port ?? throw new InvalidOperationException("Go server not started");
public int DotNetPort => _dotNetServer?.Port ?? throw new InvalidOperationException(".NET server not started");
public bool GoAvailable => _goServer is not null;
public async Task InitializeAsync()
{
_dotNetServer = new DotNetServerProcess();
var dotNetTask = _dotNetServer.StartAsync();
if (GoServerProcess.IsAvailable())
{
_goServer = new GoServerProcess();
await Task.WhenAll(dotNetTask, _goServer.StartAsync());
}
else
{
await dotNetTask;
}
}
public async Task DisposeAsync()
{
if (_goServer is not null)
await _goServer.DisposeAsync();
if (_dotNetServer is not null)
await _dotNetServer.DisposeAsync();
}
public NatsConnection CreateGoClient()
=> new(new NatsOpts { Url = $"nats://127.0.0.1:{GoPort}" });
public NatsConnection CreateDotNetClient()
=> new(new NatsOpts { Url = $"nats://127.0.0.1:{DotNetPort}" });
}