513fa1aa16
Comment/XML-doc changes only: - add summaries to ~10k test methods, fixtures, fakes and helpers (+ <param> on theories, <returns> on async Task methods, <inheritdoc/> on interface implementations the checker can resolve) - strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N, #NN, Component-0NN) from comments, keeping the explanatory text; reword false positives in comments only - real docs on fakes implementing BCL/library interfaces (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime) - reword the last 5 src/ false positives (CWE-1236, failures-1, year-0001, M365) Only non-comment edits: four one-line nested classes split across lines so members can carry docs. Build 0 errors / 0 warnings.
77 lines
3.9 KiB
C#
77 lines
3.9 KiB
C#
using ZB.MOM.WW.ScadaBridge.Commons.Observability;
|
|
|
|
namespace ZB.MOM.WW.ScadaBridge.Host.Tests;
|
|
|
|
/// <summary>
|
|
/// Infrastructure-free guards for <see cref="ScadaBridgeTelemetry"/>: the meter name is the
|
|
/// stable value registered with OTel, and the emit helpers are safe to call (they are no-op
|
|
/// until follow-on tasks wire real emit points and a listener attaches).
|
|
/// </summary>
|
|
public class ScadaBridgeTelemetryTests
|
|
{
|
|
/// <summary>Verifies that the meter name is a stable value.</summary>
|
|
/// <returns>The result.</returns>
|
|
[Fact]
|
|
public void MeterName_IsStableValue()
|
|
{
|
|
Assert.Equal("ZB.MOM.WW.ScadaBridge", ScadaBridgeTelemetry.MeterName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register row 32 class: <c>SetQueueDepthProvider</c> writes the SAME process-global
|
|
/// slot <c>QueueDepthGaugeCollection</c> (StoreAndForward.Tests) exists to serialize
|
|
/// access to — this test was mutating it with no clear and no <c>[Collection]</c>,
|
|
/// leaving a stray <c>() => 5</c> provider registered in the process for the rest of
|
|
/// this assembly's run. Since the meter/instrument state is a single static field on
|
|
/// <c>ScadaBridgeTelemetry</c> (Commons), the leak is scoped to whatever process this
|
|
/// assembly's test host runs in — it cannot reach StoreAndForward.Tests (a separate
|
|
/// assembly with its own test-host process), but it IS visible within Host.Tests, whose
|
|
/// <c>MetricsEndpointTests</c> boots a real in-process host (<c>WebApplicationFactory</c>
|
|
/// shares this AppDomain, not a child process) and scrapes <c>/metrics</c>, which
|
|
/// enumerates every registered gauge including this one.
|
|
///
|
|
/// Honesty note on what was and wasn't proven: a search of this assembly (and the whole
|
|
/// test tree) found no test today that asserts on the VALUE of
|
|
/// <c>scadabridge.store_and_forward.queue.depth</c> from Host.Tests or any other
|
|
/// same-process reader — <c>MetricsEndpointTests</c> only asserts the endpoint returns
|
|
/// Prometheus-shaped text, not this series' content, and the only test that DOES assert
|
|
/// on the value (<c>QueueDepthGaugeTests</c>) lives in StoreAndForward.Tests, a distinct
|
|
/// test-host process the leak cannot reach. So there is no currently-reproducible flake
|
|
/// to demonstrate here (no fork of this test with the leak left in has an assertion to
|
|
/// break) — the defect is a landmine for a FUTURE same-process reader, not a live one.
|
|
/// The fix (compare-and-clear in <c>finally</c>) closes the landmine regardless; a
|
|
/// <c>[Collection]</c> is intentionally not added since no second same-process reader of
|
|
/// this slot exists to serialize against as of this writing — re-run this search before
|
|
/// removing the guard below if that changes.
|
|
/// </summary>
|
|
[Fact]
|
|
public void EmitHelpers_DoNotThrow()
|
|
{
|
|
Func<long> queueDepthProvider = () => 5;
|
|
var ex = Record.Exception(() =>
|
|
{
|
|
ScadaBridgeTelemetry.RecordDeploymentApplied();
|
|
ScadaBridgeTelemetry.RecordInboundApiRequest("X");
|
|
ScadaBridgeTelemetry.SiteStreamSubscriberOpened();
|
|
ScadaBridgeTelemetry.SiteStreamSubscriberClosed();
|
|
ScadaBridgeTelemetry.LiveAlarmAggregatorStarted();
|
|
ScadaBridgeTelemetry.LiveAlarmAggregatorStopped();
|
|
ScadaBridgeTelemetry.RecordLiveAlarmStreamReconnect();
|
|
ScadaBridgeTelemetry.SetQueueDepthProvider(queueDepthProvider);
|
|
});
|
|
|
|
try
|
|
{
|
|
Assert.Null(ex);
|
|
}
|
|
finally
|
|
{
|
|
// Compare-and-clear: only removes OUR delegate from the process-global slot, so
|
|
// a legitimate concurrent registrant (a real StoreAndForwardService started
|
|
// elsewhere in this process) is never stomped — mirrors
|
|
// ScadaBridgeTelemetry.ClearQueueDepthProvider's own doc'd contract.
|
|
ScadaBridgeTelemetry.ClearQueueDepthProvider(queueDepthProvider);
|
|
}
|
|
}
|
|
}
|