test(communication): close register row 102 — serialize the two gauge-moving classes so the subscribers.active baseline holds

The gauge test polls baseline+1, but the process-global gauge's baseline is
captured once: a parallel class's streams closing after capture lowers the
gauge below baseline+1 forever. Survey confirmed only SiteStreamGrpcServerTests
and CleanupVerificationTests drive the real SubscribeInstance handler that
moves the counter; both now share the SiteStreamSubscriberGauge collection
(row-96 pattern). 4/4 full-suite runs green, durations unchanged.
This commit is contained in:
Joseph Doherty
2026-08-18 09:18:43 -04:00
parent 324ba369d9
commit d3be5f0527
3 changed files with 16 additions and 4 deletions
@@ -11,6 +11,10 @@ namespace ZB.MOM.WW.ScadaBridge.Communication.Tests.Grpc;
/// Verifies that after a gRPC stream is cancelled, the SiteStreamManager
/// subscription is properly cleaned up with no leaked subscriptions.
/// </summary>
// Serialized with SiteStreamGrpcServerTests (register row 102) — this class's real
// SiteStreamGrpcServer streams move the process-global subscribers.active gauge that
// SiteStreamSubscribersActiveGauge_GoesToOneOnConnect_AndBackToZeroOnCancel baselines.
[Collection("SiteStreamSubscriberGauge")]
public class CleanupVerificationTests : TestKit
{
[Fact]
@@ -11,6 +11,12 @@ using ZB.MOM.WW.ScadaBridge.Communication.Grpc;
namespace ZB.MOM.WW.ScadaBridge.Communication.Tests.Grpc;
// Serialized with CleanupVerificationTests (register row 102): these are the only two
// classes whose streams move the process-global scadabridge.site.stream.subscribers.active
// gauge, and the gauge test below captures its baseline ONCE — a parallel class's streams
// CLOSING after that capture makes baseline+1 unreachable (fixed-baseline deltas only
// survive contributors that hold or increase). Same collection ⇒ never concurrent.
[Collection("SiteStreamSubscriberGauge")]
public class SiteStreamGrpcServerTests : TestKit
{
private readonly ISiteStreamSubscriber _subscriber;
@@ -481,9 +487,11 @@ public class SiteStreamGrpcServerTests : TestKit
await WaitForConditionAsync(() => server.ActiveStreamCount == 1);
// While the stream is up the gauge is one above whatever baseline other
// (possibly parallel) tests left behind — read relative so the assertion
// is robust to test interleaving on the process-wide static counter.
// While the stream is up the gauge is one above the captured baseline. The
// relative read alone is NOT enough on a process-wide counter — a parallel
// class's streams closing after the capture lowers the gauge below
// baseline+1 forever (register row 102) — so the classes that move this
// gauge are serialized into the SiteStreamSubscriberGauge collection.
//
// SiteStreamSubscriberOpened() runs AFTER the _activeStreams insertion that
// WaitForConditionAsync(ActiveStreamCount == 1) keys off (see