diff --git a/tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests/DataConnectionManagerActorTests.cs b/tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests/DataConnectionManagerActorTests.cs index 77a47908..093f0ccf 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests/DataConnectionManagerActorTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests/DataConnectionManagerActorTests.cs @@ -76,7 +76,7 @@ public class DataConnectionManagerActorTests : TestKit } [Fact] - public async Task DCL002_ConnectionActorCrash_PreservesSubscriptionState() + public void DCL002_ConnectionActorCrash_PreservesSubscriptionState() { // Regression test for DataConnectionLayer-002. The supervisor used // Directive.Restart, which discards the connection actor's in-memory @@ -103,7 +103,12 @@ public class DataConnectionManagerActorTests : TestKit new DataConnectionManagerActor(_mockFactory, _options, _mockHealthCollector))); manager.Tell(new CreateConnectionCommand("conn1", "OpcUa", new Dictionary(), null, 3)); - await Task.Delay(300); // connection actor reaches Connected + // Wait until the connection actor has called ConnectAsync (i.e. reached Connected) + // rather than sleeping a fixed 300 ms that can expire before the async connect + // completes under CPU contention. + AwaitCondition( + () => mockAdapter.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "ConnectAsync"), + TimeSpan.FromSeconds(5)); // Register a subscription. manager.Tell(new SubscribeTagsRequest("c1", "inst1", "conn1", ["tag1"], DateTimeOffset.UtcNow)); @@ -111,7 +116,13 @@ public class DataConnectionManagerActorTests : TestKit // Crash the connection actor via a synchronously-throwing write. manager.Tell(new WriteTagRequest("c2", "conn1", "tag1", 42, DateTimeOffset.UtcNow)); - await Task.Delay(300); // supervisor handles the failure + // Wait until WriteAsync was invoked, proving the WriteTagRequest was fully + // processed by the connection actor (and the supervisor's Resume directive + // applied) before we query health. A fixed sleep can expire before the + // actor processes the message under CPU load. + AwaitCondition( + () => mockAdapter.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "WriteAsync"), + TimeSpan.FromSeconds(5)); // After the crash the subscription state must survive: the health report // still shows the subscribed/resolved tag. With Restart it would be 0.