test(otopcua): Once re-discovery reruns one pass per reconnect + comment tidy (follow-up B)
This commit is contained in:
@@ -805,10 +805,11 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
|
||||
Context.Parent.Tell(new DiscoveredNodesReady(_driverInstanceId, nodes));
|
||||
|
||||
// Honour the driver's re-discovery policy. A Once driver discovers synchronously in its single
|
||||
// DiscoverAsync, so a single published pass is complete — do not schedule another tick. (Never never
|
||||
// reaches here — StartDiscovery returns before the first tick.) UntilStable falls through to the
|
||||
// stop-on-stable + attempt-cap logic below.
|
||||
// Honour the driver's re-discovery policy. A Once driver runs a single post-connect pass per
|
||||
// (re)connect regardless of whether DiscoverAsync is synchronous or async — one published pass is
|
||||
// complete, so the retry loop is skipped (no further tick scheduled). (Never never reaches here —
|
||||
// StartDiscovery returns before the first tick.) UntilStable falls through to the stop-on-stable +
|
||||
// attempt-cap logic below.
|
||||
if (discovery.RediscoverPolicy == DiscoveryRediscoverPolicy.Once)
|
||||
{
|
||||
_log.Debug("DriverInstance {Id}: RediscoverPolicy=Once — single discovery pass, not scheduling another", _driverInstanceId);
|
||||
|
||||
+45
@@ -221,6 +221,51 @@ public sealed class DriverInstanceActorDiscoveryTests : RuntimeActorTestBase
|
||||
driver.DiscoverCount.ShouldBe(1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="DiscoveryRediscoverPolicy.Once"/> means one pass PER (re)connect cycle — not one pass
|
||||
/// ever. After the initial single pass settles, a <see cref="DriverInstanceActor.ForceReconnect"/>
|
||||
/// drives the actor through Reconnecting and back to Connected (via the auto retry-connect timer), and
|
||||
/// <c>StartDiscovery</c> re-kicks discovery — which must run EXACTLY ONE more pass, not the full attempt
|
||||
/// cap. Uses the ever-growing fake with a small cap (3): under a (wrong) policy-ignoring loop the
|
||||
/// never-stabilising set would publish 3 passes per connect, so a single post-reconnect pass proves
|
||||
/// <c>Once</c> is honoured on the reconnect path too. Guards the exact StartDiscovery-on-reconnect path
|
||||
/// the follow-on TriggerRediscovery task touches.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Discovery_policy_Once_reruns_one_pass_on_reconnect()
|
||||
{
|
||||
var driver = new GrowingDiscoverableStubDriver(DiscoveryRediscoverPolicy.Once);
|
||||
var parent = CreateTestProbe();
|
||||
// Small reconnect + rediscover intervals so the cycle runs fast; cap 3 so a (wrong) full loop is
|
||||
// visibly more than the one pass Once must run per (re)connect.
|
||||
var actor = parent.ChildActorOf(DriverInstanceActor.Props(
|
||||
driver,
|
||||
reconnectInterval: TimeSpan.FromMilliseconds(50),
|
||||
rediscoverInterval: TimeSpan.FromMilliseconds(20),
|
||||
rediscoverMaxAttempts: 3));
|
||||
|
||||
actor.Tell(new DriverInstanceActor.InitializeRequested("{}"));
|
||||
|
||||
// Initial connect: Once ⇒ exactly one pass (growing set → 1 node), then no more.
|
||||
var first = parent.ExpectMsg<DriverInstanceActor.DiscoveredNodesReady>(TimeSpan.FromSeconds(2));
|
||||
first.Nodes.Count.ShouldBe(1);
|
||||
parent.ExpectNoMsg(TimeSpan.FromMilliseconds(200));
|
||||
driver.DiscoverCount.ShouldBe(1);
|
||||
|
||||
// Force a reconnect: Connected → Reconnecting → (auto retry-connect) → Connected again.
|
||||
actor.Tell(new DriverInstanceActor.ForceReconnect());
|
||||
|
||||
// Once = one pass PER (re)connect: exactly ONE additional pass after the reconnect, NOT the full cap.
|
||||
// The set keeps growing across the reconnect (same driver instance), so this pass yields 2 nodes.
|
||||
var afterReconnect = parent.ExpectMsg<DriverInstanceActor.DiscoveredNodesReady>(TimeSpan.FromSeconds(3));
|
||||
afterReconnect.Nodes.Count.ShouldBe(2);
|
||||
afterReconnect.DriverInstanceId.ShouldBe(driver.DriverInstanceId);
|
||||
|
||||
// No further passes — Once did NOT run the attempt cap on reconnect; one pass per connect cycle.
|
||||
parent.ExpectNoMsg(TimeSpan.FromMilliseconds(300));
|
||||
driver.DiscoverCount.ShouldBe(2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The per-pass discovery timeout is injectable via <see cref="DriverInstanceActor.Props"/> so tests
|
||||
/// can control it without real-time delays. The default constant must be 30 seconds (behaviour-preserving).
|
||||
|
||||
Reference in New Issue
Block a user