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
@@ -28,6 +28,7 @@ public class InstanceActorTests : TestKit, IDisposable
private readonly SiteRuntimeOptions _options;
private readonly TestLocalDb _localDb;
/// <summary>Initializes the test class with an in-memory site storage and the shared actor dependencies.</summary>
public InstanceActorTests()
{
_localDb = TestLocalDb.CreateTemp("instance-actor-test");
@@ -55,6 +56,7 @@ public class InstanceActorTests : TestKit, IDisposable
NullLogger<InstanceActor>.Instance)));
}
/// <inheritdoc />
void IDisposable.Dispose()
{
// TestKit teardown first, so no in-flight actor can reach a disposed ILocalDb;
@@ -65,8 +67,9 @@ public class InstanceActorTests : TestKit, IDisposable
TestLocalDb.DeleteFiles(path);
}
// ── M1.6: site event log `instance_lifecycle` category ──────────────────
// ── Site event log `instance_lifecycle` category ──────────────────
/// <summary>Verifies that stopping the actor releases its tag subscription under its owner identity.</summary>
[Fact]
public void Stop_ReleasesTagSubscriptionWithOwnerIdentity()
{
@@ -78,6 +81,7 @@ public class InstanceActorTests : TestKit, IDisposable
Assert.Equal(instance, dcl.LastSender);
}
/// <summary>Verifies that starting an instance actor emits an instance lifecycle site event.</summary>
[Fact]
public void InstanceActor_Start_EmitsInstanceLifecycleSiteEvent()
{
@@ -112,6 +116,7 @@ public class InstanceActorTests : TestKit, IDisposable
}, TimeSpan.FromSeconds(2));
}
/// <summary>Verifies that stopping an instance actor emits an instance lifecycle site event.</summary>
[Fact]
public void InstanceActor_Stop_EmitsInstanceLifecycleSiteEvent()
{
@@ -152,6 +157,7 @@ public class InstanceActorTests : TestKit, IDisposable
}, TimeSpan.FromSeconds(2));
}
/// <summary>Verifies that the instance actor loads its attributes from the configuration.</summary>
[Fact]
public void InstanceActor_LoadsAttributesFromConfig()
{
@@ -177,6 +183,7 @@ public class InstanceActorTests : TestKit, IDisposable
Assert.Equal("corr-1", response.CorrelationId);
}
/// <summary>Verifies that getting an unknown attribute reports not found.</summary>
[Fact]
public void InstanceActor_GetAttribute_NotFound_ReturnsFalse()
{
@@ -196,6 +203,7 @@ public class InstanceActorTests : TestKit, IDisposable
Assert.Null(response.Value);
}
/// <summary>Verifies that setting a static attribute updates it in memory.</summary>
[Fact]
public void InstanceActor_SetStaticAttribute_UpdatesInMemory()
{
@@ -225,6 +233,8 @@ public class InstanceActorTests : TestKit, IDisposable
Assert.Equal("100.0", getResponse.Value?.ToString());
}
/// <summary>Verifies that setting a static attribute persists it to SQLite.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InstanceActor_SetStaticAttribute_PersistsToSQLite()
{
@@ -254,7 +264,7 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// Perf remediation (arch-review WP1.5): a burst of rapid static-attribute writes must
/// Perf remediation: a burst of rapid static-attribute writes must
/// coalesce into ONE batched SQLite transaction on a short single-shot timer — mirroring
/// NativeAlarmActor's MarkDirtyUpsert/FlushDirtyUpserts (P4) shape — rather than a write
/// per <see cref="SetStaticAttributeCommand"/>. Pinned two ways: (1) nothing is persisted
@@ -262,6 +272,7 @@ public class InstanceActorTests : TestKit, IDisposable
/// synchronously and updated in-memory state; (2) only the LATEST value per attribute
/// survives, across writes to two different attributes coalesced into the same flush.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InstanceActor_RapidStaticWrites_CoalesceIntoSingleFlush()
{
@@ -324,6 +335,8 @@ public class InstanceActorTests : TestKit, IDisposable
Assert.Equal("Running", afterFlush["Label"]);
}
/// <summary>Verifies that static overrides are loaded from SQLite.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InstanceActor_LoadsStaticOverridesFromSQLite()
{
@@ -353,6 +366,8 @@ public class InstanceActorTests : TestKit, IDisposable
Assert.Equal("200.0", response.Value?.ToString());
}
/// <summary>Verifies that a static override is reset on redeployment.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task StaticOverride_ResetOnRedeployment()
{
@@ -364,7 +379,7 @@ public class InstanceActorTests : TestKit, IDisposable
Assert.Single(overrides);
// Clear overrides BEFORE the successor exists — the ordering DeploymentManager now
// guarantees (arch-review 2026-08-19 P1-2). It used to clear inside the deploy's
// guarantees. It used to clear inside the deploy's
// persistence task, i.e. after creating the actor, so this "simulation" pinned an
// ordering the production path did not have; the end-to-end contract lives in
// RedeployStaticOverrideResetTests.
@@ -394,6 +409,7 @@ public class InstanceActorTests : TestKit, IDisposable
Assert.Equal("98.6", response.Value?.ToString());
}
/// <summary>Verifies that a data-sourced attribute starts with uncertain quality.</summary>
[Fact]
public void InstanceActor_DataSourcedAttribute_StartsWithUncertainQuality()
{
@@ -424,7 +440,7 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// SiteRuntime-019: the disable/enable lifecycle is owned entirely by the
/// The disable/enable lifecycle is owned entirely by the
/// Deployment Manager (it stops / re-creates the Instance Actor itself and
/// replies to the caller). The Instance Actor must NOT handle
/// <see cref="DisableInstanceCommand"/> / <see cref="EnableInstanceCommand"/>
@@ -450,6 +466,7 @@ public class InstanceActorTests : TestKit, IDisposable
ExpectNoMsg(TimeSpan.FromMilliseconds(500));
}
/// <summary>Verifies that a static attribute starts with good quality.</summary>
[Fact]
public void InstanceActor_StaticAttribute_StartsWithGoodQuality()
{
@@ -537,7 +554,7 @@ public class InstanceActorTests : TestKit, IDisposable
}
}
// ── MV-8: data-sourced List attribute coercion ─────────────────────────
// ── Data-sourced List attribute coercion ─────────────────────────
private IActorRef CreateInstanceActorWithDcl(string instanceName, FlattenedConfiguration config, TestProbe dcl)
{
@@ -558,7 +575,7 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// MV-8: when a data-sourced attribute is declared <c>DataType.List</c>, an
/// When a data-sourced attribute is declared <c>DataType.List</c>, an
/// incoming OPC UA array value (a CLR array surfaces from the SDK) must be
/// coerced into a typed <c>List&lt;int&gt;</c> whose elements match the
/// attribute's ElementDataType. The stored value must be a real list — not a
@@ -598,7 +615,7 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// MV-8: array elements coming in as a different CLR type (here, strings that
/// Array elements coming in as a different CLR type (here, strings that
/// are valid integers) must still coerce to the declared element type.
/// </summary>
[Fact]
@@ -635,7 +652,7 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// MV-8: an element that cannot be coerced to the declared element type must
/// An element that cannot be coerced to the declared element type must
/// set the attribute quality to <c>Bad</c> and must NOT crash the actor (it
/// stays alive and continues to answer queries).
/// </summary>
@@ -675,7 +692,7 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// MV-8 design contract: a failed coercion keeps the PRIOR value. A good
/// Design contract: a failed coercion keeps the PRIOR value. A good
/// array is delivered first and stored as a typed list; a subsequent array
/// with a non-coercible element must NOT overwrite that value — the stored
/// value stays the prior list while the quality flips to <c>Bad</c>.
@@ -718,7 +735,7 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// MV-8 guard: scalar (non-List) data-sourced attributes keep the existing
/// Guard: scalar (non-List) data-sourced attributes keep the existing
/// pass-through behaviour — a scalar value is stored unchanged.
/// </summary>
[Fact]
@@ -846,10 +863,10 @@ public class InstanceActorTests : TestKit, IDisposable
ExpectNoMsg(within);
}
// ── MV-7: static (authored) List attribute decode ──────────────────────
// ── Static (authored) List attribute decode ──────────────────────
/// <summary>
/// MV-7: a STATIC List attribute carries its default as the canonical JSON
/// A STATIC List attribute carries its default as the canonical JSON
/// array string. On load the actor must decode it to a typed list so a
/// script reading the attribute receives a real collection, not the raw
/// JSON string.
@@ -882,11 +899,12 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// MV-7: a SetStaticAttribute write on a List attribute decodes the canonical
/// A SetStaticAttribute write on a List attribute decodes the canonical
/// JSON value into a typed list for in-memory reads, but the PERSISTED form
/// (SQLite static override) must remain the canonical JSON string — never a
/// CLR-list .ToString().
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InstanceActor_SetStaticListAttribute_ReadsTypedList_PersistsJsonString()
{
@@ -925,10 +943,11 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// MV-7: a persisted static override for a List attribute is a canonical JSON
/// A persisted static override for a List attribute is a canonical JSON
/// string in SQLite; on load it must be decoded to a typed list, the same as
/// the config default.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InstanceActor_StaticListOverride_LoadsAsTypedList()
{
@@ -961,7 +980,7 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// MV-7: a malformed stored List value must NOT crash the actor — it loads
/// A malformed stored List value must NOT crash the actor — it loads
/// with quality Bad and the actor stays alive and answering.
/// </summary>
[Fact]
@@ -995,7 +1014,7 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// MV-7 guard: a scalar static attribute is unaffected by the List decode
/// Guard: a scalar static attribute is unaffected by the List decode
/// path — it still returns its raw string value.
/// </summary>
[Fact]
@@ -1021,13 +1040,14 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// MV-7 (review fix): a SetStaticAttribute write whose value fails to decode as
/// A SetStaticAttribute write whose value fails to decode as
/// a list (e.g. truncated JSON) on a List attribute must be REJECTED — reply
/// Success=false with a clear error and persist NOTHING. The script path always
/// pre-encodes valid JSON, but the Inbound API / direct-command path can submit
/// an arbitrary value, so a malformed value must not silently null the in-memory
/// value, publish "Good" quality, and durably persist a poison override.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InstanceActor_SetStaticListAttribute_Malformed_Rejected_NotPersisted()
{
@@ -1067,11 +1087,12 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// MV-7 (review fix): an empty-list value "[]" decodes to a non-null empty list
/// An empty-list value "[]" decodes to a non-null empty list
/// and must be accepted (NOT mistaken for a malformed value, which also decodes
/// to null). This pins the boundary between the "clearing/empty" and "poison"
/// cases that both surface as a null decode result.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InstanceActor_SetStaticListAttribute_EmptyList_Accepted()
{
@@ -1108,14 +1129,15 @@ public class InstanceActorTests : TestKit, IDisposable
Assert.Equal("[]", overrides["Labels"]);
}
// ── NJ-4: old-form List static override normalization on load ────────────
// ── Old-form List static override normalization on load ────────────
/// <summary>
/// NJ-4: an OLD array-of-strings static override (<c>["10","20"]</c>) for an
/// An OLD array-of-strings static override (<c>["10","20"]</c>) for an
/// Int32 List attribute must be re-persisted in the native form (<c>[10,20]</c>)
/// when the actor loads it at startup. The in-memory read still returns the
/// typed list {10,20}; the on-disk value is normalized to native JSON.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InstanceActor_OldFormListOverride_NormalizedToNativeOnLoad()
{
@@ -1153,10 +1175,11 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// NJ-4: a NATIVE-form static override (<c>[10,20]</c>) is already canonical, so
/// A NATIVE-form static override (<c>[10,20]</c>) is already canonical, so
/// load-time normalization must be a no-op — the on-disk value is unchanged
/// (idempotent: native → native is byte-identical, so no re-persist occurs).
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InstanceActor_NativeFormListOverride_NotRePersistedOnLoad()
{
@@ -1191,9 +1214,10 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// NJ-4: a scalar static override is unaffected by the List normalization path —
/// A scalar static override is unaffected by the List normalization path —
/// its on-disk value is left exactly as stored (no native re-encode).
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InstanceActor_ScalarOverride_NotTouchedByListNormalization()
{
@@ -1222,10 +1246,11 @@ public class InstanceActorTests : TestKit, IDisposable
}
/// <summary>
/// NJ-4: a malformed stored List override (truncated JSON) must NOT crash the
/// A malformed stored List override (truncated JSON) must NOT crash the
/// actor and must NOT be re-persisted — it loads with Bad quality (as today),
/// the actor stays alive, and the poison on-disk value is left unchanged.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task InstanceActor_MalformedListOverride_BadQuality_NotRePersisted()
{
@@ -1298,6 +1323,7 @@ public class InstanceActorTests : TestKit, IDisposable
return (actor, dcl);
}
/// <summary>Verifies that a failed subscribe response is retried.</summary>
[Fact]
public void FailedSubscribeResponse_IsRetried()
{
@@ -1313,6 +1339,7 @@ public class InstanceActorTests : TestKit, IDisposable
Assert.Equal(first.TagPaths, retry.TagPaths);
}
/// <summary>Verifies that a lost subscribe response is retried and a success stops the retrying.</summary>
[Fact]
public void LostSubscribeResponse_IsRetried_AndSuccessStopsRetrying()
{
@@ -1331,6 +1358,7 @@ public class InstanceActorTests : TestKit, IDisposable
// --- Lever 1 (2026-08-28): in-flight guard ---
/// <summary>Verifies that a slow subscribe does not stack duplicate requests while one is in flight.</summary>
[Fact]
public void SlowSubscribe_DoesNotStackDuplicates_WhileInFlight()
{
@@ -1344,10 +1372,11 @@ public class InstanceActorTests : TestKit, IDisposable
var (_, dclProbe) = CreateInstanceWithDataSourcedAttribute(options);
dclProbe.ExpectMsg<SubscribeTagsRequest>();
// Pre-Lever-1 this window would carry ~4 more requests (one per 200 ms tick).
// Before the in-flight guard this window would carry ~4 more requests (one per 200 ms tick).
dclProbe.ExpectNoMsg(TimeSpan.FromMilliseconds(1000));
}
/// <summary>Verifies that a slow subscribe is re-issued once after the in-flight ceiling.</summary>
[Fact]
public void SlowSubscribe_ReissuesAfterInFlightCeiling_AndOnlyOnce()
{
@@ -1367,6 +1396,7 @@ public class InstanceActorTests : TestKit, IDisposable
dclProbe.ExpectNoMsg(TimeSpan.FromMilliseconds(400));
}
/// <summary>Verifies that a reply to a superseded request is ignored and the latest request still governs.</summary>
[Fact]
public void ReplyToSupersededRequest_IsIgnored_AndLatestStillGoverns()
{
@@ -1396,6 +1426,7 @@ public class InstanceActorTests : TestKit, IDisposable
// --- Lever 1 (2026-08-28): backoff on failure, reset on success ---
/// <summary>Verifies that repeated failures back off and a success resets the interval to its floor.</summary>
[Fact]
public void RepeatedFailures_BackOff_AndSuccessResetsToFloor()
{
@@ -1431,6 +1462,7 @@ public class InstanceActorTests : TestKit, IDisposable
dclProbe.ExpectNoMsg(TimeSpan.FromMilliseconds(1200));
}
/// <summary>Verifies that a failure reply re-issues the request even though the in-flight guard has not expired.</summary>
[Fact]
public void FailureReply_ReissuesEvenThoughGuardHasNotExpired()
{
@@ -1453,6 +1485,7 @@ public class InstanceActorTests : TestKit, IDisposable
// --- Lever 1 (2026-08-28): Good quality resets the backoff ---
/// <summary>Verifies that a flapping Good quality does not defer the retry.</summary>
[Fact]
public void FlappingGood_DoesNotDeferTheRetry()
{
@@ -1489,6 +1522,7 @@ public class InstanceActorTests : TestKit, IDisposable
dclProbe.ExpectMsg<SubscribeTagsRequest>(TimeSpan.FromMilliseconds(50));
}
/// <summary>Verifies that the connection returning to Good resets the backoff and retries promptly.</summary>
[Fact]
public void ConnectionBackToGood_ResetsBackoff_AndRetriesPromptly()
{
@@ -1518,6 +1552,7 @@ public class InstanceActorTests : TestKit, IDisposable
Assert.True(sw.Elapsed < TimeSpan.FromMilliseconds(1000), $"retry took {sw.Elapsed} — backoff not reset");
}
/// <summary>Verifies that a late reply for a failed and re-issued request is ignored.</summary>
[Fact]
public void LateReplyForFailedAndReissuedRequest_IsIgnored()
{