Extract historian into a runtime-loaded plugin so hosts without the Wonderware SDK can run with Historian.Enabled=false
The aahClientManaged SDK is now isolated in ZB.MOM.WW.LmxOpcUa.Historian.Aveva and loaded via HistorianPluginLoader from a Historian/ subfolder only when enabled, removing the SDK from Host's compile-time and deploy-time surface. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using ArchestrA;
|
||||
using ZB.MOM.WW.LmxOpcUa.Historian.Aveva;
|
||||
using ZB.MOM.WW.LmxOpcUa.Host.Configuration;
|
||||
using ZB.MOM.WW.LmxOpcUa.Host.Historian;
|
||||
|
||||
namespace ZB.MOM.WW.LmxOpcUa.Tests.Helpers
|
||||
namespace ZB.MOM.WW.LmxOpcUa.Historian.Aveva.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Fake Historian connection factory for tests. Controls whether connections
|
||||
@@ -11,20 +11,10 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Helpers
|
||||
/// </summary>
|
||||
internal sealed class FakeHistorianConnectionFactory : IHistorianConnectionFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// When set, <see cref="CreateAndConnect"/> throws this exception.
|
||||
/// </summary>
|
||||
public Exception? ConnectException { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of times <see cref="CreateAndConnect"/> has been called.
|
||||
/// </summary>
|
||||
public int ConnectCallCount { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// When set, called on each <see cref="CreateAndConnect"/> to determine behavior.
|
||||
/// Receives the call count (1-based). Return null to succeed, or throw to fail.
|
||||
/// </summary>
|
||||
public Action<int>? OnConnect { get; set; }
|
||||
|
||||
public HistorianAccess CreateAndConnect(HistorianConfiguration config, HistorianConnectionType type)
|
||||
@@ -1,12 +1,11 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.LmxOpcUa.Historian.Aveva;
|
||||
using ZB.MOM.WW.LmxOpcUa.Host.Configuration;
|
||||
using ZB.MOM.WW.LmxOpcUa.Host.Historian;
|
||||
using ZB.MOM.WW.LmxOpcUa.Tests.Helpers;
|
||||
|
||||
namespace ZB.MOM.WW.LmxOpcUa.Tests.Historian
|
||||
namespace ZB.MOM.WW.LmxOpcUa.Historian.Aveva.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Verifies Historian data source lifecycle behavior: dispose safety,
|
||||
@@ -76,9 +75,9 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Historian
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtractAggregateValue_UnknownColumn_ReturnsNull()
|
||||
public void HistorianAggregateMap_UnknownColumn_ReturnsNull()
|
||||
{
|
||||
HistorianDataSource.MapAggregateToColumn(new Opc.Ua.NodeId(99999)).ShouldBeNull();
|
||||
HistorianAggregateMap.MapAggregateToColumn(new Opc.Ua.NodeId(99999)).ShouldBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -0,0 +1,41 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<RootNamespace>ZB.MOM.WW.LmxOpcUa.Historian.Aveva.Tests</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/>
|
||||
<PackageReference Include="xunit" Version="2.9.3"/>
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Shouldly" Version="4.2.1"/>
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Server" Version="1.5.374.126"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\ZB.MOM.WW.LmxOpcUa.Historian.Aveva\ZB.MOM.WW.LmxOpcUa.Historian.Aveva.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Tests reference aahClientManaged so the FakeHistorianConnectionFactory can
|
||||
implement the SDK-typed IHistorianConnectionFactory interface. -->
|
||||
<Reference Include="aahClientManaged">
|
||||
<HintPath>..\..\lib\aahClientManaged.dll</HintPath>
|
||||
<EmbedInteropTypes>false</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<Reference Include="aahClientCommon">
|
||||
<HintPath>..\..\lib\aahClientCommon.dll</HintPath>
|
||||
<EmbedInteropTypes>false</EmbedInteropTypes>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -5,55 +5,55 @@ using ZB.MOM.WW.LmxOpcUa.Host.Historian;
|
||||
|
||||
namespace ZB.MOM.WW.LmxOpcUa.Tests.Historian
|
||||
{
|
||||
public class HistorianDataSourceTests
|
||||
public class HistorianAggregateMapTests
|
||||
{
|
||||
[Fact]
|
||||
public void MapAggregateToColumn_Average_ReturnsAverage()
|
||||
{
|
||||
HistorianDataSource.MapAggregateToColumn(ObjectIds.AggregateFunction_Average).ShouldBe("Average");
|
||||
HistorianAggregateMap.MapAggregateToColumn(ObjectIds.AggregateFunction_Average).ShouldBe("Average");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapAggregateToColumn_Minimum_ReturnsMinimum()
|
||||
{
|
||||
HistorianDataSource.MapAggregateToColumn(ObjectIds.AggregateFunction_Minimum).ShouldBe("Minimum");
|
||||
HistorianAggregateMap.MapAggregateToColumn(ObjectIds.AggregateFunction_Minimum).ShouldBe("Minimum");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapAggregateToColumn_Maximum_ReturnsMaximum()
|
||||
{
|
||||
HistorianDataSource.MapAggregateToColumn(ObjectIds.AggregateFunction_Maximum).ShouldBe("Maximum");
|
||||
HistorianAggregateMap.MapAggregateToColumn(ObjectIds.AggregateFunction_Maximum).ShouldBe("Maximum");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapAggregateToColumn_Count_ReturnsValueCount()
|
||||
{
|
||||
HistorianDataSource.MapAggregateToColumn(ObjectIds.AggregateFunction_Count).ShouldBe("ValueCount");
|
||||
HistorianAggregateMap.MapAggregateToColumn(ObjectIds.AggregateFunction_Count).ShouldBe("ValueCount");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapAggregateToColumn_Start_ReturnsFirst()
|
||||
{
|
||||
HistorianDataSource.MapAggregateToColumn(ObjectIds.AggregateFunction_Start).ShouldBe("First");
|
||||
HistorianAggregateMap.MapAggregateToColumn(ObjectIds.AggregateFunction_Start).ShouldBe("First");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapAggregateToColumn_End_ReturnsLast()
|
||||
{
|
||||
HistorianDataSource.MapAggregateToColumn(ObjectIds.AggregateFunction_End).ShouldBe("Last");
|
||||
HistorianAggregateMap.MapAggregateToColumn(ObjectIds.AggregateFunction_End).ShouldBe("Last");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapAggregateToColumn_StdDev_ReturnsStdDev()
|
||||
{
|
||||
HistorianDataSource.MapAggregateToColumn(ObjectIds.AggregateFunction_StandardDeviationPopulation)
|
||||
HistorianAggregateMap.MapAggregateToColumn(ObjectIds.AggregateFunction_StandardDeviationPopulation)
|
||||
.ShouldBe("StdDev");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapAggregateToColumn_Unsupported_ReturnsNull()
|
||||
{
|
||||
HistorianDataSource.MapAggregateToColumn(new NodeId(99999)).ShouldBeNull();
|
||||
HistorianAggregateMap.MapAggregateToColumn(new NodeId(99999)).ShouldBeNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,14 +34,6 @@
|
||||
<HintPath>..\..\lib\ArchestrA.MxAccess.dll</HintPath>
|
||||
<EmbedInteropTypes>false</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<Reference Include="aahClientManaged">
|
||||
<HintPath>..\..\lib\aahClientManaged.dll</HintPath>
|
||||
<EmbedInteropTypes>false</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<Reference Include="aahClientCommon">
|
||||
<HintPath>..\..\lib\aahClientCommon.dll</HintPath>
|
||||
<EmbedInteropTypes>false</EmbedInteropTypes>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user