test(r2-04): live guard - advised write remains Good under fail-closed advise (skip-gated)

This commit is contained in:
Joseph Doherty
2026-07-13 10:54:13 -04:00
parent 084c6e3cee
commit edbbc0438c
2 changed files with 29 additions and 1 deletions
@@ -9,7 +9,7 @@
{ "id": "T5", "subject": "Galaxy internal IMxWriteOps seam under GatewayGalaxyDataWriter (sealed SDK session untestable) (06/S-1)", "status": "completed", "blockedBy": [] },
{ "id": "T6", "subject": "Galaxy fail-closed write on AdviseSupervisory failure -> BadCommunicationError, no raw write", "status": "completed", "blockedBy": ["T5"] },
{ "id": "T7", "subject": "Galaxy counters galaxy.writes.advise_failed + galaxy.writes.unconfirmed (empty-statuses Good metered)", "status": "completed", "blockedBy": ["T6"] },
{ "id": "T8", "subject": "Galaxy skip-gated live smoke: normal advised write still returns Good post-change", "status": "pending", "blockedBy": ["T6"] },
{ "id": "T8", "subject": "Galaxy skip-gated live smoke: normal advised write still returns Good post-change", "status": "completed", "blockedBy": ["T6"] },
{ "id": "T9", "subject": "PrimaryGatePolicy pure class + truth-table tests + otopcua.redundancy.primary_gate_denied counter (03/S4)", "status": "pending", "blockedBy": [] },
{ "id": "T10", "subject": "Wire DriverHostActor gates (:977/:1039/:1095) through PrimaryGatePolicy with member-count provider + S5 log-once", "status": "pending", "blockedBy": ["T9"] },
{ "id": "T11", "subject": "DriverHostActorPrimaryGateTests: deny-on-unknown multi-node, allow single-node, ack/emit variants, meter tags", "status": "pending", "blockedBy": ["T10"] },
@@ -173,6 +173,34 @@ public sealed class GatewayGalaxyLiveReopenAndWriteTests
$"borrow smoke: subscribed {WriteRef} -> handle {match.ItemHandle}; borrowed write Good with AddItemCallCount=0; control AddItemCallCount=1");
}
/// <summary>
/// archreview 06/S-1 guard — after the fail-closed advise change, a NORMAL advised no-login write
/// must STILL return Good (0). Guards against over-eager fail-closing: the advise round-trip succeeds
/// on a healthy gateway, so the raw Write proceeds and commits. If this ever returns Bad on a healthy
/// gateway, the fail-closed branch is mis-judging a successful advise. Skip-gated like the others.
/// </summary>
[Fact]
public async Task Live_normal_advised_write_still_returns_good_under_failclosed_advise()
{
var (endpoint, apiKey) = RequireLiveGatewayOrSkip();
var ct = TestContext.Current.CancellationToken;
var clientOptions = BuildClientOptions(endpoint, apiKey);
await using var session = new GalaxyMxSession(new GalaxyMxAccessOptions(ClientName: "OtOpcUaFailClosedGuard"));
await session.ConnectAsync(clientOptions, ct);
var writer = new GatewayGalaxyDataWriter(session, writeUserId: 0);
var result = await writer.WriteAsync(
[new WriteRequest(WriteRef, 5151.0f)], _ => SecurityClassification.FreeAccess, ct);
result.ShouldHaveSingleItem().StatusCode.ShouldBe(0u,
"a normal advised write must still return Good after the fail-closed advise change (no over-eager fail-close)");
writer.CachedSupervisedHandleCount.ShouldBe(1, "the healthy advise should have supervised the handle");
TestContext.Current.SendDiagnosticMessage(
$"fail-closed guard smoke: normal advised write {WriteRef}=5151 returned Good; handle supervised");
}
private static (string Endpoint, string ApiKey) RequireLiveGatewayOrSkip()
{
var endpoint = Environment.GetEnvironmentVariable("MXGW_ENDPOINT");