107 lines
3.8 KiB
C#
107 lines
3.8 KiB
C#
using System.Diagnostics.Metrics;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Observability;
|
|
|
|
namespace ZB.MOM.WW.ScadaBridge.Communication.Tests;
|
|
|
|
/// <summary>
|
|
/// Telemetry guards for the aggregated live alarm cache (plan #10, Task 6): the
|
|
/// active-aggregator observable gauge reflects Started/Stopped, and the reconnect
|
|
/// counter increments on each recorded reconnect. Mirrors the MeterListener read
|
|
/// pattern used by <c>SiteStreamGrpcServerTests.SiteStreamSubscribersActiveGauge_*</c>; reads are
|
|
/// relative to a baseline so the process-wide static instruments are robust to any
|
|
/// parallel test interleaving.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Register row 102's shape: a fixed-baseline delta only survives contributors that hold
|
|
/// constant or increase — a parallel class's actors moving the SAME process-global gauge
|
|
/// and then STOPPING after this test captures its baseline makes <c>baseline + N</c>
|
|
/// unreachable forever. <see cref="SiteAlarmAggregatorActor"/> calls
|
|
/// <see cref="ScadaBridgeTelemetry.LiveAlarmAggregatorStarted"/>/
|
|
/// <see cref="ScadaBridgeTelemetry.LiveAlarmAggregatorStopped"/> from its own
|
|
/// PreStart/PostStop, so every actor <c>Grpc.SiteAlarmAggregatorActorTests</c> spins up
|
|
/// moves this exact gauge — serialized into the same collection (row-96 pattern) so the
|
|
/// two classes never interleave.
|
|
/// </remarks>
|
|
[Collection("SiteAlarmAggregatorGauge")]
|
|
public class SiteAlarmLiveCacheTelemetryTests
|
|
{
|
|
private static long ReadGauge(string instrumentName)
|
|
{
|
|
long observed = 0;
|
|
using var listener = new MeterListener();
|
|
listener.InstrumentPublished = (instrument, l) =>
|
|
{
|
|
if (instrument.Meter.Name == ScadaBridgeTelemetry.MeterName &&
|
|
instrument.Name == instrumentName)
|
|
{
|
|
l.EnableMeasurementEvents(instrument);
|
|
}
|
|
};
|
|
listener.SetMeasurementEventCallback<long>((_, measurement, _, _) => observed = measurement);
|
|
listener.Start();
|
|
listener.RecordObservableInstruments();
|
|
return observed;
|
|
}
|
|
|
|
private static long ReadCounter(string instrumentName, Action act)
|
|
{
|
|
long delta = 0;
|
|
using var listener = new MeterListener();
|
|
listener.InstrumentPublished = (instrument, l) =>
|
|
{
|
|
if (instrument.Meter.Name == ScadaBridgeTelemetry.MeterName &&
|
|
instrument.Name == instrumentName)
|
|
{
|
|
l.EnableMeasurementEvents(instrument);
|
|
}
|
|
};
|
|
listener.SetMeasurementEventCallback<long>((_, measurement, _, _) => delta += measurement);
|
|
listener.Start();
|
|
act();
|
|
return delta;
|
|
}
|
|
|
|
[Fact]
|
|
public void ActiveAggregatorGauge_ReflectsStartAndStop()
|
|
{
|
|
const string gauge = "scadabridge.site.alarm_cache.aggregators.active";
|
|
var baseline = ReadGauge(gauge);
|
|
|
|
ScadaBridgeTelemetry.LiveAlarmAggregatorStarted();
|
|
try
|
|
{
|
|
Assert.Equal(baseline + 1, ReadGauge(gauge));
|
|
|
|
ScadaBridgeTelemetry.LiveAlarmAggregatorStarted();
|
|
try
|
|
{
|
|
Assert.Equal(baseline + 2, ReadGauge(gauge));
|
|
}
|
|
finally
|
|
{
|
|
ScadaBridgeTelemetry.LiveAlarmAggregatorStopped();
|
|
}
|
|
|
|
Assert.Equal(baseline + 1, ReadGauge(gauge));
|
|
}
|
|
finally
|
|
{
|
|
ScadaBridgeTelemetry.LiveAlarmAggregatorStopped();
|
|
}
|
|
|
|
Assert.Equal(baseline, ReadGauge(gauge));
|
|
}
|
|
|
|
[Fact]
|
|
public void ReconnectCounter_IncrementsOnEachRecordedReconnect()
|
|
{
|
|
var delta = ReadCounter("scadabridge.site.alarm_cache.reconnects", () =>
|
|
{
|
|
ScadaBridgeTelemetry.RecordLiveAlarmStreamReconnect();
|
|
ScadaBridgeTelemetry.RecordLiveAlarmStreamReconnect();
|
|
});
|
|
|
|
Assert.Equal(2, delta);
|
|
}
|
|
}
|