From 52d1373e8129b7f4f0ea2e35f86a8a5d0ed1de36 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 10 Nov 2026 15:20:15 -0500 Subject: [PATCH] test(runtime): await rebuild outcomes before asserting no-op --- .../OpcUa/OpcUaPublishActorRebuildTests.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/OpcUa/OpcUaPublishActorRebuildTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/OpcUa/OpcUaPublishActorRebuildTests.cs index 518ae662..d2d3ff80 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/OpcUa/OpcUaPublishActorRebuildTests.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/OpcUa/OpcUaPublishActorRebuildTests.cs @@ -131,13 +131,24 @@ public sealed class OpcUaPublishActorRebuildTests : RuntimeActorTestBase var actor = Sys.ActorOf(OpcUaPublishActor.PropsForTests( sink: sink, dbFactory: db, applier: applier)); - actor.Tell(Rebuild(dep)); - AwaitAssert(() => sink.Calls.ShouldContain("EF:eq-1"), duration: PresenceBudget, cancellationToken: TestContext.Current.CancellationToken); + // EF is recorded before the first apply's NodeAdded announcement. Wait for each reply so + // the snapshot includes every first-apply call and the second apply has actually finished. + var first = Rebuild(dep) with { ReportOutcome = true }; + actor.Tell(first); + var firstCompleted = ExpectMsg(PresenceBudget, + cancellationToken: TestContext.Current.CancellationToken); + firstCompleted.Correlation.ShouldBe(first.Correlation); + firstCompleted.Degraded.ShouldBeFalse(); + sink.Calls.ShouldContain("EF:eq-1"); sink.RebuildCalls.ShouldBe(0); // PureAdd — no full rebuild var callsAfterFirst = sink.Calls.Count; - actor.Tell(Rebuild(dep)); - Thread.Sleep(200); + var second = Rebuild(dep) with { ReportOutcome = true }; + actor.Tell(second); + var secondCompleted = ExpectMsg(PresenceBudget, + cancellationToken: TestContext.Current.CancellationToken); + secondCompleted.Correlation.ShouldBe(second.Correlation); + secondCompleted.Degraded.ShouldBeFalse(); // Same composition ⇒ plan IsEmpty ⇒ applier + materialise passes not run again. sink.Calls.Count.ShouldBe(callsAfterFirst); sink.RebuildCalls.ShouldBe(0);