test(virtual-tags): re-apply until the host has pruned the dead child (lmxopcua#769)
v2-ci / unit-tests (push) Has been cancelled

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
This commit is contained in:
Joseph Doherty
2026-11-09 21:59:35 -05:00
parent 850c5405d0
commit f717735753
@@ -147,9 +147,16 @@ public sealed class VirtualTagHostActorTests : RuntimeActorTestBase
mux.ExpectMsg<DependencyMuxActor.UnregisterInterest>(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<DependencyMuxActor.RegisterInterest>(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<DependencyMuxActor.RegisterInterest>(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;