From 0414a0489297ba2ac3429f51b1c69d045c375bac Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 18 Jun 2026 09:18:37 -0400 Subject: [PATCH] =?UTF-8?q?test(adminui):=20review=20fixes=20=E2=80=94=20l?= =?UTF-8?q?ocked-snapshot=20assert,=20stable=20fake=20health,=20Initialize?= =?UTF-8?q?Count=20property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DriverReconnectE2eTests.cs | 4 +++- .../Fakes/FakeReconnectDriverFactory.cs | 13 ++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests/DriverReconnectE2eTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests/DriverReconnectE2eTests.cs index 0eba864a..ca9abb80 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests/DriverReconnectE2eTests.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests/DriverReconnectE2eTests.cs @@ -172,7 +172,7 @@ public sealed class DriverReconnectE2eTests List snapshot; lock (captureLock) snapshot = captured.Where(c => c.DriverInstanceId == DriverId).ToList(); - HasReconnectThenHealthy(captured).ShouldBeTrue( + HasReconnectThenHealthy(snapshot).ShouldBeTrue( "Expected a Reconnecting push followed by a later Healthy push for the deployed driver. " + $"States seen: [{string.Join(", ", snapshot.Select(c => c.State))}]"); @@ -254,6 +254,8 @@ public sealed class DriverReconnectE2eTests await db.SaveChangesAsync(Ct); } + /// Polls every 100 ms until it returns true or + /// elapses (then throws ). private static async Task WaitForAsync(Func> condition, TimeSpan timeout) { var deadline = DateTime.UtcNow + timeout; diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests/Fakes/FakeReconnectDriverFactory.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests/Fakes/FakeReconnectDriverFactory.cs index bad9995f..ceec98f6 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests/Fakes/FakeReconnectDriverFactory.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests/Fakes/FakeReconnectDriverFactory.cs @@ -96,13 +96,16 @@ public sealed class FakeReconnectDriver : IDriver /// Timestamp of the most recent successful initialize; surfaced as the last successful read. private DateTime _lastSuccess = DateTime.UtcNow; + /// Backing field for ; mutated via . + private int _initializeCount; + /// /// Number of times has been invoked. Read by the test to prove a /// reconnect genuinely re-initialised the driver through the full cluster path (≥ 2 means the - /// initial connect plus at least one reconnect retry). Mutated via since - /// the actor's retry path runs on a thread-pool thread. + /// initial connect plus at least one reconnect retry). The actor's retry path runs on a thread-pool + /// thread, so the increment is and the read is . /// - public int InitializeCount; + public int InitializeCount => Volatile.Read(ref _initializeCount); /// /// Marks the driver as having lost its connection so the next poll reports @@ -123,7 +126,7 @@ public sealed class FakeReconnectDriver : IDriver /// A completed task — initialization always succeeds. public Task InitializeAsync(string driverConfigJson, CancellationToken cancellationToken) { - Interlocked.Increment(ref InitializeCount); + Interlocked.Increment(ref _initializeCount); _lastSuccess = DateTime.UtcNow; _reconnecting = false; return Task.CompletedTask; @@ -151,7 +154,7 @@ public sealed class FakeReconnectDriver : IDriver /// A reflecting the controllable connection state. public DriverHealth GetHealth() => _reconnecting ? new DriverHealth(DriverState.Reconnecting, _lastSuccess, null) - : new DriverHealth(DriverState.Healthy, DateTime.UtcNow, null); + : new DriverHealth(DriverState.Healthy, _lastSuccess, null); /// Returns a zero memory footprint (the fake holds no driver-attributable caches). /// Always 0.