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