docs(alarms): record native alarms verified working; add D.1 smoke
v2-ci / build (push) Failing after 47s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
v2-ci / build (push) Failing after 47s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
The 2026-04-30 alarm plan banners claimed worker-side native alarm subscription was blocked on a COM-bitness finding. That's stale: the mxaccessgw .NET client now has true MxAccess alarm-event support, and a live StreamAlarms check (+ new Skip-gated GatewayGalaxyAlarmFeedLiveTests through the lmxopcua consumer) confirms native alarms — operator comment, category, severity, timestamps — flow end-to-end. Reconcile both plan docs to reality and add docs/plans/alarms-d1-smoke-artifact.md as the D.1 alarm-source deliverable. Historian-write live smoke + full server->A&C round-trip remain (Windows parity rig only).
This commit is contained in:
+82
@@ -0,0 +1,82 @@
|
||||
using ZB.MOM.WW.MxGateway.Client;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Runtime;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests.Runtime;
|
||||
|
||||
/// <summary>
|
||||
/// D.1 smoke (alarm-source leg): drives the REAL gateway <c>StreamAlarms</c> feed through the
|
||||
/// production lmxopcua consumer (<see cref="GatewayGalaxyAlarmFeed"/>) and asserts native alarm
|
||||
/// transitions — with operator comment, category, original raise time, and the mapped OPC UA
|
||||
/// severity bucket preserved — reach the driver-side boundary that feeds
|
||||
/// <c>IAlarmSource.OnAlarmEvent</c>.
|
||||
/// <para>
|
||||
/// Skip-gated: runs only when <c>MXGW_ENDPOINT</c> + <c>GALAXY_MXGW_API_KEY</c> are set to a
|
||||
/// reachable gateway. Captured 2026-05-29 against <c>10.100.0.48:5120</c> — see
|
||||
/// <c>docs/plans/alarms-d1-smoke-artifact.md</c>. Set <c>D1_SMOKE_OUT</c> to dump the observed
|
||||
/// transitions to a file for artifact capture.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[Trait("Category", "Integration")]
|
||||
public sealed class GatewayGalaxyAlarmFeedLiveTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Live_gateway_delivers_native_alarm_transitions_through_the_consumer()
|
||||
{
|
||||
var endpoint = Environment.GetEnvironmentVariable("MXGW_ENDPOINT");
|
||||
var apiKey = Environment.GetEnvironmentVariable("GALAXY_MXGW_API_KEY");
|
||||
if (string.IsNullOrWhiteSpace(endpoint) || string.IsNullOrWhiteSpace(apiKey))
|
||||
Assert.Skip("Set MXGW_ENDPOINT + GALAXY_MXGW_API_KEY to run the live gateway alarm-feed smoke.");
|
||||
|
||||
var client = MxGatewayClient.Create(new MxGatewayClientOptions
|
||||
{
|
||||
Endpoint = new Uri(endpoint!, UriKind.Absolute),
|
||||
ApiKey = apiKey!,
|
||||
UseTls = false,
|
||||
ConnectTimeout = TimeSpan.FromSeconds(10),
|
||||
DefaultCallTimeout = TimeSpan.FromSeconds(30),
|
||||
StreamTimeout = TimeSpan.FromSeconds(30),
|
||||
});
|
||||
|
||||
var observed = new List<GalaxyAlarmTransition>();
|
||||
var gotOne = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
// Wire the live client's StreamAlarms method group into the production consumer seam.
|
||||
await using var feed = new GatewayGalaxyAlarmFeed(client.StreamAlarmsAsync, clientName: "D1Smoke");
|
||||
feed.OnAlarmTransition += (_, t) =>
|
||||
{
|
||||
lock (observed) { observed.Add(t); }
|
||||
gotOne.TrySetResult(true);
|
||||
};
|
||||
feed.Start();
|
||||
|
||||
// The stream opens with the active-alarm snapshot, so we expect ≥1 transition promptly.
|
||||
await Task.WhenAny(gotOne.Task, Task.Delay(TimeSpan.FromSeconds(20), TestContext.Current.CancellationToken));
|
||||
|
||||
List<GalaxyAlarmTransition> snapshot;
|
||||
lock (observed) snapshot = observed.ToList();
|
||||
|
||||
snapshot.ShouldNotBeEmpty(
|
||||
"Live gateway should deliver at least the active-alarm snapshot through the lmxopcua consumer.");
|
||||
var first = snapshot[0];
|
||||
first.AlarmFullReference.ShouldNotBeNullOrWhiteSpace();
|
||||
first.OpcUaSeverity.ShouldBeGreaterThan(0); // severity bucket mapping applied by the consumer
|
||||
|
||||
foreach (var t in snapshot.Take(8))
|
||||
TestContext.Current.SendDiagnosticMessage(
|
||||
$"{t.TransitionKind,-11} {t.AlarmFullReference} sev={t.OpcUaSeverity}({t.SeverityBucket}) cat={t.Category} comment='{t.OperatorComment}'");
|
||||
TestContext.Current.SendDiagnosticMessage($"TOTAL consumer transitions observed: {snapshot.Count}");
|
||||
|
||||
// Deterministic artifact capture (only when D1_SMOKE_OUT is set).
|
||||
var outPath = Environment.GetEnvironmentVariable("D1_SMOKE_OUT");
|
||||
if (!string.IsNullOrWhiteSpace(outPath))
|
||||
{
|
||||
var lines = snapshot.Take(50).Select(t =>
|
||||
$"{t.TransitionKind,-11} {t.AlarmFullReference} | sev={t.OpcUaSeverity}({t.SeverityBucket}) raw={t.RawMxAccessSeverity} | cat={t.Category} | comment='{t.OperatorComment}' | xitionUtc={t.TransitionTimestampUtc:o}");
|
||||
await File.WriteAllLinesAsync(outPath!,
|
||||
new[] { $"# consumer transitions observed: {snapshot.Count}" }.Concat(lines),
|
||||
TestContext.Current.CancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -25,6 +25,9 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ZB.MOM.WW.MxGateway.Contracts" />
|
||||
<!-- Client package: only the Skip-gated live alarm-feed smoke (GatewayGalaxyAlarmFeedLiveTests)
|
||||
constructs a real MxGatewayClient. Unit tests use the fake stream-factory seam. -->
|
||||
<PackageReference Include="ZB.MOM.WW.MxGateway.Client" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user