fix: correct MaxBytes enforcement and consumer start sequence after purge

StreamManager.Capture now accounts for full message size (subject +
payload + 16-byte overhead) when checking MaxBytes, matching Go's
memStoreMsgSize. PullConsumerEngine uses stream FirstSeq instead of
hardcoded 1 for DeliverAll after purge. Fix 6 tests with Go parity
assertions and updated MaxBytes values.
This commit is contained in:
Joseph Doherty
2026-02-24 23:59:37 -05:00
parent 1f83df12e4
commit 51ebded300
8 changed files with 6404 additions and 24 deletions

View File

@@ -91,15 +91,17 @@ public class JetStreamStreamEdgeCaseTests
[Fact]
public async Task Discard_new_rejects_when_stream_at_max_bytes()
{
// Message 1 = "discnew.a"(9) + payload(20) + overhead(16) = 45 bytes.
// MaxBytes=50 holds exactly one message; second is rejected.
await using var fx = await JetStreamApiFixture.StartWithStreamConfigAsync(new StreamConfig
{
Name = "DISCNEW",
Subjects = ["discnew.>"],
MaxBytes = 20,
MaxBytes = 50,
Discard = DiscardPolicy.New,
});
// Fill up the stream with small messages first
// Fill up the stream with one message
var ack1 = await fx.PublishAndGetAckAsync("discnew.a", "12345678901234567890");
ack1.ErrorCode.ShouldBeNull();
@@ -159,16 +161,18 @@ public class JetStreamStreamEdgeCaseTests
[Fact]
public async Task Max_msgs_with_discard_new_via_bytes_rejects_when_bytes_exceeded()
{
// Use MaxBytes + DiscardNew to get the rejection path (pre-store check in Capture())
// Use MaxBytes + DiscardNew to get the rejection path (pre-store check in Capture()).
// Message = "maxnew.a"(8) + "1234567890"(10) + overhead(16) = 34 bytes.
// MaxBytes=40 holds exactly one message; second is rejected.
await using var fx = await JetStreamApiFixture.StartWithStreamConfigAsync(new StreamConfig
{
Name = "MAXNEW",
Subjects = ["maxnew.>"],
MaxBytes = 10,
MaxBytes = 40,
Discard = DiscardPolicy.New,
});
_ = await fx.PublishAndGetAckAsync("maxnew.a", "1234567890"); // 10 bytes, fills stream
_ = await fx.PublishAndGetAckAsync("maxnew.a", "1234567890"); // 34 bytes with overhead
var rejected = await fx.PublishAndGetAckAsync("maxnew.c", "extra-data-overflows");
rejected.ErrorCode.ShouldNotBeNull();