fix(core): resolve Low code-review findings (Core-004,008,009,010,011,012)

- Core-004: add ConfigureAwait(false) to DriverHost.RegisterAsync /
  UnregisterAsync / DisposeAsync.
- Core-008: rewrite the BuildAddressSpaceAsync XML doc to correctly name
  the caller (OpcUaApplicationHost.PopulateAddressSpaces) that owns the
  per-driver isolation.
- Core-009: snapshot DriverResilienceOptions once per non-idempotent write
  in CapabilityInvoker.ExecuteWriteAsync.
- Core-010: switch DriverResilienceOptions.Resolve to TryGetValue with a
  diagnostic error message when a tier table is missing a capability.
- Core-011: add an optional diagnostic callback to PermissionTrieBuilder
  so production callers can surface scope-path mismatches.
- Core-012: correct the stale WedgeDetector ctor summary and add the
  Reconnecting row to DriverHealthReport's state matrix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-05-23 05:38:09 -04:00
parent ff2e75ab98
commit 8be6afbda4
15 changed files with 656 additions and 28 deletions

View File

@@ -67,4 +67,53 @@ public sealed class DriverHealthReportTests
{
DriverHealthReport.HttpStatus(verdict).ShouldBe(expected);
}
/// <summary>
/// Core-012 regression: <see cref="DriverState.Reconnecting"/> must aggregate to
/// <see cref="ReadinessVerdict.Degraded"/> — the doc remarks state matrix lists this
/// mapping (after the Core-012 doc fix that added the Reconnecting row).
/// </summary>
[Fact]
public void Any_Reconnecting_WithoutFaultedOrNotReady_IsDegraded()
{
var verdict = DriverHealthReport.Aggregate([
new DriverHealthSnapshot("a", DriverState.Healthy),
new DriverHealthSnapshot("b", DriverState.Reconnecting),
]);
verdict.ShouldBe(ReadinessVerdict.Degraded,
"Reconnecting = driver alive but not serving live data → /readyz stays 200 while operators see the affected driver in the body");
}
/// <summary>
/// Core-012 regression: assert the XML <c>&lt;remarks&gt;</c> on
/// <see cref="DriverHealthReport"/> names <see cref="DriverState.Reconnecting"/> in its
/// state matrix. Catches a future doc-drift if someone re-aliases Reconnecting without
/// updating the matrix.
/// </summary>
[Fact]
public void Doc_State_Matrix_Includes_Reconnecting()
{
var xmlPath = Path.Combine(
AppContext.BaseDirectory,
"ZB.MOM.WW.OtOpcUa.Core.xml");
File.Exists(xmlPath).ShouldBeTrue($"expected XML doc file at {xmlPath}");
var content = File.ReadAllText(xmlPath);
var driverHealthReportRemarks = ExtractRemarksFor(content, "T:ZB.MOM.WW.OtOpcUa.Core.Observability.DriverHealthReport");
driverHealthReportRemarks.ShouldContain("Reconnecting");
}
private static string ExtractRemarksFor(string xml, string member)
{
var memberStart = xml.IndexOf($"<member name=\"{member}\"", StringComparison.Ordinal);
if (memberStart < 0) return string.Empty;
var memberEnd = xml.IndexOf("</member>", memberStart, StringComparison.Ordinal);
if (memberEnd < 0) return string.Empty;
var slice = xml.Substring(memberStart, memberEnd - memberStart);
var remarksStart = slice.IndexOf("<remarks>", StringComparison.Ordinal);
if (remarksStart < 0) return string.Empty;
var remarksEnd = slice.IndexOf("</remarks>", remarksStart, StringComparison.Ordinal);
return remarksEnd < 0 ? string.Empty : slice.Substring(remarksStart, remarksEnd - remarksStart);
}
}