test(galaxy): isolate process-wide telemetry tests; bounded stream-cancel wait
GalaxyTelemetryTests (ActivityListener) and GatewayGalaxyDataWriterFailClosedTests (MeterListener, filtered only by meter and instrument name) observe every Galaxy span or measurement in the process. They now run in a collection with parallelization disabled (F-FU6), because a parallel driver test, or its background probe seed, polluted their counts. The stream-cancel assertion in GalaxyDriverShutdownTests goes back to a bounded wait: the instantaneous IsCompleted check introduced in round 1 was racy. Refs #735 Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
using Xunit;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Classes that assert on process-wide telemetry (an <c>ActivityListener</c> on the Galaxy
|
||||
/// ActivitySource, a <c>MeterListener</c> on the Galaxy meter) run with parallelization disabled:
|
||||
/// those listeners see every Galaxy span / measurement in the process, so any parallel class that
|
||||
/// drives a traced subscriber or the data writer — including a driver's background probe seed that
|
||||
/// outlives its test — pollutes their counts (F-FU6, observed flaky in lane F fix round 2).
|
||||
/// </summary>
|
||||
[CollectionDefinition(Name, DisableParallelization = true)]
|
||||
public sealed class ProcessWideTelemetryCollection
|
||||
{
|
||||
/// <summary>The collection name.</summary>
|
||||
public const string Name = "Process-wide Galaxy telemetry";
|
||||
}
|
||||
+4
-3
@@ -179,9 +179,10 @@ public sealed class GalaxyDriverShutdownTests
|
||||
|
||||
await driver.ShutdownAsync(CancellationToken.None);
|
||||
|
||||
// No wait: the pump's Cancel runs the stream's registration synchronously and ShutdownAsync
|
||||
// awaited the pump's dispose, so the signal is either already set or the stream was never cancelled.
|
||||
sub.StreamCancelled.Task.IsCompleted.ShouldBeTrue("ShutdownAsync must cancel the StreamEvents stream");
|
||||
// Bounded wait, not an instantaneous IsCompleted check: the pump's dispose does not promise the
|
||||
// enumerator's cancellation registration has run by the time it returns (observed flaky).
|
||||
(await Task.WhenAny(sub.StreamCancelled.Task, Task.Delay(WaitMs))).ShouldBe(sub.StreamCancelled.Task,
|
||||
"ShutdownAsync must cancel the StreamEvents stream");
|
||||
driver.HasEventPumpForTests.ShouldBeFalse();
|
||||
driver.TrackedSubscriptionCountForTests.ShouldBe(0, "handles died with the session; the host re-subscribes after re-init");
|
||||
driver.GetHealth().State.ShouldBe(DriverState.Unknown);
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests.Runtime;
|
||||
/// <see cref="ActivityListener"/> rather than asserting on internal state, so the
|
||||
/// tests double as documentation of the listener-side contract.
|
||||
/// </summary>
|
||||
[Collection(ProcessWideTelemetryCollection.Name)]
|
||||
public sealed class GalaxyTelemetryTests
|
||||
{
|
||||
/// <summary>Subscribes an ActivityListener for the test, captures each spawned activity.</summary>
|
||||
|
||||
+1
@@ -13,6 +13,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests.Runtime;
|
||||
/// of leaving a phantom-Good node. These tests drive the real write pipeline through the internal
|
||||
/// <see cref="IMxWriteOps"/> seam (the SDK session types are sealed + internal-ctor and cannot be faked).
|
||||
/// </summary>
|
||||
[Collection(ProcessWideTelemetryCollection.Name)]
|
||||
public sealed class GatewayGalaxyDataWriterFailClosedTests
|
||||
{
|
||||
private static GatewayGalaxyDataWriter NewWriter()
|
||||
|
||||
Reference in New Issue
Block a user