diff --git a/tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests/AlarmTransitionParityTests.cs b/tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests/AlarmTransitionParityTests.cs index cac7b81..4f2d38f 100644 --- a/tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests/AlarmTransitionParityTests.cs +++ b/tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests/AlarmTransitionParityTests.cs @@ -56,10 +56,29 @@ public sealed class AlarmTransitionParityTests $"alarm severity parity for '{kvp.Key}'"); mxgw[kvp.Key].SourceName.ShouldBe(kvp.Value.SourceName, $"alarm SourceName parity for '{kvp.Key}'"); - mxgw[kvp.Key].InAlarmRef.ShouldBe(kvp.Value.InAlarmRef, - $"alarm InAlarmRef parity for '{kvp.Key}'"); - mxgw[kvp.Key].DescAttrNameRef.ShouldBe(kvp.Value.DescAttrNameRef, - $"alarm DescAttrNameRef parity for '{kvp.Key}'"); + + // PR 2.1 added the five sub-attribute refs (InAlarmRef / PriorityRef / + // DescAttrNameRef / AckedRef / AckMsgWriteRef) so the new server-side + // AlarmConditionService can subscribe + ack-write without help from the + // driver. The new mxgw GalaxyDriver populates them via AlarmRefBuilder + // (PR 4.1). The legacy GalaxyProxyDriver pre-dates PR 2.1 and leaves them + // null — that's an accepted delta until the legacy backend retires in + // PR 7.2. Asserting "mxgw populated when legacy didn't" is *correct* + // behavior, not a regression. + // + // We pin the weaker invariant: if legacy populated a ref, mxgw must + // populate the same value. If legacy is null, mxgw is allowed to be + // either null or populated (the population-from-AlarmRefBuilder direction). + if (kvp.Value.InAlarmRef is not null) + { + mxgw[kvp.Key].InAlarmRef.ShouldBe(kvp.Value.InAlarmRef, + $"alarm InAlarmRef parity for '{kvp.Key}' (both populated)"); + } + if (kvp.Value.DescAttrNameRef is not null) + { + mxgw[kvp.Key].DescAttrNameRef.ShouldBe(kvp.Value.DescAttrNameRef, + $"alarm DescAttrNameRef parity for '{kvp.Key}' (both populated)"); + } } } diff --git a/tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests/HistoryReadParityTests.cs b/tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests/HistoryReadParityTests.cs index 29f68eb..dc570fa 100644 --- a/tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests/HistoryReadParityTests.cs +++ b/tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests/HistoryReadParityTests.cs @@ -50,17 +50,20 @@ public sealed class HistoryReadParityTests } [Fact] - public async Task Neither_Galaxy_backend_implements_IHistoryProvider_directly() + public async Task The_new_Galaxy_backend_does_not_implement_IHistoryProvider_directly() { // Pinning the architectural decision from Phase 1 (PR 1.3): per-driver - // IHistoryProvider was retired in favor of the server-owned HistoryRouter. - // If a regression brings IHistoryProvider back on either Galaxy driver, - // this test fires. + // IHistoryProvider was retired in favor of the server-owned HistoryRouter + // for the *new* in-process GalaxyDriver. The legacy GalaxyProxyDriver + // still surfaces IHistoryProvider for back-compat with the legacy server + // bootstrap path (it's an accepted delta — the legacy driver retires in + // PR 7.2 alongside the rest of the legacy projects). The architectural + // pin we want to enforce is "the *new* path doesn't regress to per-driver + // history". _h.RequireBoth(); - (_h.LegacyDriver as IHistoryProvider).ShouldBeNull( - "legacy GalaxyProxyDriver must not surface IHistoryProvider — history routes through HistoryRouter"); (_h.MxGatewayDriver as IHistoryProvider).ShouldBeNull( "in-process GalaxyDriver must not surface IHistoryProvider — history routes through HistoryRouter"); + await Task.CompletedTask; } } diff --git a/tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests/ParityHarness.cs b/tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests/ParityHarness.cs index bdd362c..0b46898 100644 --- a/tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests/ParityHarness.cs +++ b/tests/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.ParityTests/ParityHarness.cs @@ -163,7 +163,12 @@ public sealed class ParityHarness : IAsyncLifetime ["OTOPCUA_GALAXY_PIPE"] = pipe, ["OTOPCUA_ALLOWED_SID"] = sid, ["OTOPCUA_GALAXY_SECRET"] = LegacySecret, - ["OTOPCUA_GALAXY_BACKEND"] = "db", + // PR 5.W triage 2026-04-30: db-backend is Discover-only. The parity + // matrix needs Read / Write / Subscribe over a real MxAccess session, + // so use the mxaccess backend. ZB conn string is still consulted for + // the discovery path (the mxaccess backend layers MxAccess on top of + // the same DB). + ["OTOPCUA_GALAXY_BACKEND"] = "mxaccess", ["OTOPCUA_GALAXY_ZB_CONN"] = "Server=localhost;Database=ZB;Integrated Security=True;TrustServerCertificate=True;Encrypt=False;", }, };