docs(historian-gateway): correct the alarm-readback skip reason (SQL reader works)
v2-ci / build (pull_request) Failing after 44s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (pull_request) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (pull_request) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (pull_request) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (pull_request) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (pull_request) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (pull_request) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (pull_request) Has been skipped

Live investigation showed the earlier 'C2 server-gated event reads' attribution was
wrong: the gateway's SQL event reader works (a source-filtered ReadEvents returns a
real Galaxy-sourced event's history; a time-only ReadEvents returns 50 events). The
alarm round-trip's source-filtered readback is empty only because an ad-hoc SendEvent
is recorded in Runtime.dbo.Events WITHOUT a Source_Object — so reading existing Galaxy
alarm/event history by source works, but round-tripping OtOpcUa's own sends by source
needs the gateway's SendEvent to populate the event source. Skip message corrected.

Claude-Session: https://claude.ai/code/session_012SDSQ3AcaXqPcBtDESBRii
This commit is contained in:
Joseph Doherty
2026-06-26 23:59:56 -04:00
parent 44644ddc7f
commit 240c967576
@@ -200,18 +200,20 @@ public sealed class GatewayLiveIntegrationTests(GatewayLiveFixture fixture) : IC
} }
while (DateTime.UtcNow < deadline); while (DateTime.UtcNow < deadline);
// The SendEvent itself is the OtOpcUa contract and is asserted above. The READBACK depends on // The SendEvent itself is the OtOpcUa contract and is asserted above. The source-filtered
// the historian surfacing the sent event through the SQL dbo.Events path — which is server-gated // READBACK of a just-sent event is a historian/gateway property, not an OtOpcUa one: verified
// on 2023 R2 (the gateway's documented "C2" event-read limitation, closed won't-fix: native // live, the gateway's SQL event reader works and source-filtering works for events that carry a
// event reads are retrieval-server-gated, and the SQL workaround does not surface ad-hoc // Source_Object (real Galaxy-sourced events read back by source correctly), but an ad-hoc
// SendEvents on that server). So when no event comes back, skip with that reason rather than // SendEvent is recorded in dbo.Events WITHOUT a Source_Object — so a source-filtered read of a
// failing — the send was validated; the readback is a historian capability, not OtOpcUa's. // freshly-sent event finds nothing. Reading existing Galaxy alarm/event history by source works;
// round-tripping OtOpcUa's OWN sends by source needs the gateway's SendEvent to populate the
// event source. So when no event comes back, skip with that reason rather than failing.
if (events.Count == 0) if (events.Count == 0)
{ {
Assert.Skip( Assert.Skip(
$"Send acked, but ReadEvents returned 0 for source '{source}'. Event reads are server-gated " + $"Send acked, but a source-filtered ReadEvents returned 0 for source '{source}'. The SQL event " +
"on this historian (gateway C2, won't-fix) — run against a historian where event reads are " + "reader works (Galaxy-sourced events read back by source); an ad-hoc SendEvent is stored without " +
"supported to exercise the alarm readback."); "a Source_Object, so its source-filtered readback is empty until the gateway populates the event source.");
} }
var exactMatch = events.Any(e => string.Equals(e.EventId, alarmId, StringComparison.Ordinal)); var exactMatch = events.Any(e => string.Equals(e.EventId, alarmId, StringComparison.Ordinal));