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:
+56
-10
@@ -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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user