From 62556c245a376853814951854fb75969559db399 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Wed, 8 Jul 2026 21:38:14 -0400 Subject: [PATCH] test(archreview #10): cover actor-context preservation through the REAL CapabilityInvoker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pass-through NullDriverCapabilityInvoker returns the call-site task directly, so it never exercises the real invoker's internal `pipeline.ExecuteAsync(...).ConfigureAwait(false)`. Adds a test-only Core reference to Runtime.Tests (the PRODUCTION Runtime assembly stays Polly-free via the seam) and a discovery test that drives DriverInstanceActor through a real CapabilityInvoker over a genuinely-yielding ITagDiscovery driver — proving the invoker's internal ConfigureAwait(false) does NOT leak to the actor's own await, so the post-await Context.Parent.Tell still runs (DiscoveredNodesReady arrives). Runtime.Tests 358, Core.Tests 238. --- .../DriverInstanceActorDiscoveryTests.cs | 33 +++++++++++++++++++ .../ZB.MOM.WW.OtOpcUa.Runtime.Tests.csproj | 4 +++ 2 files changed, 37 insertions(+) diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverInstanceActorDiscoveryTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverInstanceActorDiscoveryTests.cs index 7973c920..2e74a13e 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverInstanceActorDiscoveryTests.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverInstanceActorDiscoveryTests.cs @@ -2,6 +2,7 @@ using Akka.Actor; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Core.Abstractions; +using ZB.MOM.WW.OtOpcUa.Core.Resilience; using ZB.MOM.WW.OtOpcUa.Runtime.Drivers; using ZB.MOM.WW.OtOpcUa.Runtime.Tests.Harness; @@ -144,6 +145,38 @@ public sealed class DriverInstanceActorDiscoveryTests : RuntimeActorTestBase published.DriverInstanceId.ShouldBe(driver.DriverInstanceId); } + /// + /// Arch-review #10: the SAME async-discovery context-preservation guarantee, but driven through the + /// REAL — whose Polly pipeline is awaited with + /// ConfigureAwait(false) internally. This is the one path the pass-through + /// NullDriverCapabilityInvoker (used by the sibling test) cannot cover: it returns the + /// call-site task directly, so it never exercises the invoker's internal off-context await. If that + /// internal ConfigureAwait(false) leaked to the actor's own await _invoker.ExecuteAsync(…), + /// the post-await Context.Parent.Tell in HandleRediscoverAsync would fault with + /// "no active ActorContext" and no message would arrive. Its arrival proves the actor context survives + /// the real resilience pipeline. + /// + [Fact] + public void Async_discovery_through_real_CapabilityInvoker_preserves_actor_context() + { + var pipelineBuilder = new DriverResiliencePipelineBuilder(); // real Polly pipeline, tier-A defaults + var invoker = new CapabilityInvoker( + pipelineBuilder, + driverInstanceId: "yielding-discoverable", + optionsAccessor: () => new DriverResilienceOptions { Tier = DriverTier.A }, + driverType: "Stub"); + var driver = new YieldingDiscoverableStubDriver(); + var parent = CreateTestProbe(); + var actor = parent.ChildActorOf(DriverInstanceActor.Props( + driver, rediscoverInterval: TimeSpan.FromMilliseconds(20), invoker: invoker)); + + actor.Tell(new DriverInstanceActor.InitializeRequested("{}")); + + var published = parent.ExpectMsg(TimeSpan.FromSeconds(5)); + published.Nodes.Count.ShouldBe(3); + published.DriverInstanceId.ShouldBe(driver.DriverInstanceId); + } + /// /// The attempt cap bounds a discovered set that never stabilises: a driver whose set keeps GROWING /// (1,2,3,…) never repeats its signature, so the loop is stopped only by diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/ZB.MOM.WW.OtOpcUa.Runtime.Tests.csproj b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/ZB.MOM.WW.OtOpcUa.Runtime.Tests.csproj index 5c48ed9b..14f0e0b2 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/ZB.MOM.WW.OtOpcUa.Runtime.Tests.csproj +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/ZB.MOM.WW.OtOpcUa.Runtime.Tests.csproj @@ -22,6 +22,10 @@ + +