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
@@ -32,6 +32,7 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
private readonly SharedScriptLibrary _sharedScriptLibrary;
private readonly TestLocalDb _localDb;
/// <summary>Initializes the test with a temporary SQLite storage and an in-memory shared script library.</summary>
public DeploymentManagerActorTests()
{
_localDb = TestLocalDb.CreateTemp("dm-test");
@@ -45,6 +46,7 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
_compilationService, NullLogger<SharedScriptLibrary>.Instance);
}
/// <inheritdoc />
void IDisposable.Dispose()
{
// TestKit teardown first, so no in-flight actor can reach a disposed ILocalDb;
@@ -94,7 +96,7 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
/// Builds a config carrying a single STATIC List attribute whose canonical
/// JSON-array default the Instance Actor decodes into a typed <c>List&lt;int&gt;</c>
/// in memory (InstanceActor.PreStart / DecodeAttributeValue). Used to drive a
/// routed wait whose matched value is a collection — the shape WS-4 normalizes
/// routed wait whose matched value is a collection — the shape that is normalized
/// for cross-process transport.
/// </summary>
private static string MakeConfigWithListAttributeJson(string instanceName)
@@ -118,7 +120,7 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
/// Builds a config carrying BOTH a static List attribute (whose JSON-array default
/// the Instance Actor decodes into a typed <c>List&lt;int&gt;</c>) and a static scalar
/// attribute. Used to drive a routed <see cref="RouteToGetAttributesRequest"/> that
/// exercises #162: the List value must be normalized for cross-process transport,
/// exercises list normalization: the List value must be normalized for cross-process transport,
/// while the scalar must pass through the normalizer unchanged.
/// </summary>
private static string MakeConfigWithListAndScalarAttributesJson(string instanceName)
@@ -161,6 +163,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
return JsonSerializer.Serialize(config);
}
/// <summary>Verifies that the deployment manager creates instance actors from the stored configurations.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DeploymentManager_CreatesInstanceActors_FromStoredConfigs()
{
@@ -182,6 +186,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Equal("Pump1", response.InstanceUniqueName);
}
/// <summary>Verifies that the deployment manager skips disabled instances on startup.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DeploymentManager_SkipsDisabledInstances_OnStartup()
{
@@ -200,6 +206,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.True(response.Success);
}
/// <summary>Verifies that instance actors are created in staggered batches.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DeploymentManager_StaggeredBatchCreation()
{
@@ -226,6 +234,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
}
}
/// <summary>Verifies that a deploy creates a new instance.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DeploymentManager_Deploy_CreatesNewInstance()
{
@@ -251,6 +261,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Scripts = [new ResolvedScript { CanonicalName = "S1", Code = "this is not C# ~~~" }]
});
/// <summary>Verifies that a deploy with a non-compiling script reports failure and creates no instance actor.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Deploy_WithNonCompilingScript_ReportsFailed_AndCreatesNoInstanceActor()
{
@@ -277,6 +289,7 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
// ── S5: startup deployed-config load is retried on transient failure ──
/// <summary>Verifies that a startup load failure is retried until it succeeds.</summary>
[Fact]
public void StartupLoadFailure_IsRetried_UntilSuccess()
{
@@ -318,8 +331,10 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
}, TimeSpan.FromSeconds(10));
}
// ── M1.6: site event log `deployment` category ─────────────────────────
// ── Site event log `deployment` category ─────────────────────────
/// <summary>Verifies that a successful deploy emits a deployment site event.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DeploymentManager_DeploySuccess_EmitsDeploymentSiteEvent()
{
@@ -345,6 +360,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
}, TimeSpan.FromSeconds(2));
}
/// <summary>Verifies that disable, enable and delete each emit a deployment site event.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DeploymentManager_DisableEnableDelete_EmitDeploymentSiteEvents()
{
@@ -382,6 +399,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
TimeSpan.FromSeconds(2));
}
/// <summary>Verifies that an instance can be disabled, enabled and deleted through its lifecycle.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DeploymentManager_Lifecycle_DisableEnableDelete()
{
@@ -421,8 +440,10 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.DoesNotContain(configs, c => c.InstanceUniqueName == "LifecyclePump");
}
// ── DeploymentManager-006: query-the-site-before-redeploy ──
// ── Query-the-site-before-redeploy ──
/// <summary>Verifies that a state query for a deployed instance returns its applied identity.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DeploymentStateQuery_DeployedInstance_ReturnsAppliedIdentity()
{
@@ -444,6 +465,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Equal("sha256:applied", response.AppliedRevisionHash);
}
/// <summary>Verifies that a state query for an unknown instance reports it as not deployed.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task DeploymentStateQuery_UnknownInstance_ReturnsNotDeployed()
{
@@ -461,6 +484,7 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Null(response.AppliedRevisionHash);
}
/// <summary>Verifies that the supervision strategy resumes a child on an exception.</summary>
[Fact]
public void DeploymentManager_SupervisionStrategy_ResumesOnException()
{
@@ -475,8 +499,10 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Equal(DeploymentStatus.Success, response.Status);
}
// ── Audit Log #23 (ParentExecutionId, Task 4): inbound-API routing ──
// ── ParentExecutionId: inbound-API routing ──
/// <summary>Verifies that an inbound API call carrying a parent execution id is routed to the script successfully.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteInboundApiCall_WithParentExecutionId_RoutesToScriptSuccessfully()
{
@@ -504,6 +530,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Equal(7, Convert.ToInt32(response.ReturnValue));
}
/// <summary>Verifies that an inbound API call without a parent execution id is still routed.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteInboundApiCall_WithoutParentExecutionId_StillRoutes()
{
@@ -530,6 +558,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
// ── Spec §6 (WD-2b): routed RouteToWaitForAttributeRequest → InstanceActor ──
/// <summary>Verifies that a routed wait replies matched when the attribute is already at the target value.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteInboundApiWaitForAttribute_AttributeAlreadyAtTarget_RepliesMatched()
{
@@ -562,10 +592,12 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Equal("Good", response.Quality);
}
/// <summary>Verifies that the require-good-quality flag is passed through to the instance actor.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteInboundApiWaitForAttribute_RequireGoodQuality_IsThreadedToInstanceActor()
{
// #14 (full fidelity): the additive RouteToWaitForAttributeRequest.RequireGoodQuality
// Full fidelity: the additive RouteToWaitForAttributeRequest.RequireGoodQuality
// flag must reach the InstanceActor's wait. A static attribute is Good quality, so a
// quality-gated wait whose target equals the current value still matches — proving the
// flag threads through (and does not spuriously reject a Good value).
@@ -591,6 +623,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Equal("Good", response.Quality);
}
/// <summary>Verifies that a routed wait for an unknown instance replies not found.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteInboundApiWaitForAttribute_UnknownInstance_RepliesNotFound()
{
@@ -612,10 +646,12 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Contains("not found", response.ErrorMessage!, StringComparison.OrdinalIgnoreCase);
}
/// <summary>Verifies that a routed wait matching a list value returns a serializer-safe value.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteInboundApiWaitForAttribute_ListValuedMatch_ReturnsSerializerSafeValue()
{
// WS-4: a routed wait whose matched attribute is a List-typed value comes
// A routed wait whose matched attribute is a List-typed value comes
// back from the Instance Actor as a concrete generic List<int> — a shape the
// cross-process (Newtonsoft) serializer cannot reliably round-trip, which would
// otherwise silently drop the reply and hang the caller's Ask. The handler must
@@ -658,15 +694,17 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
list.Select(e => Convert.ToDouble(e, System.Globalization.CultureInfo.InvariantCulture)));
}
// ── #162: routed RouteToGetAttributesRequest → InstanceActor (List normalization) ──
// ── Routed RouteToGetAttributesRequest → InstanceActor (List normalization) ──
/// <summary>Verifies that a routed get-attributes read returns a serializer-safe list value and leaves scalar values unchanged.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteInboundApiGetAttributes_ListValuedAttribute_ReturnsSerializerSafeValueAndScalarUnchanged()
{
// #162: a routed GetAttributes read of a List-typed static attribute comes back
// A routed GetAttributes read of a List-typed static attribute comes back
// from the Instance Actor as a concrete generic List<int> — the SAME non-primitive
// shape the cross-process (Newtonsoft) serializer cannot reliably round-trip that
// WS-4 fixed for WaitForAttribute. Un-normalized, the reply is silently dropped and
// was already fixed for WaitForAttribute. Un-normalized, the reply is silently dropped and
// the caller's Route.To().GetAttributes() Ask hangs to timeout. The handler must
// project EACH value through NormalizeRoutedReturnValue so the List survives the
// wire — while leaving scalar/string/null values unchanged (no regression).
@@ -714,6 +752,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Null(response.Values["DoesNotExist"]);
}
/// <summary>Verifies that a routed get-attributes read for an unknown instance replies not found.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteInboundApiGetAttributes_UnknownInstance_RepliesNotFound()
{
@@ -734,8 +774,10 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Contains("not found", response.ErrorMessage!, StringComparison.OrdinalIgnoreCase);
}
// ── M2.11: Debug-view routing — unknown-instance not-found signal ──
// ── Debug-view routing — unknown-instance not-found signal ──
/// <summary>Verifies that a debug snapshot request for an unknown instance sets the instance-not-found flag.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteDebugSnapshot_UnknownInstance_SetsInstanceNotFound()
{
@@ -755,6 +797,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Empty(snapshot.AlarmStates);
}
/// <summary>Verifies that a debug view subscribe for an unknown instance sets the instance-not-found flag.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteDebugViewSubscribe_UnknownInstance_SetsInstanceNotFound()
{
@@ -772,6 +816,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Empty(snapshot.AlarmStates);
}
/// <summary>Verifies that a debug snapshot for a known but empty instance does not set the instance-not-found flag.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteDebugSnapshot_KnownButEmptyInstance_DoesNotSetInstanceNotFound()
{
@@ -794,8 +840,10 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
"A deployed (but empty) instance must NOT set InstanceNotFound.");
}
// ── Task 10: notify-and-fetch — RefreshDeploymentCommand → fetch → apply ──
// ── Notify-and-fetch — RefreshDeploymentCommand → fetch → apply ──
/// <summary>Verifies that a refresh whose fetch succeeds applies the configuration and replies success.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RefreshDeployment_FetchSucceeds_AppliesConfigAndRepliesSuccess()
{
@@ -825,6 +873,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Contains(configs, c => c.InstanceUniqueName == "FetchedPump");
}
/// <summary>Verifies that a refresh whose fetch fails replies failed and applies nothing.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RefreshDeployment_FetchFails_RepliesFailedAndDoesNotApply()
{
@@ -852,6 +902,7 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.DoesNotContain(configs, c => c.InstanceUniqueName == "UnfetchedPump");
}
/// <summary>Verifies that a refresh with no fetcher replies failed.</summary>
[Fact]
public void RefreshDeployment_NullFetcher_RepliesFailed()
{
@@ -868,6 +919,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Equal("Pump", response.InstanceUniqueName);
}
/// <summary>Verifies that the refresh reply goes to the original sender across the asynchronous fetch.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RefreshDeployment_ReplyGoesToOriginalSender_AcrossAsyncFetch()
{
@@ -889,13 +942,15 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Equal("SenderPump", response.InstanceUniqueName);
}
// ── LocalDb Phase 2 / Task 12: the active-node central-only purge ──
// ── LocalDb Phase 2: the active-node central-only purge ──
/// <summary>Verifies that applying artifacts purges the central-only notification configuration.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ApplyingArtifacts_PurgesCentralOnlyNotificationConfig()
{
// Security cleanup. notification_lists and smtp_configurations can hold plaintext
// SMTP passwords written by a pre-2026-07-10 build, and the ACTIVE node's artifact
// SMTP passwords written by a build older than 2026-07-10, and the ACTIVE node's artifact
// apply is what clears them (DeploymentManagerActor.HandleDeployArtifacts). The
// standby used to hold a second copy of this call in SiteReplicationActor; LocalDb
// Phase 2 deleted that actor, so this is now the ONLY call site that keeps the
@@ -1004,6 +1059,7 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
/// policy was dropped on the floor here and every cached call fell back to the engine's
/// 50 x 30 s default.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ApplyingArtifacts_PersistsExternalSystemRetryPolicy()
{
@@ -1026,6 +1082,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Equal(45_000, reader.GetInt64(1));
}
/// <summary>Verifies that applying artifacts deletes external systems that are absent from the set.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ApplyingArtifacts_DeletesExternalSystemsAbsentFromTheSet()
{
@@ -1049,6 +1107,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Equal(1, await RowCountAsync("external_systems"));
}
/// <summary>Verifies that applying artifacts with a null set touches nothing.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ApplyingArtifacts_NullSet_TouchesNothing()
{
@@ -1067,6 +1127,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.Equal(1, await RowCountAsync("external_systems"));
}
/// <summary>Verifies that a removed shared script is unregistered from the library.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ApplyingArtifacts_RemovedSharedScript_IsUnregisteredFromLibrary()
{
@@ -1093,6 +1155,8 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
Assert.False(_sharedScriptLibrary.Contains("GoneScript"));
}
/// <summary>Verifies that a removed data connection stops its live connection in the data connection layer.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task ApplyingArtifacts_RemovedDataConnection_StopsLiveDclConnection()
{
@@ -1134,13 +1198,26 @@ public class DeploymentManagerActorTests : TestKit, IDisposable
private readonly string? _result;
private readonly Exception? _error;
/// <summary>Initializes the fetcher to return the given configuration JSON.</summary>
/// <param name="result">The configuration JSON returned from every fetch.</param>
public FakeConfigFetcher(string result) => _result = result;
/// <summary>Initializes the fetcher to throw the given exception.</summary>
/// <param name="error">The exception thrown from every fetch.</param>
public FakeConfigFetcher(Exception error) => _error = error;
/// <summary>Gets the central base URL passed to the most recent fetch.</summary>
public string? LastBaseUrl { get; private set; }
/// <summary>Gets the deployment id passed to the most recent fetch.</summary>
public string? LastDeploymentId { get; private set; }
/// <summary>Gets the token passed to the most recent fetch.</summary>
public string? LastToken { get; private set; }
/// <summary>Records the request arguments and returns the canned JSON or throws the canned exception.</summary>
/// <param name="centralFetchBaseUrl">The central base URL being fetched from.</param>
/// <param name="deploymentId">The deployment id being fetched.</param>
/// <param name="token">The deployment token.</param>
/// <param name="ct">The cancellation token.</param>
/// <returns>A task yielding the canned configuration JSON.</returns>
public async Task<string> FetchAsync(
string centralFetchBaseUrl, string deploymentId, string token, CancellationToken ct)
{