using NATS.Client.Core; namespace NATS.Server.Benchmark.Tests.Infrastructure; /// /// Starts both a Go and .NET NATS server with JetStream enabled for benchmark testing. /// Shared across all tests in the "Benchmark-JetStream" collection. /// public sealed class JetStreamServerPairFixture : IAsyncLifetime { private GoServerProcess? _goServer; private DotNetServerProcess? _dotNetServer; private string? _goStoreDir; private string? _dotNetStoreDir; 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() { _dotNetStoreDir = Path.Combine(Path.GetTempPath(), "nats-bench-dotnet-js-" + Guid.NewGuid().ToString("N")[..8]); Directory.CreateDirectory(_dotNetStoreDir); var dotNetConfig = $$""" jetstream { store_dir: "{{_dotNetStoreDir}}" max_mem_store: 256mb max_file_store: 1gb } """; _dotNetServer = new DotNetServerProcess(dotNetConfig); var dotNetTask = _dotNetServer.StartAsync(); if (GoServerProcess.IsAvailable()) { _goStoreDir = Path.Combine(Path.GetTempPath(), "nats-bench-go-js-" + Guid.NewGuid().ToString("N")[..8]); Directory.CreateDirectory(_goStoreDir); var goConfig = $$""" jetstream { store_dir: "{{_goStoreDir}}" max_mem_store: 256mb max_file_store: 1gb } """; _goServer = new GoServerProcess(goConfig); 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(); CleanupDir(_goStoreDir); CleanupDir(_dotNetStoreDir); } 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}" }); private static void CleanupDir(string? dir) { if (dir is not null && Directory.Exists(dir)) { try { Directory.Delete(dir, recursive: true); } catch { /* best-effort cleanup */ } } } }