docs(tests): fix CommentChecker findings across tests/ — 13,392 → 0 (repo-wide scan clean)

Comment/XML-doc changes only:
- add summaries to ~10k test methods, fixtures, fakes and helpers
  (+ <param> on theories, <returns> on async Task methods,
  <inheritdoc/> on interface implementations the checker can resolve)
- strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N,
  #NN, Component-0NN) from comments, keeping the explanatory text;
  reword false positives in comments only
- real docs on fakes implementing BCL/library interfaces
  (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime)
- reword the last 5 src/ false positives (CWE-1236, failures-1,
  year-0001, M365)

Only non-comment edits: four one-line nested classes split across lines
so members can carry docs. Build 0 errors / 0 warnings.
This commit is contained in:
Joseph Doherty
2026-10-07 15:05:49 -04:00
parent 0ffd4bdbea
commit 513fa1aa16
998 changed files with 17896 additions and 2395 deletions
@@ -25,6 +25,7 @@ public class DebugStreamBridgeActorTests : TestKit
private const string GrpcNodeA = "http://localhost:5100";
private const string GrpcNodeB = "http://localhost:5200";
/// <summary>Initializes the test class with a short-timeout Akka configuration.</summary>
public DebugStreamBridgeActorTests() : base(@"akka.loglevel = DEBUG")
{
// Use a very short reconnect delay for testing
@@ -67,10 +68,11 @@ public class DebugStreamBridgeActorTests : TestKit
return new TestContext(actor, commProbe, mockClient, events, terminated);
}
/// <summary>Verifies that an instance-not-found snapshot is forwarded to the event callback, tears down the stream and terminates the actor.</summary>
[Fact]
public void On_InstanceNotFound_Snapshot_Forwards_To_OnEvent_Tears_Down_Stream_And_Terminates()
{
// M2.11 (revised for M2.18 stream-first): the gRPC subscription is now opened
// Stream-first: the gRPC subscription is now opened
// up-front in PreStart, so when the site reports InstanceNotFound=true the
// bridge actor must
// (a) forward the not-found snapshot to _onEvent so DebugStreamService's TCS
@@ -111,6 +113,7 @@ public class DebugStreamBridgeActorTests : TestKit
ExpectTerminated(ctx.BridgeActor, TimeSpan.FromSeconds(3));
}
/// <summary>Verifies that PreStart sends a subscribe debug view request through the communication actor.</summary>
[Fact]
public void PreStart_Sends_SubscribeDebugViewRequest_Via_ClusterClient()
{
@@ -125,6 +128,7 @@ public class DebugStreamBridgeActorTests : TestKit
Assert.Equal("corr-1", req.CorrelationId);
}
/// <summary>Verifies that a snapshot is forwarded to the event callback.</summary>
[Fact]
public void On_Snapshot_Forwards_To_OnEvent_Callback()
{
@@ -144,10 +148,11 @@ public class DebugStreamBridgeActorTests : TestKit
lock (ctx.ReceivedEvents) { Assert.IsType<DebugViewSnapshot>(ctx.ReceivedEvents[0]); }
}
/// <summary>Verifies that receiving a snapshot does not open an additional gRPC stream.</summary>
[Fact]
public void On_Snapshot_Does_Not_Open_Additional_GrpcStream()
{
// M2.18 stream-first: the gRPC subscription is opened in PreStart, BEFORE the
// Stream-first: the gRPC subscription is opened in PreStart, BEFORE the
// snapshot arrives. After the snapshot is delivered the actor switches to
// pass-through — it must NOT open a second subscription. Exactly ONE subscribe
// call should have been made (the PreStart one).
@@ -173,6 +178,7 @@ public class DebugStreamBridgeActorTests : TestKit
Assert.Equal(InstanceName, singleCall.InstanceUniqueName);
}
/// <summary>Verifies that events from the gRPC callback are forwarded to the event callback.</summary>
[Fact]
public void Events_From_GrpcCallback_Forwarded_To_OnEvent()
{
@@ -198,6 +204,7 @@ public class DebugStreamBridgeActorTests : TestKit
lock (ctx.ReceivedEvents) { Assert.IsType<AttributeValueChanged>(ctx.ReceivedEvents[1]); }
}
/// <summary>Verifies that a gRPC error causes a reconnect to the other node.</summary>
[Fact]
public void On_GrpcError_Reconnects_To_Other_Node()
{
@@ -221,10 +228,11 @@ public class DebugStreamBridgeActorTests : TestKit
Assert.Equal("corr-1", ctx.MockGrpcClient.SubscribeCalls[1].CorrelationId);
}
/// <summary>Verifies that a gRPC error unsubscribes the old stream before reconnecting.</summary>
[Fact]
public void On_GrpcError_Unsubscribes_Old_Stream_Before_Reconnect()
{
// Communication-002 regression: a reconnect must unsubscribe the previous
// Regression: a reconnect must unsubscribe the previous
// stream so the old node does not keep a zombie relay actor / subscription.
var ctx = CreateBridgeActor();
ctx.CommProbe.ExpectMsg<SiteEnvelope>();
@@ -249,6 +257,7 @@ public class DebugStreamBridgeActorTests : TestKit
Assert.Contains("corr-1", ctx.MockGrpcClient.UnsubscribedCorrelationIds);
}
/// <summary>Verifies that the actor terminates after the maximum number of retries.</summary>
[Fact]
public void After_MaxRetries_Terminates()
{
@@ -282,6 +291,7 @@ public class DebugStreamBridgeActorTests : TestKit
Assert.True(ctx.TerminatedFlag[0]);
}
/// <summary>Verifies that stopping the debug stream cancels the gRPC subscription and sends an unsubscribe.</summary>
[Fact]
public void StopDebugStream_Cancels_Grpc_And_Sends_Unsubscribe()
{
@@ -312,6 +322,7 @@ public class DebugStreamBridgeActorTests : TestKit
ExpectTerminated(ctx.BridgeActor);
}
/// <summary>Verifies that a debug stream terminated message stops the actor idempotently.</summary>
[Fact]
public void DebugStreamTerminated_Stops_Actor_Idempotently()
{
@@ -325,10 +336,11 @@ public class DebugStreamBridgeActorTests : TestKit
Assert.True(ctx.TerminatedFlag[0]);
}
/// <summary>Verifies that a flapping stream that delivers events between failures still terminates after the maximum retries.</summary>
[Fact]
public void FlappingStream_DeliveringEventsBetweenFailures_StillTerminatesAfterMaxRetries()
{
// Communication-008 regression: a stream that connects, delivers an event,
// Regression: a stream that connects, delivers an event,
// then fails — repeatedly — must still trip MaxRetries. The retry count is
// NO LONGER reset by a received event (only by the stability window). The
// previous behaviour reset _retryCount on every event, so a flapping site
@@ -367,10 +379,11 @@ public class DebugStreamBridgeActorTests : TestKit
Assert.True(ctx.TerminatedFlag[0]);
}
/// <summary>Verifies that a gRPC error reconnects through a client bound to the other node's endpoint.</summary>
[Fact]
public void On_GrpcError_Reconnects_To_Other_Node_Endpoint()
{
// Communication-015 regression: drive the bridge actor through a node flip
// Regression: drive the bridge actor through a node flip
// with an endpoint-aware factory (one distinct mock client per endpoint).
// The first subscribe targets NodeA; after a gRPC error the bridge must
// reconnect via a client bound to the *NodeB* endpoint.
@@ -407,8 +420,9 @@ public class DebugStreamBridgeActorTests : TestKit
Assert.Equal("corr-1", factory.ClientFor(GrpcNodeB).SubscribeCalls[0].CorrelationId);
}
// ── WP1.1: graceful (status OK) stream completion is a reconnect trigger ──
// ── graceful (status OK) stream completion is a reconnect trigger ──
/// <summary>Verifies that a graceful stream completion reopens the stream on the same node.</summary>
[Fact]
public void On_GracefulStreamCompletion_Reopens_On_The_Same_Node()
{
@@ -429,6 +443,7 @@ public class DebugStreamBridgeActorTests : TestKit
Assert.Contains("corr-1", factory.ClientFor(GrpcNodeA).UnsubscribedCorrelationIds);
}
/// <summary>Verifies that repeated graceful completions do not consume the error retry budget.</summary>
[Fact]
public void RepeatedGracefulCompletions_DoNotConsume_TheErrorRetryBudget()
{
@@ -449,6 +464,7 @@ public class DebugStreamBridgeActorTests : TestKit
Assert.False(ctx.TerminatedFlag[0]);
}
/// <summary>Verifies that a late completion from a previous stream generation is ignored.</summary>
[Fact]
public void LateCompletionFromAPreviousStreamGeneration_IsIgnored()
{
@@ -461,14 +477,14 @@ public class DebugStreamBridgeActorTests : TestKit
AwaitCondition(() => factory.ClientFor(GrpcNodeB).SubscribeCalls.Count == 1,
TimeSpan.FromSeconds(5));
// A completion racing out of the dead gen-1 stream must not tear down the live one.
// A completion racing out of the dead first-generation stream must not tear down the live one.
firstSub.OnCompleted();
Thread.Sleep(300);
Assert.DoesNotContain("corr-1", factory.ClientFor(GrpcNodeB).UnsubscribedCorrelationIds);
Assert.Single(factory.ClientFor(GrpcNodeB).SubscribeCalls);
}
// ── Task 6 (arch review 02, High): teardown/failover unsubscribe is endpoint-safe ──
// ── teardown/failover unsubscribe is endpoint-safe ──
// Both paths use TryGet, never GetOrCreate, so cleanup can never open a fresh
// channel or (with (site,endpoint) keying) touch another session's channel.
@@ -485,6 +501,7 @@ public class DebugStreamBridgeActorTests : TestKit
return (actor, factory);
}
/// <summary>Verifies that gRPC cleanup unsubscribes through TryGet without opening a channel.</summary>
[Fact]
public void CleanupGrpc_UnsubscribesViaTryGet_WithoutOpeningAChannel()
{
@@ -501,6 +518,7 @@ public class DebugStreamBridgeActorTests : TestKit
Assert.Equal(createdBefore, factory.CreatedCount);
}
/// <summary>Verifies that a session failover unsubscribes the failed endpoint through TryGet and opens only the reconnect channel.</summary>
[Fact]
public void SessionFailover_UnsubscribesFailedEndpointViaTryGet_OpensOnlyTheReconnectChannel()
{
@@ -523,13 +541,14 @@ public class DebugStreamBridgeActorTests : TestKit
}
// ---------------------------------------------------------------------
// M2.18 (#26) — stream-first + replay/dedup
// Stream-first + replay/dedup
// ---------------------------------------------------------------------
/// <summary>Verifies that PreStart opens the gRPC stream before the snapshot arrives.</summary>
[Fact]
public void PreStart_Opens_GrpcStream_Before_Snapshot_Arrives()
{
// M2.18: the gRPC subscription must be opened in PreStart (stream-first),
// Stream-first: the gRPC subscription must be opened in PreStart (stream-first),
// BEFORE the snapshot is delivered, so live events start flowing during the
// snapshot-build + network-transit window. The old lifecycle opened the
// stream only after the snapshot arrived, losing gap-window events.
@@ -545,10 +564,11 @@ public class DebugStreamBridgeActorTests : TestKit
lock (ctx.ReceivedEvents) { Assert.Empty(ctx.ReceivedEvents); }
}
/// <summary>Verifies that an event buffered in the gap window before the snapshot is delivered exactly once after the snapshot.</summary>
[Fact]
public void GapWindow_Event_Buffered_Before_Snapshot_Is_Delivered_Exactly_Once_After_Snapshot()
{
// M2.18: an event arriving DURING the snapshot window (before the snapshot
// An event arriving DURING the snapshot window (before the snapshot
// is delivered) is buffered, then flushed exactly once AFTER the snapshot.
var ctx = CreateBridgeActor();
ctx.CommProbe.ExpectMsg<SiteEnvelope>();
@@ -581,10 +601,11 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
/// <summary>Verifies that a buffered event already reflected in the snapshot is dropped.</summary>
[Fact]
public void Buffered_Event_Already_Reflected_In_Snapshot_Is_Dropped()
{
// M2.18 dedup: a buffered event whose entity is in the snapshot with an equal
// Dedup: a buffered event whose entity is in the snapshot with an equal
// or newer snapshot timestamp (buffered.Timestamp <= snapshot.Timestamp) is
// already reflected and must be DROPPED.
var ctx = CreateBridgeActor();
@@ -618,10 +639,11 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
/// <summary>Verifies that a buffered event strictly newer than the snapshot entity is delivered.</summary>
[Fact]
public void Buffered_Event_Strictly_Newer_Than_Snapshot_Entity_Is_Delivered()
{
// M2.18 dedup: a buffered event strictly newer than the snapshot's entry for
// Dedup: a buffered event strictly newer than the snapshot's entry for
// the same entity (buffered.Timestamp > snapshot.Timestamp) is NOT a dup and
// must be DELIVERED after the snapshot.
var ctx = CreateBridgeActor();
@@ -655,10 +677,11 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
/// <summary>Verifies that buffered alarm deduplication uses the alarm identity and timestamp.</summary>
[Fact]
public void Buffered_Alarm_Dedup_Uses_AlarmIdentity_And_Timestamp()
{
// M2.18 dedup for alarms: identity = (instance, alarm name, source reference).
// Dedup for alarms: identity = (instance, alarm name, source reference).
// A buffered alarm older-or-equal to the snapshot's same-identity alarm is
// dropped; a strictly-newer one is delivered.
var ctx = CreateBridgeActor();
@@ -701,10 +724,11 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
/// <summary>Verifies that buffered events are flushed in arrival order.</summary>
[Fact]
public void Buffered_Events_Flushed_In_Arrival_Order()
{
// M2.18: ordering preserved across multiple buffered events (none are dups —
// Ordering preserved across multiple buffered events (none are dups —
// their entities are absent from the snapshot).
var ctx = CreateBridgeActor();
ctx.CommProbe.ExpectMsg<SiteEnvelope>();
@@ -735,10 +759,11 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
/// <summary>Verifies that after the flush the actor passes subsequent events through immediately.</summary>
[Fact]
public void PassThrough_After_Flush_Delivers_Subsequent_Events_Immediately()
{
// M2.18: after the snapshot+flush the actor switches to pass-through — later
// After the snapshot+flush the actor switches to pass-through — later
// events go straight to _onEvent (no buffering, no dup).
var ctx = CreateBridgeActor();
ctx.CommProbe.ExpectMsg<SiteEnvelope>();
@@ -767,10 +792,11 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
/// <summary>Verifies that an instance-not-found snapshot after the stream was opened first tears down the stream and does not enter pass-through.</summary>
[Fact]
public void InstanceNotFound_After_StreamFirst_Tears_Down_Stream_And_Does_Not_PassThrough()
{
// M2.18 + M2.11: stream-first means the gRPC subscription is already open
// Stream-first means the gRPC subscription is already open
// when an InstanceNotFound snapshot arrives. The bridge must tear that stream
// down (Unsubscribe the just-opened correlation), deliver the not-found
// snapshot, NOT enter pass-through, and stop cleanly.
@@ -812,10 +838,11 @@ public class DebugStreamBridgeActorTests : TestKit
lock (ctx.ReceivedEvents) { Assert.Single(ctx.ReceivedEvents); }
}
/// <summary>Verifies that a reconnect during the buffering phase keeps buffering until the snapshot arrives.</summary>
[Fact]
public void Reconnect_During_Buffering_Phase_Keeps_Buffering_Until_Snapshot()
{
// M2.18: a gRPC error/reconnect BEFORE the snapshot arrives must remain in the
// A gRPC error/reconnect BEFORE the snapshot arrives must remain in the
// buffering phase — events on the new stream are still buffered, then flushed
// when the snapshot finally arrives.
var ctx = CreateBridgeActor();
@@ -849,10 +876,11 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
/// <summary>Verifies that a reconnect after the snapshot resumes pass-through rather than buffering.</summary>
[Fact]
public void Reconnect_After_Snapshot_Resumes_PassThrough_Not_Buffering()
{
// M2.18: a mid-session reconnect (after the snapshot was already delivered)
// A mid-session reconnect (after the snapshot was already delivered)
// must resume pass-through — the snapshot is a one-time thing and events on
// the reconnected stream are delivered immediately, not re-buffered.
var ctx = CreateBridgeActor();
@@ -885,10 +913,11 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
/// <summary>Verifies that the retry count is recovered only after the stream stays stable for the stability window.</summary>
[Fact]
public void RetryCount_RecoveredOnlyAfterStreamStaysStableForStabilityWindow()
{
// Communication-008: after a stream has been connected for the stability
// After a stream has been connected for the stability
// window, the retry budget is recovered — a later transient fault then gets
// a fresh set of retries rather than being counted against the old budget.
DebugStreamBridgeActor.StabilityWindow = TimeSpan.FromMilliseconds(300);
@@ -928,8 +957,9 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
// ── WP2.3: bounded pre-snapshot buffer, hard snapshot deadline, timeout hygiene ──
// ── bounded pre-snapshot buffer, hard snapshot deadline, timeout hygiene ──
/// <summary>Verifies that the pre-snapshot buffer is capped, drops the oldest events and counts the drops.</summary>
[Fact]
public void PreSnapshotBuffer_IsCapped_DropsOldest_AndCountsTheDrops()
{
@@ -986,6 +1016,7 @@ public class DebugStreamBridgeActorTests : TestKit
}, TimeSpan.FromSeconds(10));
}
/// <summary>Verifies that a missing snapshot within the deadline fails the session instead of buffering forever.</summary>
[Fact]
public void NoSnapshotWithinDeadline_FailsTheSession_InsteadOfBufferingForever()
{
@@ -1013,6 +1044,7 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
/// <summary>Verifies that the arrival of the snapshot stands down the deadline.</summary>
[Fact]
public void SnapshotArrival_StandsDownTheDeadline()
{
@@ -1048,6 +1080,7 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
/// <summary>Verifies that stream events still reach the consumer through the wrapped callback path.</summary>
[Fact]
public void StreamEvents_StillReachTheConsumer_ThroughTheWrappedCallbackPath()
{
@@ -1076,6 +1109,7 @@ public class DebugStreamBridgeActorTests : TestKit
// ----- Orphan net: measures the CONSUMER, not the mailbox ----- //
/// <summary>Verifies that a healthy session streaming events with consumer keepalives survives well past the orphan window.</summary>
[Fact]
public void HealthySession_StreamingEvents_WithConsumerKeepalives_SurvivesWellPastTheOrphanWindow()
{
@@ -1132,6 +1166,7 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
/// <summary>Verifies that an orphaned session whose consumer is gone still terminates even while events keep arriving.</summary>
[Fact]
public void OrphanedSession_ConsumerGone_StillTerminates_EvenWhileEventsKeepArriving()
{
@@ -1173,6 +1208,7 @@ public class DebugStreamBridgeActorTests : TestKit
}
}
/// <summary>Verifies that a consumer keepalive renews the orphan window after a near miss.</summary>
[Fact]
public void ConsumerKeepalive_RenewsTheWindow_AfterANearMiss()
{
@@ -1227,10 +1263,12 @@ internal class MockSiteStreamGrpcClient : SiteStreamGrpcClient
private MockSiteStreamGrpcClient(bool _) : base() { }
/// <summary>Initializes a mock client that records subscribe and unsubscribe calls.</summary>
public MockSiteStreamGrpcClient() : base()
{
}
/// <inheritdoc />
public override Task SubscribeAsync(
string correlationId,
string instanceUniqueName,
@@ -1249,6 +1287,7 @@ internal class MockSiteStreamGrpcClient : SiteStreamGrpcClient
return tcs.Task;
}
/// <inheritdoc />
public override void Unsubscribe(string correlationId)
{
lock (_lock) { _unsubscribedCorrelationIds.Add(correlationId); }
@@ -1269,14 +1308,18 @@ internal record MockSubscription(
internal class MockSiteStreamGrpcClientFactory : SiteStreamGrpcClientFactory
{
private readonly MockSiteStreamGrpcClient _mockClient;
/// <summary>Gets the endpoints requested through <c>GetOrCreate</c>, in call order.</summary>
public List<string> RequestedEndpoints { get; } = new();
/// <summary>Initializes the factory with the mock client it always returns.</summary>
/// <param name="mockClient">The mock client returned for every endpoint.</param>
public MockSiteStreamGrpcClientFactory(MockSiteStreamGrpcClient mockClient)
: base(Microsoft.Extensions.Logging.Abstractions.NullLoggerFactory.Instance)
{
_mockClient = mockClient;
}
/// <inheritdoc />
public override SiteStreamGrpcClient GetOrCreate(string siteIdentifier, string grpcEndpoint)
{
RequestedEndpoints.Add(grpcEndpoint);
@@ -1285,7 +1328,8 @@ internal class MockSiteStreamGrpcClientFactory : SiteStreamGrpcClientFactory
// Mirrors the real factory's TryGet: returns the client only for an endpoint
// already opened via GetOrCreate, never creating one. Lets teardown/failover
// unsubscribe paths (now TryGet-based, Task 6) resolve the mock client.
// unsubscribe paths (now TryGet-based) resolve the mock client.
/// <inheritdoc />
public override SiteStreamGrpcClient? TryGet(string siteIdentifier, string grpcEndpoint)
=> RequestedEndpoints.Contains(grpcEndpoint) ? _mockClient : null;
}
@@ -1293,27 +1337,33 @@ internal class MockSiteStreamGrpcClientFactory : SiteStreamGrpcClientFactory
/// <summary>
/// Endpoint-aware mock factory: hands out a distinct <see cref="MockSiteStreamGrpcClient"/>
/// per endpoint, mirroring the real factory's corrected NodeA→NodeB failover behaviour
/// so node-flip coverage is meaningful (Communication-015).
/// so node-flip coverage is meaningful.
/// </summary>
internal class EndpointTrackingGrpcClientFactory : SiteStreamGrpcClientFactory
{
private readonly System.Collections.Concurrent.ConcurrentDictionary<string, MockSiteStreamGrpcClient> _byEndpoint = new();
/// <summary>Initializes an empty endpoint-aware factory.</summary>
public EndpointTrackingGrpcClientFactory()
: base(Microsoft.Extensions.Logging.Abstractions.NullLoggerFactory.Instance)
{
}
/// <summary>Gets the mock client bound to an endpoint, creating it on first use.</summary>
/// <param name="endpoint">The gRPC endpoint address.</param>
/// <returns>The mock client for the endpoint.</returns>
public MockSiteStreamGrpcClient ClientFor(string endpoint) =>
_byEndpoint.GetOrAdd(endpoint, _ => new MockSiteStreamGrpcClient());
/// <summary>Number of distinct endpoint clients created so far (channels opened).</summary>
public int CreatedCount => _byEndpoint.Count;
/// <inheritdoc />
public override SiteStreamGrpcClient GetOrCreate(string siteIdentifier, string grpcEndpoint)
=> ClientFor(grpcEndpoint);
// TryGet never creates: returns the client only for an already-opened endpoint.
/// <inheritdoc />
public override SiteStreamGrpcClient? TryGet(string siteIdentifier, string grpcEndpoint)
=> _byEndpoint.TryGetValue(grpcEndpoint, out var client) ? client : null;
}