Task #219 — Server-integration test coverage for IAlarmSource dispatch path #197
Reference in New Issue
Block a user
Delete Branch "task-219-alarm-history-integration"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
AlarmSubscribeIntegrationTestsalongsideHistoryReadIntegrationTestsso both optional driver capabilities —IHistoryProvider(already covered) andIAlarmSource(new) — have end-to-end coverage that boots the full OPC UA stack and exercises the wiring path from driver event →GenericDriverNodeManagerforwarder →DriverNodeManager.ConditionSinkthrough a realOpc.Ua.Client.Session.CapturingHandleproduces distinctAlarmConditionStatenodes for eachIsAlarm=truevariable.Scoped-out (documented in the class docstring, not regressions)
AlarmConditionState's inherited children (Severity/Message/ActiveState/…) with Foundation-namespace NodeIds that theDriverNodeManagerdoes not add to its predefined-node index, so reading those child attributes through a client returnsBadNodeIdUnknown.Server+ConditionRefresh) is out of reach until the node manager wiresHasNotifier+ child-node registration.GenericDriverNodeManagerTests; this PR adds the missing server-integration layer.Test plan
dotnet test tests/ZB.MOM.WW.OtOpcUa.Server.Tests/ZB.MOM.WW.OtOpcUa.Server.Tests.csproj→ 238 passed, 0 failed (includes the two new tests).🤖 Generated with Claude Code
Adds AlarmSubscribeIntegrationTests alongside HistoryReadIntegrationTests so both optional driver capabilities — IHistoryProvider (already covered) and IAlarmSource (new) — have end-to-end coverage that boots the full OPC UA stack and exercises the wiring path from driver event → GenericDriverNodeManager forwarder → DriverNodeManager ConditionSink through a real Session. Two tests: 1. Driver_alarm_transition_updates_server_side_AlarmConditionState_node — a fake IAlarmSource declares an IsAlarm=true variable, calls MarkAsAlarmCondition in DiscoverAsync, and fires OnAlarmEvent for that source. Verifies the client can browse the alarm condition node at FullReference + ".Condition" and reads the DisplayName back through Session.Read. 2. Each_IsAlarm_variable_registers_its_own_condition_node_in_the_driver_namespace — two IsAlarm variables each produce their own addressable AlarmConditionState, proving the CapturingHandle per-variable registration works. Scoped-out (documented in the class docstring): the stack exposes AlarmConditionState's inherited children (Severity / Message / ActiveState / …) with Foundation-namespace NodeIds that DriverNodeManager does not add to its predefined-node index, so reading those child attributes through a client returns BadNodeIdUnknown. OPC UA Part 9 event propagation (subscribe-on-Server + ConditionRefresh) is likewise out of reach until the node manager wires HasNotifier + child-node registration. The existing Core-level GenericDriverNodeManagerTests cover the in-memory alarm-sink fan-out semantics. Full Server.Tests suite: 238 passed, 0 failed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>