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
@@ -8,11 +8,11 @@ using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit;
namespace ZB.MOM.WW.ScadaBridge.InboundAPI.Tests;
/// <summary>
/// WP-4: Tests for <see cref="RouteHelper"/>/<see cref="RouteTarget"/> — the
/// Tests for <see cref="RouteHelper"/>/<see cref="RouteTarget"/> — the
/// cross-site Route.To() routing surface inbound API scripts use.
///
/// InboundAPI-017: this surface previously had zero coverage.
/// InboundAPI-016: routed calls must inherit the executing method's deadline token.
/// This surface previously had zero coverage.
/// Routed calls must inherit the executing method's deadline token.
/// </summary>
public class RouteHelperTests
{
@@ -27,6 +27,8 @@ public class RouteHelperTests
// --- Call ---
/// <summary>Verifies that a routed call resolves the site and returns the value.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_HappyPath_ResolvesSiteAndReturnsValue()
{
@@ -40,6 +42,8 @@ public class RouteHelperTests
Assert.Equal(99, result);
}
/// <summary>Verifies that a routed call generates a correlation id.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_GeneratesCorrelationId()
{
@@ -55,6 +59,8 @@ public class RouteHelperTests
Assert.True(Guid.TryParse(captured!.CorrelationId, out _));
}
/// <summary>Verifies that a remote failure on a routed call throws an invalid-operation exception.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_RemoteFailure_ThrowsInvalidOperationException()
{
@@ -68,6 +74,8 @@ public class RouteHelperTests
Assert.Equal("site exploded", ex.Message);
}
/// <summary>Verifies that an unresolved instance throws an invalid-operation exception.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_UnresolvedInstance_ThrowsInvalidOperationException()
{
@@ -82,6 +90,8 @@ public class RouteHelperTests
// --- GetAttribute(s) ---
/// <summary>Verifies that getting attributes returns the values.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetAttributes_HappyPath_ReturnsValues()
{
@@ -98,6 +108,8 @@ public class RouteHelperTests
Assert.Equal(2, result["b"]);
}
/// <summary>Verifies that getting a single attribute delegates to the batch call and returns one value.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetAttribute_DelegatesToBatch_AndReturnsSingleValue()
{
@@ -113,6 +125,8 @@ public class RouteHelperTests
Assert.Equal(21.5, value);
}
/// <summary>Verifies that getting an absent attribute key returns null.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetAttribute_AbsentKey_ReturnsNull()
{
@@ -128,6 +142,8 @@ public class RouteHelperTests
Assert.Null(value);
}
/// <summary>Verifies that a remote failure when getting attributes throws an invalid-operation exception.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetAttributes_RemoteFailure_ThrowsInvalidOperationException()
{
@@ -144,6 +160,8 @@ public class RouteHelperTests
// --- WaitForAttribute (spec §6) ---
/// <summary>Verifies that waiting for an attribute returns true when the value matches.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WaitForAttribute_Matched_ReturnsTrue()
{
@@ -160,6 +178,8 @@ public class RouteHelperTests
Assert.True(matched);
}
/// <summary>Verifies that waiting for an attribute returns false when the wait times out.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WaitForAttribute_TimedOut_ReturnsFalse()
{
@@ -176,6 +196,8 @@ public class RouteHelperTests
Assert.False(matched);
}
/// <summary>Verifies that a routing failure while waiting for an attribute throws an invalid-operation exception.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WaitForAttribute_RoutingFailure_ThrowsInvalidOperationException()
{
@@ -193,6 +215,8 @@ public class RouteHelperTests
Assert.Equal("instance not found", ex.Message);
}
/// <summary>Verifies that waiting for an attribute encodes the target value on the request.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WaitForAttribute_EncodesTargetValue_OnRequest()
{
@@ -215,10 +239,12 @@ public class RouteHelperTests
Assert.True(Guid.TryParse(captured.CorrelationId, out _));
}
/// <summary>Verifies that the wait timeout, not the method deadline, governs a wait for an attribute.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WaitForAttribute_IsNotBoundByMethodDeadline_WaitTimeoutGoverns()
{
// InboundAPI-029 (spec §6): unlike Call/GetAttributes/SetAttributes, the wait is
// Spec §6: unlike Call/GetAttributes/SetAttributes, the wait is
// bounded by its OWN timeout, not the method deadline. Even with the method
// deadline ALREADY cancelled, the wait still proceeds and returns the site's
// wait-timeout result — the deadline does not cut it short.
@@ -240,6 +266,8 @@ public class RouteHelperTests
Assert.NotEqual(deadline.Token, seen); // it is a per-wait token, not the method deadline
}
/// <summary>Verifies that an explicit cancellation token is honored when waiting for an attribute.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WaitForAttribute_ExplicitToken_IsHonoured()
{
@@ -260,6 +288,8 @@ public class RouteHelperTests
Assert.True(seen.IsCancellationRequested); // the explicit caller token cancels the wait
}
/// <summary>Verifies that a client disconnect cancels a wait for an attribute.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WaitForAttribute_ClientDisconnect_CancelsTheWait()
{
@@ -281,13 +311,15 @@ public class RouteHelperTests
Assert.True(seen.IsCancellationRequested); // the client-abort token cancels the wait
}
/// <summary>Verifies that a slow timed-out response is not preempted by a local backstop timeout.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WaitForAttribute_SlowTimedOutResponse_NotPreemptedByLocalBackstop()
{
// InboundAPI-031: WaitForAttribute must NOT impose a local wait-timeout backstop.
// WaitForAttribute must NOT impose a local wait-timeout backstop.
// The site enforces the wait timeout and returns Matched=false; the round trip is
// bounded by CommunicationService's Ask (timeout + IntegrationTimeout). A local CTS
// of `timeout + small grace` (the prior InboundAPI-029 approach) was TIGHTER than
// of `timeout + small grace` (the prior approach) was TIGHTER than
// that round-trip budget, so a slow-but-valid timed-out response would be cancelled
// into an exception (a 500) instead of the spec §6 `false`. With the backstop
// removed, a response arriving well after the (tiny) wait timeout still returns a
@@ -316,6 +348,8 @@ public class RouteHelperTests
Assert.False(seen.IsCancellationRequested); // no local wait-timeout backstop fired
}
/// <summary>Verifies that waiting for an attribute carries the parent execution id on the request.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WaitForAttribute_WithParentExecutionId_CarriesItOnRequest()
{
@@ -337,6 +371,8 @@ public class RouteHelperTests
// --- SetAttribute(s) ---
/// <summary>Verifies that setting a single attribute delegates to the batch call with one entry.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task SetAttribute_DelegatesToBatch_WithSingleEntry()
{
@@ -353,6 +389,8 @@ public class RouteHelperTests
Assert.Single(captured.AttributeValues);
}
/// <summary>Verifies that a remote failure when setting attributes throws an invalid-operation exception.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task SetAttributes_RemoteFailure_ThrowsInvalidOperationException()
{
@@ -367,8 +405,10 @@ public class RouteHelperTests
Assert.Equal("write rejected", ex.Message);
}
// --- InboundAPI-016: routed calls inherit the method deadline token ---
// --- Routed calls inherit the method deadline token ---
/// <summary>Verifies that a routed call without an explicit token inherits the method deadline token.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_WithNoExplicitToken_InheritsMethodDeadlineToken()
{
@@ -388,6 +428,8 @@ public class RouteHelperTests
Assert.Equal(deadline.Token, seen);
}
/// <summary>Verifies that a routed call observes cancellation when the method deadline is cancelled.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_WhenMethodDeadlineCancelled_RoutedCallObservesCancellation()
{
@@ -411,6 +453,8 @@ public class RouteHelperTests
() => bound.To("inst-1").Call("doWork"));
}
/// <summary>Verifies that an explicit token overrides the deadline token on a routed call.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_ExplicitToken_OverridesDeadlineToken()
{
@@ -429,9 +473,11 @@ public class RouteHelperTests
Assert.Equal(explicitCts.Token, seen);
}
// --- Audit Log #23 (ParentExecutionId, T3): a routed call carries the
// --- ParentExecutionId: a routed call carries the
// inbound request's ExecutionId as RouteToCallRequest.ParentExecutionId ---
/// <summary>Verifies that a routed call without a parent execution id leaves it null on the request.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_WithoutParentExecutionId_LeavesParentExecutionIdNull()
{
@@ -449,6 +495,8 @@ public class RouteHelperTests
Assert.Null(captured!.ParentExecutionId);
}
/// <summary>Verifies that a routed call carries the parent execution id on the route-to-call request.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_WithParentExecutionId_CarriesItOnRouteToCallRequest()
{
@@ -472,6 +520,8 @@ public class RouteHelperTests
Assert.True(Guid.TryParse(captured.CorrelationId, out _));
}
/// <summary>Verifies that setting the parent execution id preserves the deadline token.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WithParentExecutionId_PreservesDeadlineToken()
{
@@ -494,6 +544,8 @@ public class RouteHelperTests
Assert.NotNull(captured!.ParentExecutionId);
}
/// <summary>Verifies that getting attributes without an explicit token inherits the method deadline token.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetAttributes_WithNoExplicitToken_InheritsMethodDeadlineToken()
{
@@ -511,6 +563,8 @@ public class RouteHelperTests
Assert.Equal(deadline.Token, seen);
}
/// <summary>Verifies that setting attributes without an explicit token inherits the method deadline token.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task SetAttributes_WithNoExplicitToken_InheritsMethodDeadlineToken()
{
@@ -527,8 +581,10 @@ public class RouteHelperTests
Assert.Equal(deadline.Token, seen);
}
// --- InboundAPI-021: ParentExecutionId flows through Get/SetAttributes too ---
// --- ParentExecutionId flows through Get/SetAttributes too ---
/// <summary>Verifies that getting attributes without a parent execution id leaves it null on the request.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetAttributes_WithoutParentExecutionId_LeavesParentExecutionIdNull()
{
@@ -545,6 +601,8 @@ public class RouteHelperTests
Assert.Null(captured!.ParentExecutionId);
}
/// <summary>Verifies that getting attributes carries the parent execution id on the route-to-get-attributes request.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetAttributes_WithParentExecutionId_CarriesItOnRouteToGetAttributesRequest()
{
@@ -566,6 +624,8 @@ public class RouteHelperTests
Assert.Equal(inboundExecutionId, captured!.ParentExecutionId);
}
/// <summary>Verifies that setting attributes without a parent execution id leaves it null on the request.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task SetAttributes_WithoutParentExecutionId_LeavesParentExecutionIdNull()
{
@@ -581,6 +641,8 @@ public class RouteHelperTests
Assert.Null(captured!.ParentExecutionId);
}
/// <summary>Verifies that setting attributes carries the parent execution id on the route-to-set-attributes request.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task SetAttributes_WithParentExecutionId_CarriesItOnRouteToSetAttributesRequest()
{
@@ -600,6 +662,8 @@ public class RouteHelperTests
// --- N3: typed unreachability at the Ask boundary ---
/// <summary>Verifies that an ask timeout on a routed call throws a site-unreachable exception.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_AskTimeout_ThrowsSiteUnreachableException()
{
@@ -612,6 +676,8 @@ public class RouteHelperTests
() => CreateHelper().To("inst").Call("s"));
}
/// <summary>Verifies that an ask timeout when getting attributes throws a site-unreachable exception.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task GetAttributes_AskTimeout_ThrowsSiteUnreachableException()
{
@@ -632,6 +698,8 @@ public class RouteHelperTests
private static IReadOnlySet<string> Scope(params string[] siteIdentifiers) =>
new HashSet<string>(siteIdentifiers, StringComparer.OrdinalIgnoreCase);
/// <summary>Verifies that a routed call outside the permitted site scope throws before any routing happens.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_OutsideSiteScope_ThrowsRouteSiteScopeException_BeforeRouting()
{
@@ -647,6 +715,8 @@ public class RouteHelperTests
await _router.DidNotReceiveWithAnyArgs().RouteToCallAsync(default!, default!, default);
}
/// <summary>Verifies that a routed call inside the permitted site scope is routed.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_InsideSiteScope_Routes()
{
@@ -660,6 +730,8 @@ public class RouteHelperTests
Assert.Equal(42, await helper.To("inst-1").Call("doWork"));
}
/// <summary>Verifies that a null site scope leaves routed calls unscoped.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task Call_NullScope_IsUnscoped()
{
@@ -673,6 +745,8 @@ public class RouteHelperTests
Assert.Equal(42, await helper.To("inst-1").Call("doWork"));
}
/// <summary>Verifies that setting attributes outside the permitted site scope throws before any routing happens.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task SetAttributes_OutsideSiteScope_ThrowsRouteSiteScopeException_BeforeRouting()
{
@@ -687,6 +761,8 @@ public class RouteHelperTests
await _router.DidNotReceiveWithAnyArgs().RouteToSetAttributesAsync(default!, default!, default);
}
/// <summary>Verifies that the site scope survives the other With-style copies.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WithSiteScope_SurvivesTheOtherWithCopies()
{
@@ -708,6 +784,8 @@ public class RouteHelperTests
// --- Arch-review F11: WithBodyCapture ---
/// <summary>Verifies that the route-call audit row has no request or response summary when body capture is off.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteCallRow_WithBodyCaptureOff_HasNoRequestOrResponseSummary()
{
@@ -730,6 +808,8 @@ public class RouteHelperTests
Assert.Null(row.ResponseSummary);
}
/// <summary>Verifies that the route-call audit row has request and response summaries when body capture is on by default.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task RouteCallRow_WithBodyCaptureOn_ByDefault_HasRequestAndResponseSummary()
{
@@ -751,10 +831,12 @@ public class RouteHelperTests
Assert.Equal("99", row.ResponseSummary);
}
/// <summary>Verifies that the body-capture flag survives the other With-style copies.</summary>
/// <returns>A task that represents the asynchronous operation.</returns>
[Fact]
public async Task WithBodyCapture_SurvivesTheOtherWithCopies()
{
// Mirrors WithSiteScope_SurvivesTheOtherWithCopies (Task 3): the flag must not be
// Mirrors WithSiteScope_SurvivesTheOtherWithCopies: the flag must not be
// dropped by the copies InboundScriptExecutor makes (WithDeadline /
// WithRequestAborted / WithParentExecutionId / WithTrace / WithSiteScope).
SiteResolves("inst-1", "SiteA");