test(dcl): de-race MxGateway Unsubscribe stops-routing under load (#288)
This commit is contained in:
+17
-1
@@ -5,6 +5,12 @@ using ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Adapters;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests.Adapters;
|
||||
|
||||
// Non-parallel with the rest of the DataConnectionManagerActor collection: these adapter
|
||||
// tests pump a fire-and-forget event loop (ConnectAsync → Task.Run(RunEventLoopAsync)) whose
|
||||
// thread-pool continuation must run before the WaitUntil attach-barrier observes
|
||||
// fake.OnUpdate. Serializing within the assembly trims in-assembly thread-pool contention so
|
||||
// that barrier (and the negative Unsubscribe assertion that follows it) is not starved.
|
||||
[Collection("DataConnectionManagerActor")]
|
||||
public class MxGatewayDataConnectionTests
|
||||
{
|
||||
private static MxGatewayDataConnection NewAdapter(FakeMxGatewayClient fake) =>
|
||||
@@ -249,7 +255,17 @@ public class MxGatewayDataConnectionTests
|
||||
() => adapter.BrowseChildrenAsync(null));
|
||||
}
|
||||
|
||||
private static async Task WaitUntil(Func<bool> condition, int timeoutMs = 2000)
|
||||
// Generous ceiling (30 s, matching the DataConnectionManagerActorCollection rationale):
|
||||
// every caller polls a *monotonic, positive* barrier — fake.OnUpdate becoming non-null
|
||||
// (the fire-and-forget event-loop task has attached) or a Disconnected count reaching its
|
||||
// target. Both only ever transition once and never reset, so a longer ceiling merely
|
||||
// tolerates thread-pool starvation under full-solution CPU oversubscription; it cannot
|
||||
// produce a false pass. In Unsubscribe_stops_routing_updates this barrier establishes the
|
||||
// happens-before that the loop is attached BEFORE the test removes the subscription; the
|
||||
// negative assertion (hits == 0) runs afterwards and is independent of this timeout —
|
||||
// the update is delivered synchronously by the test thread, so widening here neither
|
||||
// weakens nor races the negative check.
|
||||
private static async Task WaitUntil(Func<bool> condition, int timeoutMs = 30_000)
|
||||
{
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
while (!condition() && sw.ElapsedMilliseconds < timeoutMs)
|
||||
|
||||
Reference in New Issue
Block a user