fix: resolve code-review findings (locally verified)
Server-054/055/056, Contracts-020/021/022, Tests-036/038/039, IntegrationTests-030/031/032 (+033 deferred to live rig), Client.Dotnet-026/028/029 (+027 won't-fix), Client.Go-030..034, Client.Python-032..036, Client.Rust-033..038. Key fix: SessionEventDistributor orphaned a subscriber that registered after the pump completed but before disposal (Server-056) -> register paths now complete late registrants under _lifecycleLock; regression test added. The racy dashboard-mirror gRPC test made deterministic (Tests-039). Verified green locally: gateway Tests targeted classes (GatewaySession, SessionEventDistributor, GatewayOptionsValidator, ProtobufContractRoundTrip, GatewaySessionDashboardMirror) + dotnet/go/python/rust client suites.
This commit is contained in:
@@ -1543,4 +1543,49 @@ public sealed class ProtobufContractRoundTripTests
|
||||
Assert.Equal(AlarmProviderMode.Subtag, parsed.OnAlarmProviderModeChanged.Mode);
|
||||
Assert.Equal(unchecked((int)0x80004005), parsed.OnAlarmProviderModeChanged.Hresult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that an <see cref="MxEvent"/> carrying a
|
||||
/// <see cref="ReplayGap"/> (the <c>optional replay_gap = 14</c> field)
|
||||
/// round-trips with both sequence fields populated, that
|
||||
/// <see cref="MxEvent.BodyCase"/> remains <see cref="MxEvent.BodyOneofCase.None"/>
|
||||
/// (replay_gap is not part of the body oneof), and pins the wire field
|
||||
/// numbers for <c>MxEvent.replay_gap</c> (14),
|
||||
/// <c>ReplayGap.requested_after_sequence</c> (1), and
|
||||
/// <c>ReplayGap.oldest_available_sequence</c> (2) via the descriptor.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void MxEvent_RoundTripsReplayGapSentinelAndPinsFieldNumbers()
|
||||
{
|
||||
// ReplayGap field on MxEvent must be wire number 14.
|
||||
Assert.Equal(14, MxEvent.ReplayGapFieldNumber);
|
||||
|
||||
// ReplayGap sub-field numbers must be pinned.
|
||||
var replayGapFields = ReplayGap.Descriptor.Fields;
|
||||
Assert.Equal(1, replayGapFields[ReplayGap.RequestedAfterSequenceFieldNumber].FieldNumber);
|
||||
Assert.Equal("requested_after_sequence", replayGapFields[ReplayGap.RequestedAfterSequenceFieldNumber].Name);
|
||||
Assert.Equal(2, replayGapFields[ReplayGap.OldestAvailableSequenceFieldNumber].FieldNumber);
|
||||
Assert.Equal("oldest_available_sequence", replayGapFields[ReplayGap.OldestAvailableSequenceFieldNumber].Name);
|
||||
|
||||
// Build a sentinel MxEvent: replay_gap set, body oneof unset, family UNSPECIFIED.
|
||||
var original = new MxEvent
|
||||
{
|
||||
SessionId = "session-1",
|
||||
WorkerSequence = 0,
|
||||
ReplayGap = new ReplayGap
|
||||
{
|
||||
RequestedAfterSequence = 150,
|
||||
OldestAvailableSequence = 200,
|
||||
},
|
||||
};
|
||||
|
||||
var parsed = MxEvent.Parser.ParseFrom(original.ToByteArray());
|
||||
|
||||
Assert.Equal(original, parsed);
|
||||
// replay_gap is NOT part of the body oneof — BodyCase must remain None.
|
||||
Assert.Equal(MxEvent.BodyOneofCase.None, parsed.BodyCase);
|
||||
Assert.NotNull(parsed.ReplayGap);
|
||||
Assert.Equal(150UL, parsed.ReplayGap.RequestedAfterSequence);
|
||||
Assert.Equal(200UL, parsed.ReplayGap.OldestAvailableSequence);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user