using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Recorder;
using ZB.MOM.WW.OtOpcUa.Runtime.Historian;
namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests;
///
/// Continuous historization on the Gateway backend silently loses what the SQL backends keep — every sample's
/// quality (the gateway stores Good), comms-loss outage markers and non-numeric values — so building the live writer
/// (which only happens when continuous historization is enabled) logs one startup Warning naming the gaps.
///
public sealed class GatewayContinuousHistorizationWarningTests
{
private sealed class CapturingProvider : ILoggerProvider
{
public readonly List<(LogLevel Level, string Message)> Entries = new();
public ILogger CreateLogger(string categoryName) => new L(this);
public void Dispose() { }
private sealed class L(CapturingProvider owner) : ILogger
{
public IDisposable? BeginScope(TState state) where TState : notnull => null;
public bool IsEnabled(LogLevel logLevel) => true;
public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter)
{
lock (owner.Entries) owner.Entries.Add((logLevel, formatter(state, exception)));
}
}
}
[Fact]
public async Task Building_the_gateway_live_writer_warns_once_about_what_the_backend_drops()
{
var capture = new CapturingProvider();
using var sp = new ServiceCollection().AddLogging(b => b.AddProvider(capture)).BuildServiceProvider();
var provider = new GatewayHistorianProvider(
new ServerHistorianOptions { Endpoint = "http://localhost:5222", UseTls = false, ApiKey = "histgw_test_secret" });
var writer = Assert.IsType(provider.CreateValueWriter(sp));
var warning = capture.Entries.Where(e => e.Level == LogLevel.Warning).ShouldHaveSingleItem().Message;
warning.ShouldContain("quality");
warning.ShouldContain("Good");
warning.ShouldContain("outage");
warning.ShouldContain("non-numeric");
warning.ShouldContain("SqlServer");
await writer.DisposeAsync();
// Positive control in the other direction: the read path alone (no continuous historization) does not warn.
capture.Entries.Clear();
await using var ds = (GatewayHistorianDataSource)provider.CreateDataSource(sp);
capture.Entries.ShouldNotContain(e => e.Level == LogLevel.Warning);
}
}