using NATS.Server.JetStream; using NATS.Server.JetStream.Models; namespace NATS.Server.Tests.JetStream; public class JetStreamRetentionRuntimeStrictParityTests { [Fact] public async Task Limits_interest_and_workqueue_retention_diverge_by_runtime_contract() { var consumers = new ConsumerManager(); var streams = new StreamManager(consumerManager: consumers); streams.CreateOrUpdate(new StreamConfig { Name = "WQ_STRICT", Subjects = ["wq.strict"], Retention = RetentionPolicy.WorkQueue, MaxMsgs = 32, }).Error.ShouldBeNull(); streams.CreateOrUpdate(new StreamConfig { Name = "INT_STRICT", Subjects = ["int.strict"], Retention = RetentionPolicy.Interest, MaxMsgs = 32, }).Error.ShouldBeNull(); consumers.CreateOrUpdate("WQ_STRICT", new ConsumerConfig { DurableName = "WQ", AckPolicy = AckPolicy.All }).Error.ShouldBeNull(); consumers.CreateOrUpdate("INT_STRICT", new ConsumerConfig { DurableName = "INT", AckPolicy = AckPolicy.All }).Error.ShouldBeNull(); streams.Capture("wq.strict", "one"u8.ToArray()); streams.Capture("wq.strict", "two"u8.ToArray()); streams.Capture("int.strict", "one"u8.ToArray()); streams.Capture("int.strict", "two"u8.ToArray()); consumers.AckAll("WQ_STRICT", "WQ", 1).ShouldBeTrue(); consumers.AckAll("INT_STRICT", "INT", 1).ShouldBeTrue(); // Trigger another retention pass after ack-floor updates. streams.Capture("wq.strict", "three"u8.ToArray()); streams.Capture("int.strict", "three"u8.ToArray()); streams.TryGet("WQ_STRICT", out var wq).ShouldBeTrue(); streams.TryGet("INT_STRICT", out var interest).ShouldBeTrue(); var wqState = await wq.Store.GetStateAsync(default); var interestState = await interest.Store.GetStateAsync(default); wqState.Messages.ShouldBe((ulong)2); // seq=1 pruned by workqueue ack floor interestState.Messages.ShouldBe((ulong)3); // interest retention does not use ack-floor pruning } }