67 lines
3.1 KiB
C#
67 lines
3.1 KiB
C#
using Akka.Actor;
|
|
using Akka.TestKit.Xunit2;
|
|
using NSubstitute;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Protocol;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Messages.DataConnection;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Types.Alarms;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
|
|
using ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Actors;
|
|
using ZB.MOM.WW.ScadaBridge.HealthMonitoring;
|
|
|
|
namespace ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests;
|
|
|
|
/// <summary>Task-10: native alarm subscribe + source-ref routing + unavailable signal.</summary>
|
|
public class DataConnectionActorAlarmTests : TestKit
|
|
{
|
|
private readonly ISiteHealthCollector _health = Substitute.For<ISiteHealthCollector>();
|
|
private readonly IDataConnectionFactory _factory = Substitute.For<IDataConnectionFactory>();
|
|
private readonly DataConnectionOptions _options = new()
|
|
{
|
|
ReconnectInterval = TimeSpan.FromMilliseconds(100),
|
|
TagResolutionRetryInterval = TimeSpan.FromMilliseconds(200),
|
|
WriteTimeout = TimeSpan.FromSeconds(5)
|
|
};
|
|
|
|
private static NativeAlarmTransition Raise(string sourceRef, string sourceObj) =>
|
|
new(sourceRef, sourceObj, "AnalogLimit.Hi", AlarmTransitionKind.Raise,
|
|
new AlarmConditionState(true, false, null, AlarmShelveState.Unshelved, false, 500),
|
|
"Process", "hi", "hi", "", "", null, DateTimeOffset.UtcNow, "92", "90");
|
|
|
|
[Fact]
|
|
public void SubscribeAlarms_RoutesTransitionToInstanceSubscriber()
|
|
{
|
|
AlarmTransitionCallback? cb = null;
|
|
var adapter = Substitute.For<IDataConnection, IAlarmSubscribableConnection>();
|
|
adapter.ConnectAsync(Arg.Any<IDictionary<string, string>>(), Arg.Any<CancellationToken>())
|
|
.Returns(Task.CompletedTask);
|
|
((IAlarmSubscribableConnection)adapter)
|
|
.SubscribeAlarmsAsync(Arg.Any<string>(), Arg.Any<string?>(),
|
|
Arg.Do<AlarmTransitionCallback>(c => cb = c), Arg.Any<CancellationToken>())
|
|
.Returns(Task.FromResult("alarm-sub-1"));
|
|
|
|
var actor = Sys.ActorOf(Props.Create(() => new DataConnectionActor(
|
|
"conn", adapter, _options, _health, _factory, "OpcUa")));
|
|
|
|
actor.Tell(new SubscribeAlarmsRequest("c", "inst", "conn", "Tank01", null, DateTimeOffset.UtcNow));
|
|
ExpectMsg<SubscribeAlarmsResponse>(m => m.Success);
|
|
|
|
Assert.NotNull(cb);
|
|
cb!(Raise("Tank01.Hi", "Tank01"));
|
|
ExpectMsg<NativeAlarmTransitionUpdate>(u => u.Transition.SourceObjectReference == "Tank01");
|
|
}
|
|
|
|
[Fact]
|
|
public void SubscribeAlarms_OnNonAlarmCapableAdapter_RepliesFailure()
|
|
{
|
|
var adapter = Substitute.For<IDataConnection>(); // not IAlarmSubscribableConnection
|
|
adapter.ConnectAsync(Arg.Any<IDictionary<string, string>>(), Arg.Any<CancellationToken>())
|
|
.Returns(Task.CompletedTask);
|
|
|
|
var actor = Sys.ActorOf(Props.Create(() => new DataConnectionActor(
|
|
"conn", adapter, _options, _health, _factory, "OpcUa")));
|
|
|
|
actor.Tell(new SubscribeAlarmsRequest("c", "inst", "conn", "Tank01", null, DateTimeOffset.UtcNow));
|
|
ExpectMsg<SubscribeAlarmsResponse>(m => !m.Success && m.ErrorMessage != null);
|
|
}
|
|
}
|