71 lines
3.1 KiB
C#
71 lines
3.1 KiB
C#
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.E2E;
|
|
|
|
/// <summary>
|
|
/// Test-only <see cref="IAddressSpaceBuilder"/> that records every Folder + Variable
|
|
/// registration. Mirrors the v1 in-process address-space build so tests can assert on
|
|
/// the same shape the legacy <c>LmxNodeManager</c> produced.
|
|
/// </summary>
|
|
public sealed class RecordingAddressSpaceBuilder : IAddressSpaceBuilder
|
|
{
|
|
public List<RecordedFolder> Folders { get; } = new();
|
|
public List<RecordedVariable> Variables { get; } = new();
|
|
public List<RecordedProperty> Properties { get; } = new();
|
|
public List<RecordedAlarmCondition> AlarmConditions { get; } = new();
|
|
|
|
public IAddressSpaceBuilder Folder(string browseName, string displayName)
|
|
{
|
|
Folders.Add(new RecordedFolder(browseName, displayName));
|
|
return this; // single flat builder for tests; nesting irrelevant for parity assertions
|
|
}
|
|
|
|
public IVariableHandle Variable(string browseName, string displayName, DriverAttributeInfo attributeInfo)
|
|
{
|
|
Variables.Add(new RecordedVariable(browseName, displayName, attributeInfo));
|
|
return new RecordedVariableHandle(attributeInfo.FullName, AlarmConditions);
|
|
}
|
|
|
|
public void AddProperty(string browseName, DriverDataType dataType, object? value)
|
|
{
|
|
Properties.Add(new RecordedProperty(browseName, dataType, value));
|
|
}
|
|
|
|
public sealed record RecordedFolder(string BrowseName, string DisplayName);
|
|
public sealed record RecordedVariable(string BrowseName, string DisplayName, DriverAttributeInfo AttributeInfo);
|
|
public sealed record RecordedProperty(string BrowseName, DriverDataType DataType, object? Value);
|
|
public sealed record RecordedAlarmCondition(string SourceNodeId, AlarmConditionInfo Info);
|
|
public sealed record RecordedAlarmTransition(string SourceNodeId, AlarmEventArgs Args);
|
|
|
|
/// <summary>
|
|
/// Sink the tests assert on to verify the alarm event forwarder routed a transition
|
|
/// to the correct source-node-id. One entry per <see cref="IAlarmSource.OnAlarmEvent"/>.
|
|
/// </summary>
|
|
public List<RecordedAlarmTransition> AlarmTransitions { get; } = new();
|
|
|
|
private sealed class RecordedVariableHandle : IVariableHandle
|
|
{
|
|
private readonly List<RecordedAlarmCondition> _conditions;
|
|
public string FullReference { get; }
|
|
public RecordedVariableHandle(string fullReference, List<RecordedAlarmCondition> conditions)
|
|
{
|
|
FullReference = fullReference;
|
|
_conditions = conditions;
|
|
}
|
|
|
|
public IAlarmConditionSink MarkAsAlarmCondition(AlarmConditionInfo info)
|
|
{
|
|
_conditions.Add(new RecordedAlarmCondition(FullReference, info));
|
|
return new RecordingSink(FullReference);
|
|
}
|
|
|
|
private sealed class RecordingSink : IAlarmConditionSink
|
|
{
|
|
public string SourceNodeId { get; }
|
|
public List<AlarmEventArgs> Received { get; } = new();
|
|
public RecordingSink(string sourceNodeId) => SourceNodeId = sourceNodeId;
|
|
public void OnTransition(AlarmEventArgs args) => Received.Add(args);
|
|
}
|
|
}
|
|
}
|