Port of Go server/reload.go option interface and diffing logic. Compares NatsOptions property-by-property to detect changes, tags each with category flags (logging, auth, TLS, non-reloadable), validates that non-reloadable options (Host, Port, ServerName) are not changed at runtime, and provides MergeCliOverrides to ensure CLI flags always take precedence over config file values during hot reload.
90 lines
2.8 KiB
C#
90 lines
2.8 KiB
C#
using NATS.Server;
|
|
using NATS.Server.Auth;
|
|
using NATS.Server.Configuration;
|
|
|
|
namespace NATS.Server.Tests;
|
|
|
|
public class ConfigReloadTests
|
|
{
|
|
[Fact]
|
|
public void Diff_NoChanges_ReturnsEmpty()
|
|
{
|
|
var old = new NatsOptions { Port = 4222, Debug = true };
|
|
var @new = new NatsOptions { Port = 4222, Debug = true };
|
|
var changes = ConfigReloader.Diff(old, @new);
|
|
changes.ShouldBeEmpty();
|
|
}
|
|
|
|
[Fact]
|
|
public void Diff_ReloadableChange_ReturnsChange()
|
|
{
|
|
var old = new NatsOptions { Debug = false };
|
|
var @new = new NatsOptions { Debug = true };
|
|
var changes = ConfigReloader.Diff(old, @new);
|
|
changes.Count.ShouldBe(1);
|
|
changes[0].Name.ShouldBe("Debug");
|
|
changes[0].IsLoggingChange.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void Diff_NonReloadableChange_ReturnsNonReloadableChange()
|
|
{
|
|
var old = new NatsOptions { Port = 4222 };
|
|
var @new = new NatsOptions { Port = 5222 };
|
|
var changes = ConfigReloader.Diff(old, @new);
|
|
changes.Count.ShouldBe(1);
|
|
changes[0].IsNonReloadable.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void Diff_MultipleChanges_ReturnsAll()
|
|
{
|
|
var old = new NatsOptions { Debug = false, MaxPayload = 1024 };
|
|
var @new = new NatsOptions { Debug = true, MaxPayload = 2048 };
|
|
var changes = ConfigReloader.Diff(old, @new);
|
|
changes.Count.ShouldBe(2);
|
|
}
|
|
|
|
[Fact]
|
|
public void Diff_AuthChange_MarkedCorrectly()
|
|
{
|
|
var old = new NatsOptions { Username = "alice" };
|
|
var @new = new NatsOptions { Username = "bob" };
|
|
var changes = ConfigReloader.Diff(old, @new);
|
|
changes[0].IsAuthChange.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void Diff_TlsChange_MarkedCorrectly()
|
|
{
|
|
var old = new NatsOptions { TlsCert = "/old/cert.pem" };
|
|
var @new = new NatsOptions { TlsCert = "/new/cert.pem" };
|
|
var changes = ConfigReloader.Diff(old, @new);
|
|
changes[0].IsTlsChange.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void Validate_NonReloadableChanges_ReturnsErrors()
|
|
{
|
|
var changes = new List<IConfigChange>
|
|
{
|
|
new ConfigChange("Port", isNonReloadable: true),
|
|
};
|
|
var errors = ConfigReloader.Validate(changes);
|
|
errors.Count.ShouldBe(1);
|
|
errors[0].ShouldContain("Port");
|
|
}
|
|
|
|
[Fact]
|
|
public void MergeWithCli_CliOverridesConfig()
|
|
{
|
|
var fromConfig = new NatsOptions { Port = 5222, Debug = true };
|
|
var cliFlags = new HashSet<string> { "Port" };
|
|
var cliValues = new NatsOptions { Port = 4222 };
|
|
|
|
ConfigReloader.MergeCliOverrides(fromConfig, cliValues, cliFlags);
|
|
fromConfig.Port.ShouldBe(4222); // CLI wins
|
|
fromConfig.Debug.ShouldBeTrue(); // config value kept (not in CLI)
|
|
}
|
|
}
|