8d154c6a81
- IHistorianDataSource.ReadEventsAsync(..., bool reverse, ...) overload: reverse = Part 11 window (lo, hi] newest-first by (time, id) DESC. Default forwards forward reads and throws NotSupportedException for reverse (Null); Gateway refuses explicitly (ascending-only stream). Server answers BadHistoryOperationUnsupported instead of silently returning the earliest N ascending. - SqlServer / QuestDB serve reverse natively (ORDER BY time DESC, id DESC + TOP/LIMIT). - Node manager: reverse event reads page with continuation points; direction stored in the cursor (HistoryContinuationState.Reverse) so a resume continues in the cursor's direction; reverse tie clusters over-fetched forward and sliced from the newest end (SliceTieCluster(reverse:)); end-only reads with a cap page backward from EndTime (mirrors raw). - Resumed event pages over-fetch by the boundary skip, so every non-final page is a full cap page. - Tests: node-manager reverse paging (ties, clusters, coarse resolution, overfetch bound, resume direction both ways, end-only, unsupported backend); shared EventReadConformance on SqlServer + QuestDB; over-the-wire reverse paging; offline Gateway pin of the UTC DateTime.MaxValue bound through the published client's proto conversion (in-process gRPC capture) and FILETIME. - docs/Historian.md event paging section.
70 lines
2.7 KiB
C#
70 lines
2.7 KiB
C#
using ZB.MOM.WW.OtOpcUa.Driver.Historian.Conformance;
|
|
using Xunit;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer.IntegrationTests;
|
|
|
|
// One concrete subclass per conformance class: the suite's tests run here against SQL Server.
|
|
|
|
[Collection(SqlHistorianCollection.Name)]
|
|
public sealed class SqlServerRawReadConformance(SqlHistorianFixture fx) : RawReadConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => SqlServerConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(SqlHistorianCollection.Name)]
|
|
public sealed class SqlServerAtTimeConformance(SqlHistorianFixture fx) : AtTimeConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => SqlServerConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(SqlHistorianCollection.Name)]
|
|
public sealed class SqlServerProcessedConformance(SqlHistorianFixture fx) : ProcessedConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => SqlServerConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(SqlHistorianCollection.Name)]
|
|
public sealed class SqlServerQualityContractConformance(SqlHistorianFixture fx) : QualityContractConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => SqlServerConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(SqlHistorianCollection.Name)]
|
|
public sealed class SqlServerLiveWriteConformance(SqlHistorianFixture fx) : LiveWriteConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => SqlServerConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(SqlHistorianCollection.Name)]
|
|
public sealed class SqlServerUpdateConformance(SqlHistorianFixture fx) : UpdateConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => SqlServerConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(SqlHistorianCollection.Name)]
|
|
public sealed class SqlServerTagNameConformance(SqlHistorianFixture fx) : TagNameConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => SqlServerConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(SqlHistorianCollection.Name)]
|
|
public sealed class SqlServerModifiedValueConformance(SqlHistorianFixture fx) : ModifiedValueConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => SqlServerConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(SqlHistorianCollection.Name)]
|
|
public sealed class SqlServerEventReadConformance(SqlHistorianFixture fx) : EventReadConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => SqlServerConformanceBackend.CreateAsync(fx);
|
|
}
|