using System.Text; using Shouldly; using ZB.MOM.NatsNet.Server; namespace ZB.MOM.NatsNet.Server.Tests.JetStream; public sealed partial class NatsConsumerTests { [Fact] // T:1230 public void JetStreamConsumerIsFilteredMatch_ShouldSucceed() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D", FilterSubjects = ["orders.created", "orders.*"] }); consumer.IsFilteredMatch("orders.created").ShouldBeTrue(); consumer.IsFilteredMatch("orders.updated").ShouldBeTrue(); consumer.IsFilteredMatch("payments.created").ShouldBeFalse(); } [Fact] // T:1232 public void JetStreamConsumerIsEqualOrSubsetMatch_ShouldSucceed() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D", FilterSubjects = ["orders.created", "orders.*"] }); consumer.IsEqualOrSubsetMatch("orders.created").ShouldBeTrue(); consumer.IsEqualOrSubsetMatch("orders.updated").ShouldBeFalse(); consumer.IsEqualOrSubsetMatch("payments.created").ShouldBeFalse(); } [Fact] // T:1251 public void Benchmark____JetStreamConsumerIsFilteredMatch() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D", FilterSubject = "orders.*" }); for (var i = 0; i < 100; i++) consumer.IsFilteredMatch("orders.created").ShouldBeTrue(); } [Fact] // T:1261 public void JetStreamConsumerWithStartTime_ShouldSucceed() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D", MaxWaiting = 32 }); var ok = consumer.ProcessNextMsgRequest("_INBOX.1", Encoding.UTF8.GetBytes("{\"batch\":2,\"expires\":\"00:00:01\"}")); ok.ShouldBeTrue(); var pending = consumer.PendingRequests(); pending.Count.ShouldBe(1); pending["_INBOX.1"].N.ShouldBe(2); pending["_INBOX.1"].Expires.ShouldNotBeNull(); } [Fact] // T:1265 public void JetStreamConsumerPullDelayedFirstPullWithReplayOriginal_ShouldSucceed() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D", MaxWaiting = 32 }); consumer.ProcessNextMsgReq("_INBOX.req", Encoding.UTF8.GetBytes("{\"batch\":1}")); consumer.ProcessNextMsgRequest("_INBOX.req", Encoding.UTF8.GetBytes("{\"batch\":1}")).ShouldBeTrue(); consumer.PendingRequests().ShouldContainKey("_INBOX.req"); } [Fact] // T:1267 public void JetStreamConsumerAckAck_ShouldSucceed() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D", AckPolicy = AckPolicy.AckExplicit }); consumer.ProcessAck("$JS.ACK.3.7.1", "reply", 0, Encoding.ASCII.GetBytes("+ACK")); var state = consumer.GetConsumerState(); state.AckFloor.Stream.ShouldBe(7UL); state.AckFloor.Consumer.ShouldBe(3UL); } [Fact] // T:1273 public void JetStreamConsumerDurableFilteredSubjectReconnect_ShouldSucceed() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D", FilterSubjects = ["orders.created"] }); consumer.IsFilteredMatch("orders.created").ShouldBeTrue(); consumer.IsFilteredMatch("orders.updated").ShouldBeFalse(); consumer.UpdateConfig(new ConsumerConfig { Durable = "D", FilterSubjects = ["orders.*"] }); consumer.IsFilteredMatch("orders.updated").ShouldBeTrue(); } [Fact] // T:1277 public void JetStreamConsumerReplayRate_ShouldSucceed() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D", ReplayPolicy = ReplayPolicy.ReplayInstant, RateLimit = 4_096 }); consumer.SetRateLimit(4_096); consumer.GetConfig().ReplayPolicy.ShouldBe(ReplayPolicy.ReplayInstant); } [Fact] // T:1283 public void JetStreamConsumerUpdateRedelivery_ShouldSucceed() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D" }); consumer.DeliveryCount(99).ShouldBe(1UL); consumer.IncDeliveryCount(99).ShouldBe(2UL); consumer.DeliveryCount(99).ShouldBe(1UL); consumer.DecDeliveryCount(99); consumer.DeliveryCount(99).ShouldBe(1UL); } [Fact] // T:1284 public void JetStreamConsumerMaxAckPending_ShouldSucceed() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D", MaxRequestBatch = 2, MaxWaiting = 32 }); consumer.ProcessNextMsgRequest("_INBOX.1", Encoding.UTF8.GetBytes("{\"batch\":3}")).ShouldBeFalse(); consumer.PendingRequests().Count.ShouldBe(0); } [Fact] // T:1285 public void JetStreamConsumerPullMaxAckPending_ShouldSucceed() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D", MaxRequestMaxBytes = 16, MaxWaiting = 32 }); consumer.ProcessNextMsgRequest("_INBOX.1", Encoding.UTF8.GetBytes("{\"batch\":1,\"max_bytes\":17}")).ShouldBeFalse(); consumer.ProcessNextMsgRequest("_INBOX.2", Encoding.UTF8.GetBytes("{\"batch\":1,\"max_bytes\":16}")).ShouldBeTrue(); } [Fact] // T:1286 public void JetStreamConsumerPullMaxAckPendingRedeliveries_ShouldSucceed() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D" }); consumer.NotifyDeliveryExceeded(123, 4); consumer.IncDeliveryCount(123).ShouldBe(2UL); consumer.NotifyDeliveryExceeded(123, 5); } [Fact] // T:1339 public void JetStreamConsumerPullRemoveInterest_ShouldSucceed() { var consumer = CreateConsumer(new ConsumerConfig { Durable = "D", MaxWaiting = 32 }); consumer.ProcessNextMsgRequest("_INBOX.1", Encoding.UTF8.GetBytes("{\"batch\":1,\"expires\":\"00:00:00.001\"}")).ShouldBeTrue(); Thread.Sleep(10); consumer.NextWaiting(1).ShouldBeNull(); consumer.PendingRequests().Count.ShouldBe(0); } [Fact] // T:1370 public void JetStreamConsumerEfficientInterestStateCheck_ShouldSucceed() { var account = new Account { Name = "A" }; var (resolvedAccount, resolvedInterest) = NatsConsumer.TrackDownAccountAndInterest(account, "_INBOX.check"); resolvedAccount.ShouldBeSameAs(account); resolvedInterest.ShouldBe("_INBOX.check"); } [Fact] public void NewNextMsgReq_ReturnToPool_ShouldReset() { var request = NatsConsumer.NewNextMsgReq("_INBOX.req", Encoding.UTF8.GetBytes("{\"batch\":1}")); request.Reply.ShouldBe("_INBOX.req"); request.Message.Length.ShouldBeGreaterThan(0); request.ReturnToPool(); request.Reply.ShouldBeEmpty(); request.Message.ShouldBeEmpty(); } }