using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Core.Abstractions; namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests; /// /// End-to-end smoke against a live opc-plc simulator launched in alarm mode /// (--alm). Exercises the filter-aware /// /// overload by issuing a HistoryReadEvents against the simulator's Server notifier /// and asserting at least one historical event row comes back with the SelectClause /// fields populated. /// /// /// Requires the simulator started with --alm (alarm + history simulation), which /// does not guarantee — the test skips with a clear reason /// when the upstream returns BadHistoryOperationUnsupported instead of a HistoryEvent /// payload. PR-12 ships the build-only scaffold; the green-test pass lands when the /// fixture image is upgraded to the alarm SKU. /// [Collection(OpcPlcCollection.Name)] [Trait("Category", "Integration")] [Trait("Simulator", "opc-plc")] public sealed class OpcUaClientHistoryEventsTests(OpcPlcFixture sim) { [Fact] public async Task ReadEventsAsync_against_opc_plc_alarm_mode_returns_BaseEventType_fields() { if (sim.SkipReason is not null) Assert.Skip(sim.SkipReason); // Build-only scaffold: the test wires up the call but skips before assertions until // the opc-plc fixture is launched with --alm. When the fixture image carries alarms // the call should round-trip through Session.HistoryReadAsync + ReadEventDetails and // produce at least one HistoricalEventRow with the default SelectClause keys // populated (EventId / SourceName / Time / Message / Severity / ReceiveTime). Assert.Skip( "opc-plc --alm mode not guaranteed by the default fixture image. " + "Re-enable when OpcPlcFixture is upgraded to launch with --alm and a known-good " + "alarm event source path."); #pragma warning disable CS0162 // unreachable scaffold below — kept for the post-fixture-upgrade flip var options = OpcPlcProfile.BuildOptions(sim.EndpointUrl); await using var drv = new OpcUaClientDriver(options, driverInstanceId: "opcua-events-smoke"); await drv.InitializeAsync("{}", TestContext.Current.CancellationToken); var request = new EventHistoryRequest( StartTime: DateTime.UtcNow.AddMinutes(-30), EndTime: DateTime.UtcNow.AddMinutes(1), NumValuesPerNode: 100, SelectClauses: null, WhereClause: null); // The Server node (i=2253) is the standard history-events notifier on opc-plc. var batch = await drv.ReadEventsAsync("i=2253", request, TestContext.Current.CancellationToken); batch.ShouldNotBeNull(); batch.Events.Count.ShouldBeGreaterThan(0, "opc-plc --alm raises events at least every 5s"); var first = batch.Events[0]; first.Fields.ShouldContainKey("EventId"); first.Fields.ShouldContainKey("Severity"); #pragma warning restore CS0162 } }