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
@@ -7,7 +7,7 @@ using ZB.MOM.WW.ScadaBridge.TestSupport;
namespace ZB.MOM.WW.ScadaBridge.StoreAndForward.Tests;
/// <summary>
/// Audit Log #23 — M3 Bundle E Tasks E4 + E5: the store-and-forward retry
/// Cached-call lifecycle observer: the store-and-forward retry
/// loop invokes <see cref="ICachedCallLifecycleObserver"/> after every
/// cached-call attempt. The observer is given a
/// <see cref="CachedCallAttemptContext"/> derived from the underlying
@@ -32,6 +32,7 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
private readonly StoreAndForwardOptions _options;
private readonly CapturingObserver _observer;
/// <summary>Initializes the test with a temporary local database, storage and observer.</summary>
public CachedCallAttemptEmissionTests()
{
_localDb = TestLocalDb.CreateTemp("E4Tests");
@@ -55,8 +56,13 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
siteId: "site-77");
}
/// <summary>Prepares the test class before the tests run.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public async Task InitializeAsync() => await _storage.InitializeAsync();
/// <summary>Releases the resources held by this test class asynchronously.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public Task DisposeAsync() => Task.CompletedTask;
/// <summary>Releases the resources held by this test class.</summary>
public void Dispose()
{
var path = _localDb.Path;
@@ -70,9 +76,12 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
/// </summary>
private sealed class CapturingObserver : ICachedCallLifecycleObserver
{
/// <summary>The observer notifications received, in order.</summary>
public List<CachedCallAttemptContext> Notifications { get; } = new();
/// <summary>When true, the observer throws on every notification.</summary>
public Exception? ThrowOnNotify { get; set; }
/// <inheritdoc />
public Task OnAttemptCompletedAsync(CachedCallAttemptContext context, CancellationToken ct = default)
{
if (ThrowOnNotify != null)
@@ -90,7 +99,7 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
private async Task<TrackedOperationId> EnqueueBufferedAsync(
StoreAndForwardCategory category, string target, int maxRetries = 3)
{
// The TrackedOperationId is the S&F message id (Bundle E3 contract).
// The TrackedOperationId is the S&F message id (see the cached-call contract).
var trackedId = TrackedOperationId.New();
await _service.EnqueueAsync(
category,
@@ -104,8 +113,10 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
return trackedId;
}
// ── Task E4: per-attempt observer notifications ──
// ── Per-attempt observer notifications ──
/// <summary>Verifies that a failed attempt with an HTTP 500 emits attempted telemetry.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Attempt_FailWithHttp500_EmitsAttemptedTelemetry()
{
@@ -129,6 +140,8 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Equal("Plant.Pump42", notification.SourceInstanceId);
}
/// <summary>Verifies that a successful attempt emits a delivered outcome.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Attempt_Success_EmitsDeliveredOutcome()
{
@@ -147,6 +160,8 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Null(notification.LastError);
}
/// <summary>Verifies that a permanent failure emits a permanent-failure outcome.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Attempt_PermanentFailure_EmitsPermanentFailureOutcome()
{
@@ -162,6 +177,8 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Equal(CachedCallAttemptOutcome.PermanentFailure, notification.Outcome);
}
/// <summary>Verifies that an attempt of a cached database write emits on the database outbound channel.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Attempt_CachedDbWrite_EmitsDbOutboundChannel()
{
@@ -178,6 +195,8 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Equal("myDb", notification.Target);
}
/// <summary>Verifies that an attempt in the notification category produces no observer notification.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Attempt_NotificationCategory_NoObserverNotification()
{
@@ -198,12 +217,14 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Empty(_observer.Notifications);
}
/// <summary>Verifies that an attempt whose message id is not a GUID produces no observer notification.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Attempt_MessageIdNotAGuid_NoObserverNotification()
{
// Pre-M3 cached calls (no TrackedOperationId threaded in) use a random
// GUID-N message id from S&F itself. We should still emit (M3 expects
// post-rollout these are tracked) — BUT pre-rollout messages can have
// Earlier cached calls (no TrackedOperationId threaded in) use a random
// GUID-N message id from S&F itself. We should still emit (post-rollout these
// are tracked) — BUT pre-rollout messages can have
// a non-parseable id, in which case the observer is silently skipped
// to keep S&F bookkeeping intact.
_service.RegisterDeliveryHandler(StoreAndForwardCategory.ExternalSystem,
@@ -221,8 +242,10 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Empty(_observer.Notifications);
}
// ── Task E5: terminal-state observer notifications ──
// ── Terminal-state observer notifications ──
/// <summary>Verifies that terminal delivery emits a resolve with the delivered status.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Terminal_Delivered_EmitsResolveWithDeliveredStatus()
{
@@ -242,6 +265,8 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Equal(CachedCallAttemptOutcome.Delivered, notification.Outcome);
}
/// <summary>Verifies that parking after max retries emits a resolve with the parked-max-retries status.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Terminal_Parked_OnMaxRetries_EmitsParkedMaxRetries()
{
@@ -261,6 +286,8 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Equal(trackedId, _observer.Notifications[1].TrackedOperationId);
}
/// <summary>Verifies that a retry-fail then retry-succeed lifecycle emits the expected sequence.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Lifecycle_RetryFail_RetrySucceed_EmitsExpectedSequence()
{
@@ -284,8 +311,10 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Equal(trackedId, _observer.Notifications[1].TrackedOperationId);
}
// ── Audit Log #23 (ExecutionId Task 4): ExecutionId / SourceScript ──
// ── ExecutionId / SourceScript ──
/// <summary>Verifies that an attempt carries the execution id and source script from the buffered message.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Attempt_CarriesExecutionIdAndSourceScript_FromBufferedMessage()
{
@@ -317,6 +346,8 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Equal("Plant.Pump42/OnTick", notification.SourceScript);
}
/// <summary>Verifies that a null execution id and source script surface as null.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Attempt_NullExecutionIdAndSourceScript_SurfaceAsNull()
{
@@ -334,6 +365,8 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Null(notification.SourceScript);
}
/// <summary>Verifies that a terminal resolve carries the execution id and source script.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task TerminalResolve_CarriesExecutionIdAndSourceScript()
{
@@ -364,8 +397,10 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Equal("Plant.Tank/OnAlarm", notification.SourceScript);
}
// ── Audit Log #23 (ParentExecutionId Task 6): ParentExecutionId ──
// ── ParentExecutionId ──
/// <summary>Verifies that an attempt carries the parent execution id from the buffered message.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Attempt_CarriesParentExecutionId_FromBufferedMessage()
{
@@ -395,6 +430,8 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Equal(parentExecutionId, notification.ParentExecutionId);
}
/// <summary>Verifies that a null parent execution id surfaces as null.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Attempt_NullParentExecutionId_SurfacesAsNull()
{
@@ -412,6 +449,8 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Null(notification.ParentExecutionId);
}
/// <summary>Verifies that a terminal resolve carries the parent execution id.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task TerminalResolve_CarriesParentExecutionId()
{
@@ -443,6 +482,8 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
// ── Best-effort contract: observer throws must NOT corrupt retry bookkeeping ──
/// <summary>Verifies that an observer that throws does not corrupt the retry count.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Observer_Throws_DoesNotCorruptRetryCount()
{
@@ -460,16 +501,21 @@ public class CachedCallAttemptEmissionTests : IAsyncLifetime, IDisposable
Assert.Null(msg);
}
// ── Task 19: audit-observer decoupled from the sweep via an ordered channel ──
// ── Audit-observer decoupled from the sweep via an ordered channel ──
private sealed class DelegatingObserver : ICachedCallLifecycleObserver
{
private readonly Func<CachedCallAttemptContext, Task> _onNotify;
/// <summary>Initializes the observer with the callback to invoke for each notification.</summary>
/// <param name="onNotify">The callback invoked for each attempt notification.</param>
public DelegatingObserver(Func<CachedCallAttemptContext, Task> onNotify) => _onNotify = onNotify;
/// <inheritdoc />
public Task OnAttemptCompletedAsync(CachedCallAttemptContext context, CancellationToken ct = default)
=> _onNotify(context);
}
/// <summary>Verifies that a slow observer does not block the sweep and events arrive in order.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task SlowObserver_DoesNotBlockTheSweep_AndEventsArriveInOrder()
{