using Microsoft.Extensions.Logging.Abstractions;
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests;
///
/// Gitea #686: the gateway's ReadRaw streams ascending only and rejects start > end with
/// InvalidArgument, which used to be recorded as a backend health failure. The source declares it cannot read
/// newest-first (so the server walks back with forward reads), and refuses a reverse window itself without sending
/// anything or counting a failure.
///
public sealed class GatewayRawDirectionTests
{
private static CancellationToken Ct => TestContext.Current.CancellationToken;
[Fact]
public void The_gateway_source_declares_it_cannot_read_raw_newest_first()
{
IHistorianDataSource ds = new GatewayHistorianDataSource(
new FakeHistorianGatewayClient(), NullLogger.Instance);
ds.SupportsReverseRaw.ShouldBeFalse();
}
[Fact]
public async Task A_reverse_raw_window_is_refused_unsent_and_is_not_a_backend_failure()
{
var fake = new FakeHistorianGatewayClient();
IHistorianDataSource ds = new GatewayHistorianDataSource(fake, NullLogger.Instance);
var end = new DateTime(2026, 10, 12, 18, 7, 45, DateTimeKind.Utc);
await Should.ThrowAsync(() =>
ds.ReadRawAsync("Gate681", end, new DateTime(0, DateTimeKind.Utc), 3, Ct));
fake.ReadRawCallCount.ShouldBe(0);
var health = ds.GetHealthSnapshot();
health.TotalFailures.ShouldBe(0);
health.ConsecutiveFailures.ShouldBe(0);
// Positive control: a forward read of the same window is sent.
await ds.ReadRawAsync("Gate681", new DateTime(2026, 10, 12, 18, 0, 0, DateTimeKind.Utc), end, 3, Ct);
fake.ReadRawCallCount.ShouldBe(1);
}
}