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
@@ -6,7 +6,7 @@ using ZB.MOM.WW.ScadaBridge.TestSupport;
namespace ZB.MOM.WW.ScadaBridge.StoreAndForward.Tests;
/// <summary>
/// WP-9: Tests for SQLite persistence layer.
/// Tests for SQLite persistence layer.
/// </summary>
/// <remarks>
/// Backed by a real temp-file LocalDb rather than the shared-cache in-memory database
@@ -20,16 +20,22 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
private readonly TestLocalDb _localDb;
private readonly StoreAndForwardStorage _storage;
/// <summary>Creates a temporary LocalDb-backed store for each test.</summary>
public StoreAndForwardStorageTests()
{
_localDb = TestLocalDb.CreateTemp("StorageTests");
_storage = new StoreAndForwardStorage(_localDb.Db, NullLogger<StoreAndForwardStorage>.Instance);
}
/// <summary>Initializes the store-and-forward storage schema.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public async Task InitializeAsync() => await _storage.InitializeAsync();
/// <summary>Completes immediately; the synchronous <c>Dispose</c> releases the resources.</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()
{
// Dispose first — the master connection anchors the WAL, so the sidecars
@@ -39,6 +45,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
TestLocalDb.DeleteFiles(path);
}
/// <summary>Verifies that enqueuing stores the message.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task EnqueueAsync_StoresMessage()
{
@@ -52,6 +60,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Equal("target1", retrieved.Target);
}
/// <summary>Verifies that enqueuing works for every message category.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task EnqueueAsync_AllCategories()
{
@@ -68,6 +78,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Equal(StoreAndForwardCategory.CachedDbWrite, db!.Category);
}
/// <summary>Verifies that removing a message deletes it from the store.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RemoveMessageAsync_RemovesSuccessfully()
{
@@ -78,6 +90,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Null(retrieved);
}
/// <summary>Verifies that updating a message persists the changed fields.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task UpdateMessageAsync_UpdatesFields()
{
@@ -96,6 +110,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Equal("Connection refused", retrieved.LastError);
}
/// <summary>Verifies that the retry query returns only pending messages.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetMessagesForRetryAsync_ReturnsOnlyPendingMessages()
{
@@ -112,10 +128,12 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.All(forRetry, m => Assert.Equal(StoreAndForwardMessageStatus.Pending, m.Status));
}
/// <summary>Verifies that with a non-zero retry interval the retry query excludes messages not yet due and includes due ones.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetMessagesForRetryAsync_NonZeroInterval_ExcludesNotYetDueIncludesDue()
{
// StoreAndForward-013: exercise the julianday elapsed-time comparison with a
// Exercise the julianday elapsed-time comparison with a
// non-zero retry interval. A message attempted just now must NOT be due; one
// attempted long ago must be due.
var notDue = CreateMessage("notdue", StoreAndForwardCategory.ExternalSystem);
@@ -141,6 +159,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Contains("never", ids);
}
/// <summary>Verifies that the parked query returns only parked messages.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetParkedMessagesAsync_ReturnsParkedOnly()
{
@@ -154,6 +174,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.All(messages, m => Assert.Equal(StoreAndForwardMessageStatus.Parked, m.Status));
}
/// <summary>Verifies that retrying a parked message moves it back to pending.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RetryParkedMessageAsync_MovesToPending()
{
@@ -171,10 +193,12 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Equal(0, retrieved.RetryCount);
}
/// <summary>Verifies that retrying a parked message clears its last attempt time so it is immediately due.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RetryParkedMessageAsync_ClearsLastAttemptAt_SoMessageIsImmediatelyDue()
{
// StoreAndForward-010: a re-queued parked message must be unambiguously due
// A re-queued parked message must be unambiguously due
// for the next sweep regardless of its (stale) last_attempt_at. Use a large
// retry interval so a leftover timestamp would otherwise exclude the message.
var msg = CreateMessage("requeue1", StoreAndForwardCategory.ExternalSystem);
@@ -196,6 +220,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Contains(due, m => m.Id == "requeue1");
}
/// <summary>Verifies that discarding a parked message removes it.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DiscardParkedMessageAsync_RemovesMessage()
{
@@ -211,6 +237,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Null(retrieved);
}
/// <summary>Verifies that the buffer depth query returns the correct count per category.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetBufferDepthByCategoryAsync_ReturnsCorrectCounts()
{
@@ -222,6 +250,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.True(depth.GetValueOrDefault(StoreAndForwardCategory.ExternalSystem) >= 2);
}
/// <summary>Verifies that the origin-instance query returns the correct message count.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetMessageCountByOriginInstanceAsync_ReturnsCount()
{
@@ -237,6 +267,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Equal(2, count);
}
/// <summary>Verifies that parked messages are returned correctly across pages.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetParkedMessagesAsync_Pagination()
{
@@ -256,10 +288,12 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Equal(2, page2.Count);
}
/// <summary>Verifies that the transactioned parked reads report a count that matches the full result set.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetParkedMessagesAsync_TransactionedReads_CountMatchesFullResultSet()
{
// StoreAndForward-006: the COUNT(*) and paged SELECT now run inside one
// The COUNT(*) and paged SELECT now run inside one
// transaction so they share a consistent snapshot. This functional check
// guards the fix — it verifies the transaction wiring did not break paging:
// the reported TotalCount and the rows assembled across all pages agree, and
@@ -289,6 +323,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Equal(25, collected.Distinct().Count());
}
/// <summary>Verifies that the status query returns an accurate message count.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetMessageCountByStatusAsync_ReturnsAccurateCount()
{
@@ -299,8 +335,10 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.True(count >= 1);
}
// ── Audit Log #23 (ExecutionId Task 4): execution_id / source_script ──
// ── ExecutionId: execution_id / source_script ──
/// <summary>Verifies that enqueuing round-trips the execution id and source script.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task EnqueueAsync_RoundTripsExecutionIdAndSourceScript()
{
@@ -320,6 +358,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Equal("Plant.Pump42/OnTick", retrieved.SourceScript);
}
/// <summary>Verifies that a null execution id and source script round-trip as null.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task EnqueueAsync_NullExecutionIdAndSourceScript_RoundTripAsNull()
{
@@ -337,6 +377,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Null(retrieved.SourceScript);
}
/// <summary>Verifies that the execution id and source script survive a retry sweep read.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ExecutionIdAndSourceScript_SurviveRetrySweepRead()
{
@@ -357,6 +399,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Equal("Plant.Tank/OnAlarm", row.SourceScript);
}
/// <summary>Verifies that a legacy row without the new columns reads back with null values.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task LegacyRowWithoutNewColumns_ReadsBackAsNull()
{
@@ -401,6 +445,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Null(retrieved.SourceScript);
}
/// <summary>Verifies that a malformed execution id reads back as null without aborting the retry sweep.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task MalformedExecutionId_ReadsBackAsNull_DoesNotAbortRetrySweep()
{
@@ -440,6 +486,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Null(retrieved!.ExecutionId);
}
/// <summary>Verifies that initialization is idempotent when the columns already exist.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InitializeAsync_IsIdempotent_WhenColumnsAlreadyExist()
{
@@ -456,8 +504,10 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Equal(message.ExecutionId, retrieved!.ExecutionId);
}
// ── Audit Log #23 (ParentExecutionId Task 6): parent_execution_id ──
// ── ParentExecutionId: parent_execution_id ──
/// <summary>Verifies that enqueuing round-trips the parent execution id.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task EnqueueAsync_RoundTripsParentExecutionId()
{
@@ -475,6 +525,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Equal(parentExecutionId, retrieved!.ParentExecutionId);
}
/// <summary>Verifies that a null parent execution id round-trips as null.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task EnqueueAsync_NullParentExecutionId_RoundTripsAsNull()
{
@@ -490,6 +542,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Null(retrieved!.ParentExecutionId);
}
/// <summary>Verifies that the parent execution id survives a retry sweep read.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ParentExecutionId_SurvivesRetrySweepRead()
{
@@ -508,12 +562,14 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Equal(parentExecutionId, row.ParentExecutionId);
}
/// <summary>Verifies that a legacy row without the parent execution id column reads back with a null value.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task LegacyRowWithoutParentExecutionIdColumn_ReadsBackAsNull()
{
// Back-compat: a row persisted by a build that pre-dates the
// parent_execution_id column must still deserialize, with
// ParentExecutionId reading back as null. Simulate the pre-Task-6
// ParentExecutionId reading back as null. Simulate the pre-ParentExecutionId
// schema (which already has execution_id / source_script from the
// ExecutionId rollout) by recreating the table without
// parent_execution_id, inserting directly, then running InitializeAsync
@@ -554,6 +610,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Null(retrieved.ParentExecutionId);
}
/// <summary>Verifies that a malformed parent execution id reads back as null without aborting the retry sweep.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task MalformedParentExecutionId_ReadsBackAsNull_DoesNotAbortRetrySweep()
{
@@ -589,8 +647,10 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Null(retrieved!.ParentExecutionId);
}
// ── Task 7 (arch review 02, Performance): bounded due-rows query ──
// ── Bounded due-rows query ──
/// <summary>Verifies that the retry query honors its limit and returns the oldest messages first.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetMessagesForRetry_HonorsLimit_OldestFirst()
{
@@ -649,6 +709,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
// library, so the shim is gone — but either way it is not this class's to assert,
// and SiteLocalDbDirectoryTests pins the outcome for the site host.
/// <summary>Verifies that initialization leaves the database in WAL journal mode.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Initialize_LeavesTheDatabaseInWalJournalMode()
{
@@ -675,8 +737,10 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
}
}
// ── Task 18: epoch-ms due-check ──
// ── Epoch-ms due-check ──
/// <summary>Verifies that the retry query uses epoch milliseconds and respects the retry interval.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetMessagesForRetry_UsesEpochMs_RespectsInterval()
{
@@ -701,6 +765,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Assert.Single(await _storage.GetMessagesForRetryAsync());
}
/// <summary>Verifies that initialization backfills epoch milliseconds for legacy rows.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Initialize_BackfillsEpochMs_ForLegacyRows()
{
@@ -738,7 +804,7 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
return result is DBNull ? null : result;
}
// ── Task 20: buffer-resync storage primitives ──
// ── Buffer-resync storage primitives ──
private static StoreAndForwardMessage NewMsg(
string id,
@@ -756,6 +822,8 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
Status = status,
};
/// <summary>Verifies that the all-messages query returns every status, oldest first, up to the limit.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetAllMessages_ReturnsEveryStatus_OldestFirst_UpToLimit()
{
@@ -779,8 +847,10 @@ public class StoreAndForwardStorageTests : IAsyncLifetime, IDisposable
// LocalDbConfigConvergenceTests.ANodeWithNewerLocalRows_KeepsThem_WhenAPeerSnapshotArrives
// now covers.
// ── Task 23: oldest-parked-age health signal ──
// ── Oldest-parked-age health signal ──
/// <summary>Verifies that the oldest-parked query returns the oldest parked row's creation time, or null when none are parked.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetOldestParkedCreatedAt_ReturnsOldestParkedRow_OrNull()
{