Fix E2E test gaps and add comprehensive E2E + parity test suites
- Fix pull consumer fetch: send original stream subject in HMSG (not inbox) so NATS client distinguishes data messages from control messages - Fix MaxAge expiry: add background timer in StreamManager for periodic pruning - Fix JetStream wire format: Go-compatible anonymous objects with string enums, proper offset-based pagination for stream/consumer list APIs - Add 42 E2E black-box tests (core messaging, auth, TLS, accounts, JetStream) - Add ~1000 parity tests across all subsystems (gaps closure) - Update gap inventory docs to reflect implementation status
This commit is contained in:
79
tests/NATS.Server.Tests/Raft/RaftParityBatch3Tests.cs
Normal file
79
tests/NATS.Server.Tests/Raft/RaftParityBatch3Tests.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using NATS.Server.Raft;
|
||||
|
||||
namespace NATS.Server.Tests.Raft;
|
||||
|
||||
public class RaftParityBatch3Tests
|
||||
{
|
||||
[Fact]
|
||||
public async Task ProposeMulti_proposes_entries_in_order()
|
||||
{
|
||||
using var leader = ElectSingleNodeLeader();
|
||||
|
||||
var indexes = await leader.ProposeMultiAsync(["cmd-1", "cmd-2", "cmd-3"], CancellationToken.None);
|
||||
|
||||
indexes.Count.ShouldBe(3);
|
||||
indexes[0].ShouldBe(1);
|
||||
indexes[1].ShouldBe(2);
|
||||
indexes[2].ShouldBe(3);
|
||||
leader.Log.Entries.Count.ShouldBe(3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PeerState_tracks_lag_and_current_flags()
|
||||
{
|
||||
var peer = new RaftPeerState
|
||||
{
|
||||
PeerId = "n2",
|
||||
NextIndex = 10,
|
||||
MatchIndex = 7,
|
||||
LastContact = DateTime.UtcNow,
|
||||
};
|
||||
|
||||
peer.RecalculateLag();
|
||||
peer.RefreshCurrent(TimeSpan.FromSeconds(1));
|
||||
|
||||
peer.Lag.ShouldBe(2);
|
||||
peer.Current.ShouldBeTrue();
|
||||
|
||||
peer.LastContact = DateTime.UtcNow - TimeSpan.FromSeconds(5);
|
||||
peer.RefreshCurrent(TimeSpan.FromSeconds(1));
|
||||
peer.Current.ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CommittedEntry_contains_index_and_entries()
|
||||
{
|
||||
var entries = new[]
|
||||
{
|
||||
new RaftLogEntry(42, 3, "set x"),
|
||||
new RaftLogEntry(43, 3, "set y"),
|
||||
};
|
||||
|
||||
var committed = new CommittedEntry(43, entries);
|
||||
|
||||
committed.Index.ShouldBe(43);
|
||||
committed.Entries.Count.ShouldBe(2);
|
||||
committed.Entries[0].Command.ShouldBe("set x");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RaftEntry_roundtrips_to_wire_shape()
|
||||
{
|
||||
var entry = new RaftEntry(RaftEntryType.AddPeer, new byte[] { 1, 2, 3 });
|
||||
|
||||
var wire = entry.ToWire();
|
||||
var decoded = RaftEntry.FromWire(wire);
|
||||
|
||||
decoded.Type.ShouldBe(RaftEntryType.AddPeer);
|
||||
decoded.Data.ShouldBe(new byte[] { 1, 2, 3 });
|
||||
}
|
||||
|
||||
private static RaftNode ElectSingleNodeLeader()
|
||||
{
|
||||
var node = new RaftNode("n1");
|
||||
node.ConfigureCluster([node]);
|
||||
node.StartElection(1);
|
||||
node.IsLeader.ShouldBeTrue();
|
||||
return node;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user