using System.Net; using System.Net.Sockets; using Microsoft.Extensions.Logging.Abstractions; namespace NATS.Server.Tests; public class PprofEndpointTests { [Fact] public async Task Debug_pprof_endpoint_returns_profile_index_when_profport_enabled() { await using var fx = await PprofMonitorFixture.StartWithProfilingAsync(); var body = await fx.GetStringAsync("/debug/pprof"); body.ShouldContain("profiles"); } } internal sealed class PprofMonitorFixture : IAsyncDisposable { private readonly NatsServer _server; private readonly CancellationTokenSource _cts; private readonly HttpClient _http; private readonly int _monitorPort; private PprofMonitorFixture(NatsServer server, CancellationTokenSource cts, HttpClient http, int monitorPort) { _server = server; _cts = cts; _http = http; _monitorPort = monitorPort; } public static async Task StartWithProfilingAsync() { var monitorPort = GetFreePort(); var options = new NatsOptions { Host = "127.0.0.1", Port = 0, MonitorPort = monitorPort, ProfPort = monitorPort, }; var server = new NatsServer(options, NullLoggerFactory.Instance); var cts = new CancellationTokenSource(); _ = server.StartAsync(cts.Token); await server.WaitForReadyAsync(); var http = new HttpClient(); for (var i = 0; i < 50; i++) { try { var response = await http.GetAsync($"http://127.0.0.1:{monitorPort}/healthz"); if (response.IsSuccessStatusCode) break; } catch { } await Task.Delay(50); } return new PprofMonitorFixture(server, cts, http, monitorPort); } public Task GetStringAsync(string path) { return _http.GetStringAsync($"http://127.0.0.1:{_monitorPort}{path}"); } public async ValueTask DisposeAsync() { _http.Dispose(); await _cts.CancelAsync(); _server.Dispose(); _cts.Dispose(); } private static int GetFreePort() { using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Bind(new IPEndPoint(IPAddress.Loopback, 0)); return ((IPEndPoint)socket.LocalEndPoint!).Port; } }