From f717735753c56e57250d28e7a18130bef997caac Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 9 Nov 2026 21:59:35 -0500 Subject: [PATCH] test(virtual-tags): re-apply until the host has pruned the dead child (lmxopcua#769) Child_is_respawned_after_unexpected_termination watched the child die, then re-applied once. The host prunes _children only when its own Terminated arrives, so a re-apply that lands first still sees vt-1 as present, spawns nothing, and the test times out at 15 s (caught 1 in 5 full Runtime.Tests runs on 2026-11-09). Re-apply inside AwaitAssert until the new RegisterInterest arrives; the assertions are unchanged. 30/30 isolated runs pass. Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV --- .../VirtualTags/VirtualTagHostActorTests.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/VirtualTags/VirtualTagHostActorTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/VirtualTags/VirtualTagHostActorTests.cs index 3b759cf70..9b0d669b1 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/VirtualTags/VirtualTagHostActorTests.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/VirtualTags/VirtualTagHostActorTests.cs @@ -147,9 +147,16 @@ public sealed class VirtualTagHostActorTests : RuntimeActorTestBase mux.ExpectMsg(TimeSpan.FromSeconds(5)); // Re-apply with the same plan — host should see vt-1 absent from _children and spawn fresh. - host.Tell(new VirtualTagHostActor.ApplyVirtualTags(plan)); - var reg2 = mux.ExpectMsg(TimeSpan.FromSeconds(5)); - reg2.TagRefs.ShouldContain("a"); + // The test saw the child die, but the host's own Terminated (which prunes _children) can land + // after a single re-apply, which then still sees vt-1 as present and spawns nothing + // (lmxopcua#769: this raced ~1 in 6 full runs). Re-apply until the host has pruned it. + DependencyMuxActor.RegisterInterest? reg2 = null; + AwaitAssert(() => + { + host.Tell(new VirtualTagHostActor.ApplyVirtualTags(plan)); + reg2 = mux.ExpectMsg(TimeSpan.FromMilliseconds(500)); + }, TimeSpan.FromSeconds(10), TimeSpan.FromMilliseconds(50)); + reg2!.TagRefs.ShouldContain("a"); // The new child must be a different actor ref than the one we killed. var secondChild = mux.LastSender;