using System.Diagnostics.Metrics;
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Commons.Observability;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using ZB.MOM.WW.OtOpcUa.Runtime.Historian;
namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.Historian;
///
/// The otopcua.historian.outbox.unreadable gauge reports the bound outbox's
/// . The listener is filtered by the instrument INSTANCE (the
/// shared object plus the instrument name), never by meter name alone, so a
/// parallel test's measurements on another meter of the same name cannot reach it; and the bound outbox reports a
/// distinctive count, so the asserted value can only have come from this test's outbox.
///
public sealed class ContinuousHistorizationMetricsTests
{
private const string GaugeName = "otopcua.historian.outbox.unreadable";
[Fact]
public void The_unreadable_gauge_reports_the_bound_outboxs_unreadable_count()
{
const long distinctive = 7_331_919L;
ContinuousHistorizationMetrics.BindOutbox(new UnreadableOutbox(distinctive));
var observed = new List();
using var listener = new MeterListener
{
InstrumentPublished = (instrument, l) =>
{
if (ReferenceEquals(instrument.Meter, OtOpcUaTelemetry.Meter) && instrument.Name == GaugeName)
l.EnableMeasurementEvents(instrument);
},
};
listener.SetMeasurementEventCallback((instrument, value, _, _) =>
{
if (instrument.Name == GaugeName) observed.Add(value);
});
listener.Start();
listener.RecordObservableInstruments();
observed.ShouldBe([distinctive]);
}
private sealed class UnreadableOutbox(long unreadable) : IHistorizationOutbox
{
public long DroppedCount => 0;
public long UnreadableCount => unreadable;
public ValueTask AppendAsync(HistorizationOutboxEntry entry, CancellationToken ct) => ValueTask.CompletedTask;
public ValueTask AppendBatchAsync(IReadOnlyList entries, CancellationToken ct) => ValueTask.CompletedTask;
public ValueTask> PeekBatchAsync(int max, CancellationToken ct) =>
ValueTask.FromResult>([]);
public ValueTask RemoveAsync(Guid id, CancellationToken ct) => ValueTask.CompletedTask;
public ValueTask CountAsync(CancellationToken ct) => ValueTask.FromResult(0);
public void Dispose() { }
}
}