From 240c967576f8a84fdce3cf0f4031c93a6fd1067d Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Fri, 26 Jun 2026 23:59:56 -0400 Subject: [PATCH] docs(historian-gateway): correct the alarm-readback skip reason (SQL reader works) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../Live/GatewayLiveIntegrationTests.cs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests/Live/GatewayLiveIntegrationTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests/Live/GatewayLiveIntegrationTests.cs index a215095c..fb9f06a3 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests/Live/GatewayLiveIntegrationTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests/Live/GatewayLiveIntegrationTests.cs @@ -200,18 +200,20 @@ public sealed class GatewayLiveIntegrationTests(GatewayLiveFixture fixture) : IC } while (DateTime.UtcNow < deadline); - // The SendEvent itself is the OtOpcUa contract and is asserted above. The READBACK depends on - // the historian surfacing the sent event through the SQL dbo.Events path — which is server-gated - // on 2023 R2 (the gateway's documented "C2" event-read limitation, closed won't-fix: native - // event reads are retrieval-server-gated, and the SQL workaround does not surface ad-hoc - // SendEvents on that server). So when no event comes back, skip with that reason rather than - // failing — the send was validated; the readback is a historian capability, not OtOpcUa's. + // The SendEvent itself is the OtOpcUa contract and is asserted above. The source-filtered + // READBACK of a just-sent event is a historian/gateway property, not an OtOpcUa one: verified + // live, the gateway's SQL event reader works and source-filtering works for events that carry a + // Source_Object (real Galaxy-sourced events read back by source correctly), but an ad-hoc + // SendEvent is recorded in dbo.Events WITHOUT a Source_Object — so a source-filtered read of a + // 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) { Assert.Skip( - $"Send acked, but ReadEvents returned 0 for source '{source}'. Event reads are server-gated " + - "on this historian (gateway C2, won't-fix) — run against a historian where event reads are " + - "supported to exercise the alarm readback."); + $"Send acked, but a source-filtered ReadEvents returned 0 for source '{source}'. The SQL event " + + "reader works (Galaxy-sourced events read back by source); an ad-hoc SendEvent is stored without " + + "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));