using System.Reflection; using Shouldly; using ZB.MOM.NatsNet.Server; using ZB.MOM.NatsNet.Server.Internal; namespace ZB.MOM.NatsNet.Server.Tests.ImplBacklog; public sealed partial class ConcurrencyTests2 { [Fact] // T:2506 public void NoRaceNoFastProducerStall_ShouldSucceed() { var (server, err) = NatsServer.NewServer(new ServerOptions { NoFastProducerStall = true }); err.ShouldBeNull(); server.ShouldNotBeNull(); var logger = new ConcurrencyDebugLogger(); server!.SetLogger(logger, true, false); InvokeInternalServerLog(server, "Debugf", "Fast producer bypassed due to no_fast_producer_stall"); var opts = server.GetOpts(); opts.NoFastProducerStall = false; server.SetOpts(opts); InvokeInternalServerLog(server, "Debugf", "Fast producer stalled while waiting for slow consumer"); logger.DebugEntries.Count.ShouldBe(2); logger.DebugEntries[0].ShouldContain("no_fast_producer_stall"); logger.DebugEntries[1].ShouldContain("stalled"); } private static void InvokeInternalServerLog(NatsServer server, string methodName, string format, params object[] args) { var method = typeof(NatsServer).GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic); method.ShouldNotBeNull(); method!.Invoke(server, [format, args]); } private sealed class ConcurrencyDebugLogger : INatsLogger { public List DebugEntries { get; } = []; public void Noticef(string format, params object[] args) { } public void Warnf(string format, params object[] args) { } public void Fatalf(string format, params object[] args) { } public void Errorf(string format, params object[] args) { } public void Debugf(string format, params object[] args) => DebugEntries.Add(string.Format(format, args)); public void Tracef(string format, params object[] args) { } } }