Files
ScadaBridge/tests/ZB.MOM.WW.ScadaBridge.Host.Tests/ScadaBridgeTelemetryTests.cs
T
Joseph Doherty 513fa1aa16 docs(tests): fix CommentChecker findings across tests/ — 13,392 → 0 (repo-wide scan clean)
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.
2026-10-07 15:05:49 -04:00

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>() =&gt; 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);
}
}
}