docs(src): add missing XML docs and strip tracking-ID comments

Sweep of 203 source files resolving CommentChecker findings: add
<summary>/<param>/<returns>/<inheritdoc> where missing, and remove
resolved task/issue tracking markers (Tests-NNN, Worker-NNN, Server-NNN,
Task N) from code comments. Comment/doc-only — no logic changes.
Server+Tests build clean under TreatWarningsAsErrors.
This commit is contained in:
Joseph Doherty
2026-07-07 14:09:49 -04:00
parent 8914472706
commit fca978de07
203 changed files with 1834 additions and 1383 deletions
@@ -13,7 +13,7 @@ using ZB.MOM.WW.MxGateway.Tests.TestSupport;
namespace ZB.MOM.WW.MxGateway.Tests.Gateway.Grpc;
/// <summary>
/// Tests for Server-021. <c>MxAccessGatewayService.ApplyConstraintsAsync</c> and
/// <c>MxAccessGatewayService.ApplyConstraintsAsync</c> and
/// the <c>BulkConstraintPlan</c> / <c>ReadBulkConstraintPlan</c> /
/// <c>WriteBulkConstraintPlan</c> / <c>SubscribeBulkConstraintPlan</c> reply-merge
/// logic was previously exercised only with an allow-all enforcer, so denial
@@ -34,6 +34,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// worker once with only the allowed tags, then splice the denied entries
/// back into the reply at their original indices.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_AddItemBulk_WithMixedDenials_InterleavesDeniedAndAllowedInOriginalIndexOrder()
{
@@ -95,6 +96,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// <see cref="BulkConstraintPlan.HasAllowedItems"/> false, return the
/// denied-only reply, and never call the session manager.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_SubscribeBulk_WhenAllTagsDenied_DoesNotCallWorkerAndReturnsDeniedReply()
{
@@ -118,6 +120,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// <c>FilterHandleBulkAsync</c> against <c>CheckReadHandleAsync</c>. Partial
/// denial must still produce a merged-by-index <c>BulkSubscribeReply</c>.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_AdviseItemBulk_WithMixedHandleDenials_MergesDeniedIntoReply()
{
@@ -166,6 +169,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// unchanged — the constraint plan is null and no merge occurs. Regression
/// guard against accidentally engaging the merge path for the common case.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_SubscribeBulk_WithAllowAllEnforcer_PassesThroughUnchanged()
{
@@ -208,6 +212,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// the SubscribeBulk family because the reply slot is
/// <c>BulkReadReply</c>, not <c>BulkSubscribeReply</c>.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_ReadBulk_WithMixedDenials_MergesDeniedBulkReadResults()
{
@@ -255,6 +260,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// <see cref="MxAccessGatewayService"/>'s <c>ReadBulkConstraintPlan</c>
/// <c>CreateDeniedReply</c> path.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_ReadBulk_WhenAllTagsDenied_ShortCircuitsWithDeniedOnlyReply()
{
@@ -279,6 +285,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// forwarded command and splice a denied <c>BulkWriteResult</c> back in at
/// the original index.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_WriteBulk_WithDeniedHandle_DropsEntryFromWorkerCallAndMergesDenialIntoReply()
{
@@ -329,6 +336,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// switch arm than plain <c>WriteBulk</c>. The merge logic is shared, so a
/// full denial here is enough to prove the secured-bulk routing.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_WriteSecuredBulk_WhenAllHandlesDenied_ShortCircuitsWithDeniedOnlyReply()
{
@@ -347,13 +355,14 @@ public sealed class MxAccessGatewayServiceConstraintTests
}
/// <summary>
/// Tests-020: <c>Write2Bulk</c> takes the third <c>GetPayload</c>/<c>SetPayload</c>
/// <c>Write2Bulk</c> takes the third <c>GetPayload</c>/<c>SetPayload</c>
/// switch arm in <c>WriteBulkConstraintPlan</c>. The merge logic is shared with
/// <c>WriteBulk</c>, but a full denial through the <c>CreateDeniedReply</c> path
/// proves the <c>Write2Bulk</c> arm of the per-kind <c>SetPayload</c> switch fires
/// (and not, say, <c>WriteBulk</c> by mistake) — guarding against a refactor that
/// drops or misroutes the <c>Write2Bulk</c> case.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_Write2Bulk_WhenAllHandlesDenied_ShortCircuitsWithDeniedOnlyReply()
{
@@ -377,11 +386,12 @@ public sealed class MxAccessGatewayServiceConstraintTests
}
/// <summary>
/// Tests-020: <c>WriteSecured2Bulk</c> takes the fourth <c>GetPayload</c>/<c>SetPayload</c>
/// <c>WriteSecured2Bulk</c> takes the fourth <c>GetPayload</c>/<c>SetPayload</c>
/// switch arm in <c>WriteBulkConstraintPlan</c>. Same reasoning as
/// <c>Write2Bulk</c> — assert the <c>WriteSecured2Bulk</c> reply slot is populated
/// to prove that arm of the switch fires.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_WriteSecured2Bulk_WhenAllHandlesDenied_ShortCircuitsWithDeniedOnlyReply()
{
@@ -404,10 +414,10 @@ public sealed class MxAccessGatewayServiceConstraintTests
Assert.Empty(reply.WriteSecuredBulk?.Results ?? new Google.Protobuf.Collections.RepeatedField<BulkWriteResult>());
}
// === Worker reply-count divergence (Tests-024) ===
// === Worker reply-count divergence ===
/// <summary>
/// Tests-024: <c>WriteBulkConstraintPlan.MergeDeniedInto</c> dequeues from
/// <c>WriteBulkConstraintPlan.MergeDeniedInto</c> dequeues from
/// <c>allowedResults</c> per non-denied slot via <c>Queue.TryDequeue</c>,
/// which silently returns <c>false</c> when the queue is empty. Pin the
/// observable behaviour when the worker returns FEWER allowed results than
@@ -417,6 +427,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// This fixture makes that "silent truncate" behaviour explicit so a future
/// change either fills the gap with a synthetic failure or fails this test.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_WriteBulk_WhenWorkerReturnsFewerResultsThanAllowed_MergedReplyIsTruncated()
{
@@ -464,12 +475,13 @@ public sealed class MxAccessGatewayServiceConstraintTests
}
/// <summary>
/// Tests-024: when the worker returns MORE allowed results than the
/// When the worker returns MORE allowed results than the
/// gateway forwarded, the extras must be silently ignored — the merged
/// reply length stays at <c>OriginalCount</c>. This pins the
/// <c>for index &lt; OriginalCount</c> loop bound so a regression that
/// accidentally surfaces extras as trailing results is caught.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_WriteBulk_WhenWorkerReturnsExtraResults_IgnoresExtras()
{
@@ -527,6 +539,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// <see cref="StatusCode.PermissionDenied"/> via <c>EnforceWriteHandleAsync</c>
/// and never reach the session manager.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_Write_WithDeniedHandle_ThrowsPermissionDeniedAndDoesNotCallWorker()
{
@@ -554,6 +567,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// enforce helper -> <c>RecordDenialAsync</c>, so the recorded denial carries the exact
/// id the client sent (including non-GUID trace ids used by Rust/Python/Java clients).
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_Write_WithDeniedHandle_ThreadsClientCorrelationIdIntoRecordedDenial()
{
@@ -581,6 +595,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// <c>ApplyConstraintsAsync</c> (Write/Write2/WriteSecured/WriteSecured2) is
/// reachable for at least one of the secured kinds.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_WriteSecured_WithDeniedHandle_ThrowsPermissionDenied()
{
@@ -604,6 +619,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// <see cref="StatusCode.PermissionDenied"/> via <c>EnforceReadTagAsync</c>
/// and never reach the session manager.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Invoke_AddItem_WithDeniedTag_ThrowsPermissionDeniedAndDoesNotCallWorker()
{
@@ -881,11 +897,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
/// <param name="session">The session to seed.</param>
public void SeedSession(GatewaySession session) => seededSessions[session.SessionId] = session;
/// <summary>Opens a test session asynchronously.</summary>
/// <param name="request">The session open request.</param>
/// <param name="clientIdentity">The client identity, if any.</param>
/// <param name="ownerKeyId">The API key identifier of the caller, if any.</param>
/// <param name="cancellationToken">Token to observe for cancellation.</param>
/// <inheritdoc />
public Task<GatewaySession> OpenSessionAsync(
SessionOpenRequest request,
string? clientIdentity,
@@ -893,9 +905,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
CancellationToken cancellationToken) =>
Task.FromResult(seededSessions.Values.First());
/// <summary>Tries to get a test session by identifier.</summary>
/// <param name="sessionId">The session identifier.</param>
/// <param name="session">The session, if found.</param>
/// <inheritdoc />
public bool TryGetSession(string sessionId, out GatewaySession session)
{
if (seededSessions.TryGetValue(sessionId, out GatewaySession? seeded))
@@ -914,10 +924,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
return true;
}
/// <summary>Invokes a worker command and returns the reply asynchronously.</summary>
/// <param name="sessionId">The session identifier.</param>
/// <param name="command">The worker command.</param>
/// <param name="cancellationToken">Token to observe for cancellation.</param>
/// <inheritdoc />
public Task<WorkerCommandReply> InvokeAsync(
string sessionId,
WorkerCommand command,
@@ -928,9 +935,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
return Task.FromResult(InvokeReply);
}
/// <summary>Reads events from the session asynchronously.</summary>
/// <param name="sessionId">The session identifier.</param>
/// <param name="cancellationToken">Token to observe for cancellation.</param>
/// <inheritdoc />
public async IAsyncEnumerable<WorkerEvent> ReadEventsAsync(
string sessionId,
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken)
@@ -943,33 +948,25 @@ public sealed class MxAccessGatewayServiceConstraintTests
}
}
/// <summary>Closes a test session asynchronously.</summary>
/// <param name="sessionId">The session identifier.</param>
/// <param name="cancellationToken">Token to observe for cancellation.</param>
/// <inheritdoc />
public Task<SessionCloseResult> CloseSessionAsync(
string sessionId,
CancellationToken cancellationToken) =>
Task.FromResult(new SessionCloseResult(sessionId, SessionState.Closed, AlreadyClosed: false));
/// <summary>Kills a worker process asynchronously.</summary>
/// <param name="sessionId">The session identifier.</param>
/// <param name="reason">The reason for killing the worker.</param>
/// <param name="cancellationToken">Token to observe for cancellation.</param>
/// <inheritdoc />
public Task<SessionCloseResult> KillWorkerAsync(
string sessionId,
string reason,
CancellationToken cancellationToken) =>
Task.FromResult(new SessionCloseResult(sessionId, SessionState.Closed, AlreadyClosed: false));
/// <summary>Closes expired session leases asynchronously.</summary>
/// <param name="now">The current time to check against.</param>
/// <param name="cancellationToken">Token to observe for cancellation.</param>
/// <inheritdoc />
public Task<int> CloseExpiredLeasesAsync(
DateTimeOffset now,
CancellationToken cancellationToken) => Task.FromResult(0);
/// <summary>Shuts down the test session manager asynchronously.</summary>
/// <param name="cancellationToken">Token to observe for cancellation.</param>
/// <inheritdoc />
public Task ShutdownAsync(CancellationToken cancellationToken) => Task.CompletedTask;
private static GatewaySession CreateFallbackSession(string sessionId)
@@ -994,9 +991,7 @@ public sealed class MxAccessGatewayServiceConstraintTests
private sealed class FakeEventStreamService(FakeSessionManager sessionManager) : IEventStreamService
{
/// <summary>Streams events for the test session asynchronously.</summary>
/// <param name="request">The stream events request.</param>
/// <param name="cancellationToken">Token to observe for cancellation.</param>
/// <inheritdoc />
public async IAsyncEnumerable<MxEvent> StreamEventsAsync(
StreamEventsRequest request,
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken)
@@ -1012,33 +1007,28 @@ public sealed class MxAccessGatewayServiceConstraintTests
private sealed class FakeWorkerClient : IWorkerClient
{
/// <summary>Gets the test session identifier.</summary>
/// <inheritdoc />
public string SessionId { get; } = MxAccessGatewayServiceConstraintTests.SessionId;
/// <summary>Gets the test worker process identifier.</summary>
/// <inheritdoc />
public int? ProcessId { get; } = 1234;
/// <summary>Gets the test worker client state.</summary>
/// <inheritdoc />
public WorkerClientState State { get; } = WorkerClientState.Ready;
/// <summary>Gets the last recorded heartbeat time.</summary>
/// <inheritdoc />
public DateTimeOffset LastHeartbeatAt { get; } = DateTimeOffset.UtcNow;
/// <summary>Starts the test worker client asynchronously.</summary>
/// <param name="cancellationToken">Token to observe for cancellation.</param>
/// <inheritdoc />
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
/// <summary>Invokes a command on the test worker asynchronously.</summary>
/// <param name="command">The worker command.</param>
/// <param name="timeout">Maximum time to wait for completion.</param>
/// <param name="cancellationToken">Token to observe for cancellation.</param>
/// <inheritdoc />
public Task<WorkerCommandReply> InvokeAsync(
WorkerCommand command,
TimeSpan timeout,
CancellationToken cancellationToken) => Task.FromResult(new WorkerCommandReply());
/// <summary>Reads events from the test worker asynchronously.</summary>
/// <param name="cancellationToken">Token to observe for cancellation.</param>
/// <inheritdoc />
public async IAsyncEnumerable<WorkerEvent> ReadEventsAsync(
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken)
{
@@ -1046,18 +1036,16 @@ public sealed class MxAccessGatewayServiceConstraintTests
yield break;
}
/// <summary>Shuts down the test worker client asynchronously.</summary>
/// <param name="timeout">Maximum time to wait for completion.</param>
/// <param name="cancellationToken">Token to observe for cancellation.</param>
/// <inheritdoc />
public Task ShutdownAsync(TimeSpan timeout, CancellationToken cancellationToken) => Task.CompletedTask;
/// <summary>Kills the test worker process.</summary>
/// <param name="reason">The reason for killing the worker.</param>
/// <inheritdoc />
public void Kill(string reason)
{
}
/// <inheritdoc />
/// <summary>Disposes the test worker client. No-op — there is no unmanaged state to release.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
}
}