Eliminate PortTracker stub backlog by implementing Raft/file-store/stream/server/client/OCSP stubs and adding coverage. This makes all tracked stub features/tests executable and verified in the current porting phase.

This commit is contained in:
Joseph Doherty
2026-02-27 08:56:26 -05:00
parent ba4f41cf71
commit 8849265780
33 changed files with 2938 additions and 407 deletions

View File

@@ -15,6 +15,7 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
namespace ZB.MOM.NatsNet.Server.Internal;
@@ -25,7 +26,16 @@ namespace ZB.MOM.NatsNet.Server.Internal;
/// </summary>
public static class SignalHandler
{
private const string ResolvePidError = "unable to resolve pid, try providing one";
private static string _processName = "nats-server";
internal static Func<List<int>> ResolvePidsHandler { get; set; } = ResolvePids;
internal static Func<int, UnixSignal, Exception?> SendSignalHandler { get; set; } = SendSignal;
internal static void ResetTestHooks()
{
ResolvePidsHandler = ResolvePids;
SendSignalHandler = SendSignal;
}
/// <summary>
/// Sets the process name used for resolving PIDs.
@@ -46,25 +56,67 @@ public static class SignalHandler
try
{
List<int> pids;
if (string.IsNullOrEmpty(pidExpr))
var pids = new List<int>(1);
var pidStr = pidExpr.TrimEnd('*');
var isGlob = pidExpr.EndsWith('*');
if (!string.IsNullOrEmpty(pidStr))
{
pids = ResolvePids();
if (pids.Count == 0)
return new InvalidOperationException("no nats-server processes found");
}
else
{
if (int.TryParse(pidExpr, out var pid))
pids = [pid];
else
return new InvalidOperationException($"invalid pid: {pidExpr}");
if (!int.TryParse(pidStr, out var pid))
return new InvalidOperationException($"invalid pid: {pidStr}");
pids.Add(pid);
}
var signal = CommandToUnixSignal(command);
if (string.IsNullOrEmpty(pidStr) || isGlob)
pids = ResolvePidsHandler();
if (pids.Count > 1 && !isGlob)
{
var sb = new StringBuilder($"multiple {_processName} processes running:");
foreach (var p in pids)
sb.Append('\n').Append(p);
return new InvalidOperationException(sb.ToString());
}
if (pids.Count == 0)
return new InvalidOperationException($"no {_processName} processes running");
UnixSignal signal;
try
{
signal = CommandToUnixSignal(command);
}
catch (Exception ex)
{
return ex;
}
var errBuilder = new StringBuilder();
foreach (var pid in pids)
Process.GetProcessById(pid).Kill(signal == UnixSignal.SigKill);
{
var pidText = pid.ToString();
if (pidStr.Length > 0 && pidText != pidStr)
{
if (!isGlob || !pidText.StartsWith(pidStr, StringComparison.Ordinal))
continue;
}
var err = SendSignalHandler(pid, signal);
if (err != null)
{
errBuilder
.Append('\n')
.Append("signal \"")
.Append(CommandToString(command))
.Append("\" ")
.Append(pid)
.Append(": ")
.Append(err.Message);
}
}
if (errBuilder.Length > 0)
return new InvalidOperationException(errBuilder.ToString());
return null;
}
@@ -80,7 +132,7 @@ public static class SignalHandler
/// </summary>
public static List<int> ResolvePids()
{
var pids = new List<int>();
var pids = new List<int>(8);
try
{
var psi = new ProcessStartInfo("pgrep", _processName)
@@ -90,22 +142,33 @@ public static class SignalHandler
CreateNoWindow = true,
};
using var proc = Process.Start(psi);
if (proc == null) return pids;
if (proc == null)
throw new InvalidOperationException(ResolvePidError);
var output = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
if (proc.ExitCode != 0)
return pids;
var currentPid = Environment.ProcessId;
foreach (var line in output.Split('\n', StringSplitOptions.RemoveEmptyEntries))
{
if (int.TryParse(line.Trim(), out var pid) && pid != currentPid)
if (!int.TryParse(line.Trim(), out var pid))
throw new InvalidOperationException(ResolvePidError);
if (pid != currentPid)
pids.Add(pid);
}
}
catch (InvalidOperationException ex) when (ex.Message == ResolvePidError)
{
throw;
}
catch
{
// pgrep not available or failed
throw new InvalidOperationException(ResolvePidError);
}
return pids;
}
@@ -119,7 +182,33 @@ public static class SignalHandler
ServerCommand.Quit => UnixSignal.SigInt,
ServerCommand.Reopen => UnixSignal.SigUsr1,
ServerCommand.Reload => UnixSignal.SigHup,
_ => throw new ArgumentOutOfRangeException(nameof(command), $"unknown command: {command}"),
ServerCommand.LameDuckMode => UnixSignal.SigUsr2,
ServerCommand.Term => UnixSignal.SigTerm,
_ => throw new ArgumentOutOfRangeException(nameof(command), $"unknown signal \"{CommandToString(command)}\""),
};
private static Exception? SendSignal(int pid, UnixSignal signal)
{
try
{
Process.GetProcessById(pid).Kill(signal == UnixSignal.SigKill);
return null;
}
catch (Exception ex)
{
return ex;
}
}
private static string CommandToString(ServerCommand command) => command switch
{
ServerCommand.Stop => "stop",
ServerCommand.Quit => "quit",
ServerCommand.Reopen => "reopen",
ServerCommand.Reload => "reload",
ServerCommand.LameDuckMode => "ldm",
ServerCommand.Term => "term",
_ => command.ToString().ToLowerInvariant(),
};
/// <summary>