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.6 KiB
C#
70 lines
2.6 KiB
C#
using ZB.MOM.WW.OtOpcUa.Driver.Historian.Conformance;
|
|
using Xunit;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb.IntegrationTests;
|
|
|
|
// One concrete subclass per conformance class: the suite's tests run here against QuestDB.
|
|
|
|
[Collection(QuestDbCollection.Name)]
|
|
public sealed class QuestDbRawReadConformance(QuestDbFixture fx) : RawReadConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => QuestDbConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(QuestDbCollection.Name)]
|
|
public sealed class QuestDbAtTimeConformance(QuestDbFixture fx) : AtTimeConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => QuestDbConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(QuestDbCollection.Name)]
|
|
public sealed class QuestDbProcessedConformance(QuestDbFixture fx) : ProcessedConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => QuestDbConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(QuestDbCollection.Name)]
|
|
public sealed class QuestDbQualityContractConformance(QuestDbFixture fx) : QualityContractConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => QuestDbConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(QuestDbCollection.Name)]
|
|
public sealed class QuestDbLiveWriteConformance(QuestDbFixture fx) : LiveWriteConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => QuestDbConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(QuestDbCollection.Name)]
|
|
public sealed class QuestDbUpdateConformance(QuestDbFixture fx) : UpdateConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => QuestDbConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(QuestDbCollection.Name)]
|
|
public sealed class QuestDbTagNameConformance(QuestDbFixture fx) : TagNameConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => QuestDbConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(QuestDbCollection.Name)]
|
|
public sealed class QuestDbModifiedValueConformance(QuestDbFixture fx) : ModifiedValueConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => QuestDbConformanceBackend.CreateAsync(fx);
|
|
}
|
|
|
|
[Collection(QuestDbCollection.Name)]
|
|
public sealed class QuestDbEventReadConformance(QuestDbFixture fx) : EventReadConformance
|
|
{
|
|
/// <inheritdoc/>
|
|
protected override Task<IConformanceBackend> CreateBackendAsync() => QuestDbConformanceBackend.CreateAsync(fx);
|
|
}
|