104 lines
4.0 KiB
C#
104 lines
4.0 KiB
C#
using System.Text.Json;
|
|
using Akka.Actor;
|
|
using Akka.TestKit.Xunit2;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Messages.DataConnection;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Messages.DebugView;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Streaming;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Types.Alarms;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening;
|
|
using ZB.MOM.WW.ScadaBridge.SiteRuntime;
|
|
using ZB.MOM.WW.ScadaBridge.SiteRuntime.Actors;
|
|
using ZB.MOM.WW.ScadaBridge.SiteRuntime.Persistence;
|
|
using ZB.MOM.WW.ScadaBridge.SiteRuntime.Scripts;
|
|
|
|
namespace ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests.Actors;
|
|
|
|
/// <summary>
|
|
/// Task 16: InstanceActor spawns NativeAlarmActor children from the flattened
|
|
/// configuration and surfaces enriched native alarm state in the DebugView snapshot.
|
|
/// </summary>
|
|
public class InstanceActorNativeAlarmTests : TestKit, IDisposable
|
|
{
|
|
private readonly SiteStorageService _storage;
|
|
private readonly ScriptCompilationService _compilationService;
|
|
private readonly SharedScriptLibrary _sharedScriptLibrary;
|
|
private readonly SiteRuntimeOptions _options = new();
|
|
private readonly string _dbFile;
|
|
|
|
public InstanceActorNativeAlarmTests()
|
|
{
|
|
_dbFile = Path.Combine(Path.GetTempPath(), $"instance-native-{Guid.NewGuid():N}.db");
|
|
_storage = new SiteStorageService($"Data Source={_dbFile}", NullLogger<SiteStorageService>.Instance);
|
|
_storage.InitializeAsync().GetAwaiter().GetResult();
|
|
_compilationService = new ScriptCompilationService(NullLogger<ScriptCompilationService>.Instance);
|
|
_sharedScriptLibrary = new SharedScriptLibrary(_compilationService, NullLogger<SharedScriptLibrary>.Instance);
|
|
}
|
|
|
|
private IActorRef CreateInstanceActorWithDcl(string instanceName, FlattenedConfiguration config, IActorRef dclManager) =>
|
|
ActorOf(Props.Create(() => new InstanceActor(
|
|
instanceName,
|
|
JsonSerializer.Serialize(config),
|
|
_storage,
|
|
_compilationService,
|
|
_sharedScriptLibrary,
|
|
null,
|
|
_options,
|
|
NullLogger<InstanceActor>.Instance,
|
|
dclManager)));
|
|
|
|
private static FlattenedConfiguration ConfigWithNativeSource(string instanceName) => new()
|
|
{
|
|
InstanceUniqueName = instanceName,
|
|
NativeAlarmSources =
|
|
[
|
|
new ResolvedNativeAlarmSource
|
|
{
|
|
CanonicalName = "Pressure",
|
|
ConnectionName = "Opc",
|
|
SourceReference = "ns=2;s=T01"
|
|
}
|
|
]
|
|
};
|
|
|
|
[Fact]
|
|
public void SpawnsNativeAlarmActor_WhichSubscribesViaDcl()
|
|
{
|
|
var dcl = CreateTestProbe();
|
|
CreateInstanceActorWithDcl("inst", ConfigWithNativeSource("inst"), dcl.Ref);
|
|
|
|
var req = dcl.ExpectMsg<SubscribeAlarmsRequest>();
|
|
Assert.Equal("inst", req.InstanceUniqueName);
|
|
Assert.Equal("Opc", req.ConnectionName);
|
|
Assert.Equal("ns=2;s=T01", req.SourceReference);
|
|
}
|
|
|
|
[Fact]
|
|
public void DebugViewSnapshot_IncludesNativeAlarm_AfterTransition()
|
|
{
|
|
var dcl = CreateTestProbe();
|
|
var actor = CreateInstanceActorWithDcl("inst", ConfigWithNativeSource("inst"), dcl.Ref);
|
|
|
|
// Simulate the NativeAlarmActor emitting an enriched event upward.
|
|
actor.Tell(new AlarmStateChanged("inst", "T01.Hi", AlarmState.Active, 800, DateTimeOffset.UtcNow)
|
|
{
|
|
Kind = AlarmKind.NativeOpcUa,
|
|
SourceReference = "T01.Hi",
|
|
Condition = new AlarmConditionState(true, false, null, AlarmShelveState.Unshelved, false, 800)
|
|
});
|
|
|
|
actor.Tell(new SubscribeDebugViewRequest("inst", "c"));
|
|
var snap = ExpectMsg<DebugViewSnapshot>();
|
|
|
|
Assert.Contains(snap.AlarmStates, a =>
|
|
a.SourceReference == "T01.Hi" && a.Kind == AlarmKind.NativeOpcUa && a.Condition.Severity == 800);
|
|
}
|
|
|
|
void IDisposable.Dispose()
|
|
{
|
|
Shutdown();
|
|
try { File.Delete(_dbFile); } catch { /* cleanup */ }
|
|
}
|
|
}
|