using NATS.Server.JetStream.Api; using NATS.Server.JetStream.Models; using NATS.Server.JetStream.Validation; using NATS.Server.JetStream; namespace NATS.Server.JetStream.Tests.JetStream.Api; public class JetStreamApiLimitsParityBatch1Tests { [Fact] public void Constants_match_go_reference_values() { JetStreamApiLimits.JSMaxDescriptionLen.ShouldBe(4_096); JetStreamApiLimits.JSMaxMetadataLen.ShouldBe(128 * 1024); JetStreamApiLimits.JSMaxNameLen.ShouldBe(255); JetStreamApiLimits.JSDefaultRequestQueueLimit.ShouldBe(10_000); } [Theory] [InlineData(null, false)] [InlineData("", false)] [InlineData(" ", false)] [InlineData("ORDERS", true)] [InlineData("ORD ERS", false)] [InlineData("ORDERS.*", false)] [InlineData("ORDERS.>", false)] public void IsValidName_enforces_expected_rules(string? name, bool expected) { JetStreamConfigValidator.IsValidName(name).ShouldBe(expected); } [Fact] public void Stream_create_rejects_name_over_max_length() { var manager = new StreamManager(); var response = manager.CreateOrUpdate(new StreamConfig { Name = new string('S', JetStreamApiLimits.JSMaxNameLen + 1), Subjects = ["a"], }); response.Error.ShouldNotBeNull(); response.Error!.Description.ShouldBe("invalid stream name"); } [Fact] public void Stream_create_rejects_description_over_max_bytes() { var manager = new StreamManager(); var response = manager.CreateOrUpdate(new StreamConfig { Name = "LIMITDESC", Subjects = ["a"], Description = new string('d', JetStreamApiLimits.JSMaxDescriptionLen + 1), }); response.Error.ShouldNotBeNull(); response.Error!.Description.ShouldBe("stream description is too long"); } [Fact] public void Stream_create_rejects_metadata_over_max_bytes() { var manager = new StreamManager(); var response = manager.CreateOrUpdate(new StreamConfig { Name = "LIMITMETA", Subjects = ["a"], Metadata = new Dictionary { ["k"] = new string('m', JetStreamApiLimits.JSMaxMetadataLen), }, }); response.Error.ShouldNotBeNull(); response.Error!.Description.ShouldBe("stream metadata exceeds maximum size"); } [Fact] public void Consumer_create_rejects_durable_name_over_max_length() { var manager = new ConsumerManager(); var response = manager.CreateOrUpdate("S", new ConsumerConfig { DurableName = new string('C', JetStreamApiLimits.JSMaxNameLen + 1), }); response.Error.ShouldNotBeNull(); response.Error!.Description.ShouldBe("invalid durable name"); } [Fact] public void Consumer_create_rejects_metadata_over_max_bytes() { var manager = new ConsumerManager(); var response = manager.CreateOrUpdate("S", new ConsumerConfig { DurableName = "C1", Metadata = new Dictionary { ["k"] = new string('m', JetStreamApiLimits.JSMaxMetadataLen), }, }); response.Error.ShouldNotBeNull(); response.Error!.Description.ShouldBe("consumer metadata exceeds maximum size"); } }