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
@@ -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");