Replace direct SQL queries against Historian Runtime database with the Wonderware Historian managed SDK (ArchestrA.HistorianAccess). Add HistoryServerCapabilities node, AggregateFunctions folder, continuation points, ReadAtTime interpolation, ReturnBounds, ReadModified rejection, HistoricalDataConfiguration per node, historical event access, and client-side StandardDeviation aggregate support. Remove screenshot tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
117 lines
3.2 KiB
C#
117 lines
3.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Opc.Ua;
|
|
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.LmxOpcUa.Host.Historian;
|
|
|
|
namespace ZB.MOM.WW.LmxOpcUa.Tests.Historian
|
|
{
|
|
public class HistoryContinuationPointTests
|
|
{
|
|
private static List<DataValue> CreateTestValues(int count)
|
|
{
|
|
var values = new List<DataValue>();
|
|
for (var i = 0; i < count; i++)
|
|
values.Add(new DataValue
|
|
{
|
|
Value = new Variant((double)i),
|
|
SourceTimestamp = DateTime.UtcNow.AddSeconds(i),
|
|
StatusCode = StatusCodes.Good
|
|
});
|
|
return values;
|
|
}
|
|
|
|
[Fact]
|
|
public void Store_ReturnsNonEmptyContinuationPoint()
|
|
{
|
|
var mgr = new HistoryContinuationPointManager();
|
|
var values = CreateTestValues(5);
|
|
|
|
var cp = mgr.Store(values);
|
|
|
|
cp.ShouldNotBeNull();
|
|
cp.Length.ShouldBe(16); // GUID = 16 bytes
|
|
}
|
|
|
|
[Fact]
|
|
public void Retrieve_ValidContinuationPoint_ReturnsStoredValues()
|
|
{
|
|
var mgr = new HistoryContinuationPointManager();
|
|
var values = CreateTestValues(5);
|
|
var cp = mgr.Store(values);
|
|
|
|
var retrieved = mgr.Retrieve(cp);
|
|
|
|
retrieved.ShouldNotBeNull();
|
|
retrieved!.Count.ShouldBe(5);
|
|
}
|
|
|
|
[Fact]
|
|
public void Retrieve_SameContinuationPointTwice_ReturnsNullSecondTime()
|
|
{
|
|
var mgr = new HistoryContinuationPointManager();
|
|
var values = CreateTestValues(3);
|
|
var cp = mgr.Store(values);
|
|
|
|
mgr.Retrieve(cp).ShouldNotBeNull();
|
|
mgr.Retrieve(cp).ShouldBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void Retrieve_InvalidBytes_ReturnsNull()
|
|
{
|
|
var mgr = new HistoryContinuationPointManager();
|
|
|
|
mgr.Retrieve(new byte[] { 1, 2, 3 }).ShouldBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void Retrieve_NullBytes_ReturnsNull()
|
|
{
|
|
var mgr = new HistoryContinuationPointManager();
|
|
|
|
mgr.Retrieve(null!).ShouldBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void Retrieve_UnknownGuid_ReturnsNull()
|
|
{
|
|
var mgr = new HistoryContinuationPointManager();
|
|
|
|
mgr.Retrieve(Guid.NewGuid().ToByteArray()).ShouldBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void Release_RemovesContinuationPoint()
|
|
{
|
|
var mgr = new HistoryContinuationPointManager();
|
|
var values = CreateTestValues(5);
|
|
var cp = mgr.Store(values);
|
|
|
|
mgr.Release(cp);
|
|
|
|
mgr.Retrieve(cp).ShouldBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void MultipleContinuationPoints_IndependentRetrieval()
|
|
{
|
|
var mgr = new HistoryContinuationPointManager();
|
|
var values1 = CreateTestValues(3);
|
|
var values2 = CreateTestValues(7);
|
|
|
|
var cp1 = mgr.Store(values1);
|
|
var cp2 = mgr.Store(values2);
|
|
|
|
var r1 = mgr.Retrieve(cp1);
|
|
var r2 = mgr.Retrieve(cp2);
|
|
|
|
r1.ShouldNotBeNull();
|
|
r1!.Count.ShouldBe(3);
|
|
r2.ShouldNotBeNull();
|
|
r2!.Count.ShouldBe(7);
|
|
}
|
|
}
|
|
}
|