using Microsoft.Extensions.Logging.Abstractions; using NATS.Server.Configuration; namespace NATS.Server.JetStream.Tests; public class JetStreamClusterReloadTests { [Fact] public async Task Reload_rejects_non_reloadable_jetstream_storage_change() { await using var fixture = await ConfigReloadFixture.StartJetStreamAsync(); var ex = await Should.ThrowAsync(() => fixture.ReloadAsync("jetstream { store_dir: '/new' }")); ex.Message.ShouldContain("requires restart"); } } internal sealed class ConfigReloadFixture : IAsyncDisposable { private readonly string _configPath; private readonly NatsServer _server; private ConfigReloadFixture(string configPath, NatsServer server) { _configPath = configPath; _server = server; } public static Task StartJetStreamAsync() { var configPath = Path.Combine(Path.GetTempPath(), $"natsdotnet-reload-{Guid.NewGuid():N}.conf"); File.WriteAllText(configPath, "jetstream { store_dir: '/old' }"); var options = new NatsOptions { ConfigFile = configPath, JetStream = new JetStreamOptions { StoreDir = "/old", MaxMemoryStore = 1_024 * 1_024, MaxFileStore = 10 * 1_024 * 1_024, }, }; var server = new NatsServer(options, NullLoggerFactory.Instance); return Task.FromResult(new ConfigReloadFixture(configPath, server)); } public Task ReloadAsync(string configText) { File.WriteAllText(_configPath, configText); _server.ReloadConfigOrThrow(); return Task.CompletedTask; } public ValueTask DisposeAsync() { _server.Dispose(); if (File.Exists(_configPath)) File.Delete(_configPath); return ValueTask.CompletedTask; } }