Merge pull request 'Phase 2 PR 8 — gateway-level host-status push from MxAccessGalaxyBackend' (#7) from phase-2-pr8-alarms-hoststatus into v2
This commit was merged in pull request #7.
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ArchestrA.MxAccess;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Host.Backend;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Host.Backend.Galaxy;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Host.Backend.MxAccess;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Host.Sta;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Shared.Contracts;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Host.Tests;
|
||||
|
||||
[Trait("Category", "Unit")]
|
||||
public sealed class HostStatusPushTests
|
||||
{
|
||||
/// <summary>
|
||||
/// PR 8 — when MxAccessClient.ConnectionStateChanged fires false→true→false,
|
||||
/// MxAccessGalaxyBackend raises OnHostStatusChanged once per transition with
|
||||
/// HostName=ClientName, RuntimeStatus="Running"/"Stopped", and a timestamp.
|
||||
/// This is the gateway-level signal; per-platform ScanState probes are deferred.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task ConnectionStateChanged_raises_OnHostStatusChanged_with_gateway_name()
|
||||
{
|
||||
using var pump = new StaPump("Test.Sta");
|
||||
await pump.WaitForStartedAsync();
|
||||
var proxy = new FakeProxy();
|
||||
var mx = new MxAccessClient(pump, proxy, "GatewayClient", new MxAccessClientOptions { AutoReconnect = false });
|
||||
using var backend = new MxAccessGalaxyBackend(
|
||||
new GalaxyRepository(new GalaxyRepositoryOptions { ConnectionString = "Server=.;Database=ZB;Integrated Security=True;" }),
|
||||
mx,
|
||||
historian: null);
|
||||
|
||||
var notifications = new ConcurrentQueue<HostConnectivityStatus>();
|
||||
backend.OnHostStatusChanged += (_, s) => notifications.Enqueue(s);
|
||||
|
||||
await mx.ConnectAsync();
|
||||
await mx.DisconnectAsync();
|
||||
|
||||
notifications.Count.ShouldBe(2);
|
||||
notifications.TryDequeue(out var first).ShouldBeTrue();
|
||||
first!.HostName.ShouldBe("GatewayClient");
|
||||
first.RuntimeStatus.ShouldBe("Running");
|
||||
first.LastObservedUtcUnixMs.ShouldBeGreaterThan(0);
|
||||
|
||||
notifications.TryDequeue(out var second).ShouldBeTrue();
|
||||
second!.HostName.ShouldBe("GatewayClient");
|
||||
second.RuntimeStatus.ShouldBe("Stopped");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Dispose_unsubscribes_so_post_dispose_state_changes_do_not_fire_events()
|
||||
{
|
||||
using var pump = new StaPump("Test.Sta");
|
||||
await pump.WaitForStartedAsync();
|
||||
var proxy = new FakeProxy();
|
||||
var mx = new MxAccessClient(pump, proxy, "GatewayClient", new MxAccessClientOptions { AutoReconnect = false });
|
||||
var backend = new MxAccessGalaxyBackend(
|
||||
new GalaxyRepository(new GalaxyRepositoryOptions { ConnectionString = "Server=.;Database=ZB;Integrated Security=True;" }),
|
||||
mx,
|
||||
historian: null);
|
||||
|
||||
var count = 0;
|
||||
backend.OnHostStatusChanged += (_, _) => Interlocked.Increment(ref count);
|
||||
|
||||
await mx.ConnectAsync();
|
||||
count.ShouldBe(1);
|
||||
|
||||
backend.Dispose();
|
||||
await mx.DisconnectAsync();
|
||||
|
||||
count.ShouldBe(1); // no second notification after Dispose
|
||||
}
|
||||
|
||||
private sealed class FakeProxy : IMxProxy
|
||||
{
|
||||
private int _next = 1;
|
||||
public int Register(string _) => 42;
|
||||
public void Unregister(int _) { }
|
||||
public int AddItem(int _, string __) => Interlocked.Increment(ref _next);
|
||||
public void RemoveItem(int _, int __) { }
|
||||
public void AdviseSupervisory(int _, int __) { }
|
||||
public void UnAdviseSupervisory(int _, int __) { }
|
||||
public void Write(int _, int __, object ___, int ____) { }
|
||||
public event MxDataChangeHandler? OnDataChange { add { } remove { } }
|
||||
public event MxWriteCompleteHandler? OnWriteComplete { add { } remove { } }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user