From b8202e1147cd96d3e83ef646c7ced2d5abc6ba49 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 9 Nov 2026 13:22:34 -0500 Subject: [PATCH] test: remaining xUnit1051/1031/1030, CS8602/8604, CS0618, CS0219, CS0649, NU1510 fixes (lmxopcua#725) Awaited deadline oracles get the runner token; sync-over-async tests made async; nullable child models asserted via ShouldNotBeNull() return values; obsolete SDK ctors replaced with the telemetry overloads; dead locals/fixture and the redundant DI PackageReference removed. No suppressions. Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV --- .../DefaultSubscriptionAdapterTests.cs | 6 ++-- .../OpcUaClientServiceTests.cs | 4 +-- .../MainWindowViewModelTests.cs | 36 +++++++++---------- .../ReadWriteViewModelTests.cs | 2 +- .../ScriptedAlarmEngineTests.cs | 15 ++++---- .../CompiledScriptCacheTests.cs | 17 ++++----- .../FocasLowFindingsTests.cs | 2 +- .../Browse/DeployWatcherTests.cs | 4 +-- .../Health/HostStatusAggregatorTests.cs | 6 ++-- .../Runtime/EventPumpDispatchFaultTests.cs | 4 +-- .../Runtime/EventPumpReplayGapTests.cs | 14 ++++---- .../Runtime/EventPumpStreamFaultTests.cs | 8 ++--- .../Runtime/GalaxyDriverFixRound1Tests.cs | 6 ++-- .../Runtime/GalaxyDriverReadTests.cs | 2 +- .../Runtime/GalaxyDriverShutdownTests.cs | 4 +-- .../Runtime/GatewayGalaxyAlarmFeedTests.cs | 8 ++--- .../ReconnectSupervisorCycleCtsTests.cs | 6 ++-- ...pcUa.Driver.Historian.Gateway.Tests.csproj | 4 +-- .../ModbusDriverProbeParityTests.cs | 2 +- .../ModbusDriverProbeTests.cs | 6 ++-- .../ModbusLifecycleHygieneTests.cs | 4 +-- .../MqttDriverDiscoveryTests.cs | 2 +- ...OpcUaClientBrowseSessionAttributesTests.cs | 2 +- ...OpcUaClientBrowseSessionPaginationTests.cs | 2 +- .../OpcUaClientDriverBrowserTests.cs | 2 +- .../SqlCatalogGateDriverTests.cs | 4 +-- .../TwinCATLowFindingsRegressionTests.cs | 4 +-- 27 files changed, 84 insertions(+), 92 deletions(-) diff --git a/tests/Client/ZB.MOM.WW.OtOpcUa.Client.Shared.Tests/Adapters/DefaultSubscriptionAdapterTests.cs b/tests/Client/ZB.MOM.WW.OtOpcUa.Client.Shared.Tests/Adapters/DefaultSubscriptionAdapterTests.cs index 07980b36..7d728616 100644 --- a/tests/Client/ZB.MOM.WW.OtOpcUa.Client.Shared.Tests/Adapters/DefaultSubscriptionAdapterTests.cs +++ b/tests/Client/ZB.MOM.WW.OtOpcUa.Client.Shared.Tests/Adapters/DefaultSubscriptionAdapterTests.cs @@ -15,7 +15,7 @@ public class DefaultSubscriptionAdapterTests [Fact] public async Task DeleteAsync_detaches_the_subscription_from_its_session_once() { - var subscription = new Subscription(); + var subscription = new Subscription(ClientTelemetry.Context); var detached = new List(); var adapter = new DefaultSubscriptionAdapter(subscription, (s, _) => { @@ -34,7 +34,7 @@ public class DefaultSubscriptionAdapterTests public void Dispose_detaches_the_subscription_from_its_session() { var detached = 0; - var adapter = new DefaultSubscriptionAdapter(new Subscription(), (_, _) => + var adapter = new DefaultSubscriptionAdapter(new Subscription(ClientTelemetry.Context), (_, _) => { Interlocked.Increment(ref detached); return Task.CompletedTask; @@ -49,7 +49,7 @@ public class DefaultSubscriptionAdapterTests [Fact] public async Task A_failing_detach_does_not_throw_from_DeleteAsync() { - var adapter = new DefaultSubscriptionAdapter(new Subscription(), + var adapter = new DefaultSubscriptionAdapter(new Subscription(ClientTelemetry.Context), (_, _) => throw new InvalidOperationException("boom")); await Should.NotThrowAsync(() => adapter.DeleteAsync(TestContext.Current.CancellationToken)); diff --git a/tests/Client/ZB.MOM.WW.OtOpcUa.Client.Shared.Tests/OpcUaClientServiceTests.cs b/tests/Client/ZB.MOM.WW.OtOpcUa.Client.Shared.Tests/OpcUaClientServiceTests.cs index 9c7fb1f6..57794c23 100644 --- a/tests/Client/ZB.MOM.WW.OtOpcUa.Client.Shared.Tests/OpcUaClientServiceTests.cs +++ b/tests/Client/ZB.MOM.WW.OtOpcUa.Client.Shared.Tests/OpcUaClientServiceTests.cs @@ -860,7 +860,6 @@ public class OpcUaClientServiceTests : IDisposable [Fact] public async Task GetRedundancyInfoAsync_MissingOptionalArrays_ReturnsGracefully() { - var readCallIndex = 0; var session = new FakeSessionAdapter { ReadResponseFunc = nodeId => @@ -1554,7 +1553,7 @@ public class OpcUaClientServiceTests : IDisposable { await _service.SubscribeAsync(nodeId); await _service.UnsubscribeAsync(nodeId); - })); + }, TestContext.Current.CancellationToken)); } // No InvalidOperationException from concurrent Dictionary mutation. @@ -1634,7 +1633,6 @@ public class OpcUaClientServiceTests : IDisposable var alarmFakeSub = new FakeSubscriptionAdapter(); // First CreateSubscription call → data subscription; second → alarm subscription. - var callIndex = 0; var session = new FakeSessionAdapter { NextSubscription = dataFakeSub diff --git a/tests/Client/ZB.MOM.WW.OtOpcUa.Client.UI.Tests/MainWindowViewModelTests.cs b/tests/Client/ZB.MOM.WW.OtOpcUa.Client.UI.Tests/MainWindowViewModelTests.cs index dfb02a37..249af3bb 100644 --- a/tests/Client/ZB.MOM.WW.OtOpcUa.Client.UI.Tests/MainWindowViewModelTests.cs +++ b/tests/Client/ZB.MOM.WW.OtOpcUa.Client.UI.Tests/MainWindowViewModelTests.cs @@ -94,7 +94,7 @@ public class MainWindowViewModelTests { await _vm.ConnectCommand.ExecuteAsync(null); - _vm.BrowseTree.RootNodes.Count.ShouldBe(1); + _vm.BrowseTree.ShouldNotBeNull().RootNodes.Count.ShouldBe(1); _vm.BrowseTree.RootNodes[0].DisplayName.ShouldBe("Root"); } @@ -148,7 +148,7 @@ public class MainWindowViewModelTests _vm.SessionLabel.ShouldBe(string.Empty); _vm.RedundancyInfo.ShouldBeNull(); - _vm.BrowseTree.RootNodes.ShouldBeEmpty(); + _vm.BrowseTree.ShouldNotBeNull().RootNodes.ShouldBeEmpty(); _vm.SubscriptionCount.ShouldBe(0); } @@ -176,11 +176,11 @@ public class MainWindowViewModelTests { await _vm.ConnectCommand.ExecuteAsync(null); - var node = _vm.BrowseTree.RootNodes[0]; + var node = _vm.BrowseTree.ShouldNotBeNull().RootNodes[0]; _vm.SelectedTreeNode = node; - _vm.ReadWrite.SelectedNodeId.ShouldBe(node.NodeId); - _vm.History.SelectedNodeId.ShouldBe(node.NodeId); + _vm.ReadWrite.ShouldNotBeNull().SelectedNodeId.ShouldBe(node.NodeId); + _vm.History.ShouldNotBeNull().SelectedNodeId.ShouldBe(node.NodeId); } /// @@ -191,10 +191,10 @@ public class MainWindowViewModelTests { await _vm.ConnectCommand.ExecuteAsync(null); - _vm.ReadWrite.IsConnected.ShouldBeTrue(); - _vm.Subscriptions.IsConnected.ShouldBeTrue(); - _vm.Alarms.IsConnected.ShouldBeTrue(); - _vm.History.IsConnected.ShouldBeTrue(); + _vm.ReadWrite.ShouldNotBeNull().IsConnected.ShouldBeTrue(); + _vm.Subscriptions.ShouldNotBeNull().IsConnected.ShouldBeTrue(); + _vm.Alarms.ShouldNotBeNull().IsConnected.ShouldBeTrue(); + _vm.History.ShouldNotBeNull().IsConnected.ShouldBeTrue(); } /// @@ -206,10 +206,10 @@ public class MainWindowViewModelTests await _vm.ConnectCommand.ExecuteAsync(null); await _vm.DisconnectCommand.ExecuteAsync(null); - _vm.ReadWrite.IsConnected.ShouldBeFalse(); - _vm.Subscriptions.IsConnected.ShouldBeFalse(); - _vm.Alarms.IsConnected.ShouldBeFalse(); - _vm.History.IsConnected.ShouldBeFalse(); + _vm.ReadWrite.ShouldNotBeNull().IsConnected.ShouldBeFalse(); + _vm.Subscriptions.ShouldNotBeNull().IsConnected.ShouldBeFalse(); + _vm.Alarms.ShouldNotBeNull().IsConnected.ShouldBeFalse(); + _vm.History.ShouldNotBeNull().IsConnected.ShouldBeFalse(); } /// @@ -355,7 +355,7 @@ public class MainWindowViewModelTests await _vm.SubscribeSelectedNodesCommand.ExecuteAsync(null); - _vm.Subscriptions.ActiveSubscriptions.ShouldBeEmpty(); + _vm.Subscriptions.ShouldNotBeNull().ActiveSubscriptions.ShouldBeEmpty(); } /// @@ -366,12 +366,12 @@ public class MainWindowViewModelTests { await _vm.ConnectCommand.ExecuteAsync(null); - var node = _vm.BrowseTree.RootNodes[0]; + var node = _vm.BrowseTree.ShouldNotBeNull().RootNodes[0]; _vm.SelectedTreeNodes.Add(node); _vm.ViewHistoryForSelectedNodeCommand.Execute(null); - _vm.History.SelectedNodeId.ShouldBe(node.NodeId); + _vm.History.ShouldNotBeNull().SelectedNodeId.ShouldBe(node.NodeId); _vm.SelectedTabIndex.ShouldBe(3); } @@ -506,7 +506,7 @@ public class MainWindowViewModelTests await _vm.ConnectCommand.ExecuteAsync(null); // Add a subscription - _vm.Subscriptions.IsConnected = true; + _vm.Subscriptions.ShouldNotBeNull().IsConnected = true; await _vm.Subscriptions.AddSubscriptionForNodeAsync("ns=2;s=TestSub"); // Disconnect saves settings including subscriptions @@ -554,7 +554,7 @@ public class MainWindowViewModelTests await vm.ConnectCommand.ExecuteAsync(null); - vm.Subscriptions.ActiveSubscriptions.Count.ShouldBe(2); + vm.Subscriptions.ShouldNotBeNull().ActiveSubscriptions.Count.ShouldBe(2); vm.Subscriptions.ActiveSubscriptions[0].NodeId.ShouldBe("ns=2;s=Restored1"); vm.Subscriptions.ActiveSubscriptions[1].NodeId.ShouldBe("ns=2;s=Restored2"); vm.SubscriptionCount.ShouldBe(2); diff --git a/tests/Client/ZB.MOM.WW.OtOpcUa.Client.UI.Tests/ReadWriteViewModelTests.cs b/tests/Client/ZB.MOM.WW.OtOpcUa.Client.UI.Tests/ReadWriteViewModelTests.cs index 24caa13c..ff46d4e6 100644 --- a/tests/Client/ZB.MOM.WW.OtOpcUa.Client.UI.Tests/ReadWriteViewModelTests.cs +++ b/tests/Client/ZB.MOM.WW.OtOpcUa.Client.UI.Tests/ReadWriteViewModelTests.cs @@ -128,7 +128,7 @@ public class ReadWriteViewModelTests // because auto-read catches the exception too _vm.SelectedNodeId = "ns=2;s=SomeNode"; - _vm.CurrentStatus.ShouldContain("Error"); + _vm.CurrentStatus.ShouldNotBeNull().ShouldContain("Error"); } /// Verifies that clear resets all properties. diff --git a/tests/Core/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.Tests/ScriptedAlarmEngineTests.cs b/tests/Core/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.Tests/ScriptedAlarmEngineTests.cs index d023a8f4..662bdc65 100644 --- a/tests/Core/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.Tests/ScriptedAlarmEngineTests.cs +++ b/tests/Core/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.Tests/ScriptedAlarmEngineTests.cs @@ -739,7 +739,7 @@ public sealed class ScriptedAlarmEngineTests up.Push("Temp", 150); - var winner = await Task.WhenAny(ackDone.Task, Task.Delay(TimeSpan.FromSeconds(3))); + var winner = await Task.WhenAny(ackDone.Task, Task.Delay(TimeSpan.FromSeconds(3), TestContext.Current.CancellationToken)); winner.ShouldBe(ackDone.Task, "subscriber re-entering the engine must not deadlock against _evalGate"); await ackDone.Task; // surface any inner exception @@ -753,7 +753,7 @@ public sealed class ScriptedAlarmEngineTests /// Verifies that OnEvent emission occurs after the evaluation gate is released, so subscribers can re-enter the engine without deadlocking (regression for Core.ScriptedAlarms-003). [Fact] - public void OnEvent_emission_happens_outside_evalGate(/* -003 */) + public async Task OnEvent_emission_happens_outside_evalGate(/* -003 */) { // Direct white-box check on the gate-release ordering: AcknowledgeAsync // emits the Acknowledged event AFTER releasing the gate. We assert that @@ -764,8 +764,8 @@ public sealed class ScriptedAlarmEngineTests var eng = Build(up, out _); try { - eng.LoadAsync([Alarm("HighTemp", """return (int)ctx.GetTag("Temp").Value > 100;""")], - TestContext.Current.CancellationToken).GetAwaiter().GetResult(); + await eng.LoadAsync([Alarm("HighTemp", """return (int)ctx.GetTag("Temp").Value > 100;""")], + TestContext.Current.CancellationToken); // Drive to Active so Acknowledge has something to ack. up.Push("Temp", 150); // Use the same WaitForAsync that other tests use — synchronously @@ -796,8 +796,7 @@ public sealed class ScriptedAlarmEngineTests } }; - eng.AcknowledgeAsync("HighTemp", "alice", null, CancellationToken.None) - .GetAwaiter().GetResult(); + await eng.AcknowledgeAsync("HighTemp", "alice", null, CancellationToken.None); gateFreeInsideEmission.ShouldBeTrue( "_evalGate must be released before OnEvent fires so subscribers " + @@ -844,7 +843,7 @@ public sealed class ScriptedAlarmEngineTests // Verify Dispose does NOT complete immediately — it should block waiting // for the in-flight task. Without the -006 fix Dispose returns straight // away and the background reevaluation can outlive the engine. - var prematureFinish = await Task.WhenAny(disposeTask, Task.Delay(200)); + var prematureFinish = await Task.WhenAny(disposeTask, Task.Delay(200, TestContext.Current.CancellationToken)); prematureFinish.ShouldNotBe(disposeTask, "Dispose must block until in-flight background tasks complete"); @@ -1749,7 +1748,7 @@ public sealed class ScriptedAlarmEngineTests eng.InFlightCountForTest.ShouldBe(1); var disposeTask = Task.Run(() => eng.Dispose(), TestContext.Current.CancellationToken); - var raced = await Task.WhenAny(disposeTask, Task.Delay(300)); + var raced = await Task.WhenAny(disposeTask, Task.Delay(300, TestContext.Current.CancellationToken)); raced.ShouldNotBe(disposeTask, "Dispose must not return while registered background work is still running"); gate.SetResult(); diff --git a/tests/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Tests/CompiledScriptCacheTests.cs b/tests/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Tests/CompiledScriptCacheTests.cs index 3841d6ff..c7c280c1 100644 --- a/tests/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Tests/CompiledScriptCacheTests.cs +++ b/tests/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Tests/CompiledScriptCacheTests.cs @@ -13,11 +13,6 @@ namespace ZB.MOM.WW.OtOpcUa.Core.Scripting.Tests; [Trait("Category", "Unit")] public sealed class CompiledScriptCacheTests { - private sealed class CompileCountingGate - { - public int Count; - } - /// Verifies that the first call to GetOrCompile compiles the script and caches the evaluator. [Fact] public void First_call_compiles_and_caches() @@ -112,7 +107,7 @@ public sealed class CompiledScriptCacheTests /// Verifies that concurrent compiles of the same source deduplicate to a single compilation. [Fact] - public void Concurrent_compiles_of_the_same_source_deduplicate() + public async Task Concurrent_compiles_of_the_same_source_deduplicate() { // LazyThreadSafetyMode.ExecutionAndPublication guarantees only one compile // even when multiple threads race GetOrCompile against an empty cache. @@ -122,13 +117,13 @@ public sealed class CompiledScriptCacheTests const string src = """return 99;"""; var tasks = Enumerable.Range(0, 20) - .Select(_ => Task.Run(() => cache.GetOrCompile(src))) + .Select(_ => Task.Run(() => cache.GetOrCompile(src), TestContext.Current.CancellationToken)) .ToArray(); - Task.WhenAll(tasks).GetAwaiter().GetResult(); + var evaluators = await Task.WhenAll(tasks); - var firstInstance = tasks[0].Result; - foreach (var t in tasks) - ReferenceEquals(t.Result, firstInstance).ShouldBeTrue(); + var firstInstance = evaluators[0]; + foreach (var e in evaluators) + ReferenceEquals(e, firstInstance).ShouldBeTrue(); cache.Count.ShouldBe(1); } diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasLowFindingsTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasLowFindingsTests.cs index 5e09df86..d9565783 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasLowFindingsTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Tests/FocasLowFindingsTests.cs @@ -129,7 +129,7 @@ public sealed class FocasLowFindingsTests // timeout fix, this never completes (Probe runs forever). var cancelled = await Task.WhenAny( hangSignal.Task, - Task.Delay(TimeSpan.FromSeconds(2))) == hangSignal.Task; + Task.Delay(TimeSpan.FromSeconds(2), TestContext.Current.CancellationToken)) == hangSignal.Task; await drv.ShutdownAsync(CancellationToken.None); diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Browse/DeployWatcherTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Browse/DeployWatcherTests.cs index 5728e953..f808bf64 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Browse/DeployWatcherTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Browse/DeployWatcherTests.cs @@ -237,7 +237,7 @@ public sealed class DeployWatcherTests // StopAsync should complete without throwing and within a reasonable window. var stopTask = watcher.StopAsync(); - var completed = await Task.WhenAny(stopTask, Task.Delay(TimeSpan.FromSeconds(5))); + var completed = await Task.WhenAny(stopTask, Task.Delay(TimeSpan.FromSeconds(5), TestContext.Current.CancellationToken)); completed.ShouldBe(stopTask); await stopTask; // observe (no) exception } @@ -256,7 +256,7 @@ public sealed class DeployWatcherTests // Should not throw, should not hang. var disposeTask = Task.Run(watcher.Dispose, TestContext.Current.CancellationToken); - var completed = await Task.WhenAny(disposeTask, Task.Delay(TimeSpan.FromSeconds(5))); + var completed = await Task.WhenAny(disposeTask, Task.Delay(TimeSpan.FromSeconds(5), TestContext.Current.CancellationToken)); completed.ShouldBe(disposeTask); await disposeTask; } diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Health/HostStatusAggregatorTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Health/HostStatusAggregatorTests.cs index 1b6b1610..a67da32b 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Health/HostStatusAggregatorTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Health/HostStatusAggregatorTests.cs @@ -124,7 +124,7 @@ public sealed class HostStatusAggregatorTests /// Verifies that concurrent updates do not corrupt the internal dictionary. [Fact] - public void ConcurrentUpdates_DoNotCorruptDictionary() + public async Task ConcurrentUpdates_DoNotCorruptDictionary() { var agg = new HostStatusAggregator(); const int threadCount = 8; @@ -138,9 +138,9 @@ public sealed class HostStatusAggregatorTests var state = i % 2 == 0 ? HostState.Running : HostState.Stopped; agg.Update(Status(hostName, state)); } - })).ToArray(); + }, TestContext.Current.CancellationToken)).ToArray(); - Task.WaitAll(tasks, TestContext.Current.CancellationToken); + await Task.WhenAll(tasks).WaitAsync(TestContext.Current.CancellationToken); agg.Snapshot().Count.ShouldBeLessThanOrEqualTo(32); } } diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/EventPumpDispatchFaultTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/EventPumpDispatchFaultTests.cs index 8d48d6d5..6c6d3823 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/EventPumpDispatchFaultTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/EventPumpDispatchFaultTests.cs @@ -66,7 +66,7 @@ public sealed class EventPumpDispatchFaultTests await subscriber.EmitAsync(7); - (await Task.WhenAny(fault.Task, Task.Delay(WaitMs))).ShouldBe(fault.Task, + (await Task.WhenAny(fault.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(fault.Task, "a dispatch-loop exit must be reported as a stream fault"); (await fault.Task).ShouldBeOfType(); } @@ -89,7 +89,7 @@ public sealed class EventPumpDispatchFaultTests await subscriber.EmitAsync(7); - (await Task.WhenAny(delivered.Task, Task.Delay(WaitMs))).ShouldBe(delivered.Task); + (await Task.WhenAny(delivered.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(delivered.Task); (await delivered.Task).FullReference.ShouldBe("Tank01.Level"); faulted.ShouldBeFalse(); } diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/EventPumpReplayGapTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/EventPumpReplayGapTests.cs index df76fcc8..e43211c1 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/EventPumpReplayGapTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/EventPumpReplayGapTests.cs @@ -57,7 +57,7 @@ public sealed class EventPumpReplayGapTests await subscriber.EmitAsync(GapSentinel(requestedAfter: 100, oldestAvailable: 250)); - (await Task.WhenAny(observed.Task, Task.Delay(WaitMs))).ShouldBe(observed.Task, + (await Task.WhenAny(observed.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(observed.Task, "a replay-gap sentinel must reach the driver so it can re-snapshot"); var gap = await observed.Task; gap.RequestedAfterSequence.ShouldBe(100UL); @@ -93,7 +93,7 @@ public sealed class EventPumpReplayGapTests pump.Start(); await subscriber.EmitAsync(GapSentinel(requestedAfter: 1, oldestAvailable: 2)); - (await Task.WhenAny(gapSeen.Task, Task.Delay(WaitMs))).ShouldBe(gapSeen.Task); + (await Task.WhenAny(gapSeen.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(gapSeen.Task); // A positive control: follow the sentinel with a real event on the same handle. Without // it, "nothing was dispatched" would also pass on a pump that dispatches nothing at all. @@ -106,7 +106,7 @@ public sealed class EventPumpReplayGapTests SourceTimestamp = Timestamp.FromDateTime(DateTime.UtcNow), }); - (await Task.WhenAny(realValue.Task, Task.Delay(WaitMs))).ShouldBe(realValue.Task, + (await Task.WhenAny(realValue.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(realValue.Task, "the pump must keep dispatching real events after a sentinel"); (await realValue.Task).Snapshot.Value.ShouldBe(12.5); Volatile.Read(ref dispatched).ShouldBe(1, "only the real event may be dispatched, never the sentinel"); @@ -149,7 +149,7 @@ public sealed class EventPumpReplayGapTests await subscriber.EmitAsync(GapSentinel(requestedAfter: 5, oldestAvailable: 900)); - (await Task.WhenAny(observed.Task, Task.Delay(WaitMs))).ShouldBe(observed.Task, + (await Task.WhenAny(observed.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(observed.Task, "the sentinel must not be droppable by channel back-pressure"); (await observed.Task).OldestAvailableSequence.ShouldBe(900UL); @@ -187,7 +187,7 @@ public sealed class EventPumpReplayGapTests Quality = 192, }); - (await Task.WhenAny(resumed.Task, Task.Delay(WaitMs))).ShouldBe(resumed.Task, + (await Task.WhenAny(resumed.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(resumed.Task, "a failed re-snapshot must not stop the stream that is still delivering"); faulted.ShouldBeFalse("a throwing gap callback is not a transport fault"); } @@ -217,7 +217,7 @@ public sealed class EventPumpReplayGapTests subscriber.CompleteStream(); - (await Task.WhenAny(faultObserved.Task, Task.Delay(WaitMs))).ShouldBe(faultObserved.Task, + (await Task.WhenAny(faultObserved.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(faultObserved.Task, "a server-completed stream is as fatal as a faulted one and must reach the supervisor"); (await faultObserved.Task).Message.ShouldContain("closed or evicted"); } @@ -277,7 +277,7 @@ public sealed class EventPumpReplayGapTests SourceTimestamp = Timestamp.FromDateTime(DateTime.UtcNow), }); - (await Task.WhenAny(bothSeen.Task, Task.Delay(WaitMs))).ShouldBe(bothSeen.Task); + (await Task.WhenAny(bothSeen.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(bothSeen.Task); lock (received) { diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/EventPumpStreamFaultTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/EventPumpStreamFaultTests.cs index 9d43ed2d..e976f4d6 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/EventPumpStreamFaultTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/EventPumpStreamFaultTests.cs @@ -35,7 +35,7 @@ public sealed class EventPumpStreamFaultTests // Drop the gw stream — RunAsync's await foreach throws. subscriber.FaultStream(new IOException("simulated gateway transport drop")); - var completed = await Task.WhenAny(faultObserved.Task, Task.Delay(WaitMs)); + var completed = await Task.WhenAny(faultObserved.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken)); completed.ShouldBe(faultObserved.Task, "EventPump must invoke onStreamFault when the gw StreamEvents stream faults"); (await faultObserved.Task).ShouldBeOfType(); @@ -69,9 +69,9 @@ public sealed class EventPumpStreamFaultTests subscriber.FaultStream(new IOException("simulated gateway transport drop")); - (await Task.WhenAny(reopenRan.Task, Task.Delay(WaitMs))).ShouldBe(reopenRan.Task, + (await Task.WhenAny(reopenRan.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(reopenRan.Task, "stream fault must trigger the supervisor's reopen path"); - (await Task.WhenAny(replayRan.Task, Task.Delay(WaitMs))).ShouldBe(replayRan.Task, + (await Task.WhenAny(replayRan.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(replayRan.Task, "stream fault must trigger the supervisor's replay path"); await supervisor.WaitForHealthyAsync(new CancellationTokenSource(WaitMs).Token); @@ -114,7 +114,7 @@ public sealed class EventPumpStreamFaultTests await resubscribed.EmitAsync(itemHandle: 7, value: 123.0); - var completed = await Task.WhenAny(resumed.Task, Task.Delay(WaitMs)); + var completed = await Task.WhenAny(resumed.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken)); completed.ShouldBe(resumed.Task, "a fresh EventPump created after a fault must resume dispatching OnDataChange"); (await resumed.Task).FullReference.ShouldBe("Tank.Level"); diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GalaxyDriverFixRound1Tests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GalaxyDriverFixRound1Tests.cs index c7529e15..a55d79b0 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GalaxyDriverFixRound1Tests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GalaxyDriverFixRound1Tests.cs @@ -251,7 +251,7 @@ public sealed class GalaxyDriverFixRound1Tests await WaitUntilAsync(() => Volatile.Read(ref deploys.Opened) == 1, "the deploy watch must open"); await deploys.PushAsync(1, new DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero)); // bootstrap await deploys.PushAsync(2, new DateTimeOffset(2026, 1, 2, 0, 0, 0, TimeSpan.Zero)); - (await Task.WhenAny(platforms.Entered.Task, Task.Delay(WaitMs))).ShouldBe(platforms.Entered.Task, + (await Task.WhenAny(platforms.Entered.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(platforms.Entered.Task, "the first rediscovery pass must be parked mid-fetch"); await deploys.PushAsync(3, new DateTimeOffset(2026, 1, 3, 0, 0, 0, TimeSpan.Zero)); @@ -308,7 +308,7 @@ public sealed class GalaxyDriverFixRound1Tests var subscribeCallsBefore = sub.SubscribeCalls; try { - (await Task.WhenAny(sub.UnsubscribeEntered.Task, Task.Delay(WaitMs))).ShouldBe(sub.UnsubscribeEntered.Task, + (await Task.WhenAny(sub.UnsubscribeEntered.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(sub.UnsubscribeEntered.Task, "the teardown must be parked inside the probe watcher's unsubscribe"); shutdown.IsCompleted.ShouldBeFalse(); @@ -391,7 +391,7 @@ public sealed class GalaxyDriverFixRound1Tests await driver.SubscribeAsync(["Tank01.Level"], TimeSpan.Zero, CancellationToken.None); var replay = driver.InvokeReplayForTestAsync(CancellationToken.None); - (await Task.WhenAny(sub.SubscribeEntered.Task, Task.Delay(WaitMs))).ShouldBe(sub.SubscribeEntered.Task, + (await Task.WhenAny(sub.SubscribeEntered.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(sub.SubscribeEntered.Task, "the replay must be parked inside its SubscribeBulk"); await driver.ShutdownAsync(CancellationToken.None); diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GalaxyDriverReadTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GalaxyDriverReadTests.cs index 462adfc9..ed536835 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GalaxyDriverReadTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GalaxyDriverReadTests.cs @@ -172,7 +172,7 @@ public sealed class GalaxyDriverReadTests }; var readTask = driver.ReadAsync(["Silent.Tag"], CancellationToken.None); - var finished = await Task.WhenAny(readTask, Task.Delay(TimeSpan.FromSeconds(10))); + var finished = await Task.WhenAny(readTask, Task.Delay(TimeSpan.FromSeconds(10), TestContext.Current.CancellationToken)); finished.ShouldBe(readTask); var result = await readTask; diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GalaxyDriverShutdownTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GalaxyDriverShutdownTests.cs index a2e4b0ef..5c2b9b94 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GalaxyDriverShutdownTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GalaxyDriverShutdownTests.cs @@ -174,14 +174,14 @@ public sealed class GalaxyDriverShutdownTests driver.HasEventPumpForTests.ShouldBeTrue(); await sub.EmitAsync(sub.HandleByRef["Tank01.Level"], 42.0); - (await Task.WhenAny(delivered.Task, Task.Delay(WaitMs))).ShouldBe(delivered.Task, + (await Task.WhenAny(delivered.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(delivered.Task, "positive control: the stream must deliver before the shutdown"); await driver.ShutdownAsync(CancellationToken.None); // Bounded wait, not an instantaneous IsCompleted check: the pump's dispose does not promise the // enumerator's cancellation registration has run by the time it returns (observed flaky). - (await Task.WhenAny(sub.StreamCancelled.Task, Task.Delay(WaitMs))).ShouldBe(sub.StreamCancelled.Task, + (await Task.WhenAny(sub.StreamCancelled.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(sub.StreamCancelled.Task, "ShutdownAsync must cancel the StreamEvents stream"); driver.HasEventPumpForTests.ShouldBeFalse(); driver.TrackedSubscriptionCountForTests.ShouldBe(0, "handles died with the session; the host re-subscribes after re-init"); diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GatewayGalaxyAlarmFeedTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GatewayGalaxyAlarmFeedTests.cs index ab0c2795..fe1fb6cd 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GatewayGalaxyAlarmFeedTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GatewayGalaxyAlarmFeedTests.cs @@ -53,7 +53,7 @@ public sealed class GatewayGalaxyAlarmFeedTests }; feed.Start(); - (await Task.WhenAny(got3.Task, Task.Delay(TimeSpan.FromSeconds(2)))) + (await Task.WhenAny(got3.Task, Task.Delay(TimeSpan.FromSeconds(2), TestContext.Current.CancellationToken))) .ShouldBe(got3.Task, "snapshot + transition should dispatch within 2s"); observed.Count.ShouldBe(3); @@ -109,7 +109,7 @@ public sealed class GatewayGalaxyAlarmFeedTests }; feed.Start(); - (await Task.WhenAny(got2.Task, Task.Delay(TimeSpan.FromSeconds(2)))).ShouldBe(got2.Task); + (await Task.WhenAny(got2.Task, Task.Delay(TimeSpan.FromSeconds(2), TestContext.Current.CancellationToken))).ShouldBe(got2.Task); observed[0].TransitionKind.ShouldBe(GalaxyAlarmTransitionKind.Clear); observed[0].IsRestatement.ShouldBeTrue(); @@ -145,7 +145,7 @@ public sealed class GatewayGalaxyAlarmFeedTests }; feed.Start(); - (await Task.WhenAny(gotOne.Task, Task.Delay(TimeSpan.FromSeconds(2)))) + (await Task.WhenAny(gotOne.Task, Task.Delay(TimeSpan.FromSeconds(2), TestContext.Current.CancellationToken))) .ShouldBe(gotOne.Task); // Only the well-formed Raise survives; the Unspecified + empty messages drop. @@ -187,7 +187,7 @@ public sealed class GatewayGalaxyAlarmFeedTests }; feed.Start(); - (await Task.WhenAny(gotOne.Task, Task.Delay(TimeSpan.FromSeconds(3)))) + (await Task.WhenAny(gotOne.Task, Task.Delay(TimeSpan.FromSeconds(3), TestContext.Current.CancellationToken))) .ShouldBe(gotOne.Task, "the feed should reopen the stream and deliver after a fault"); calls.ShouldBeGreaterThanOrEqualTo(2); diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/ReconnectSupervisorCycleCtsTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/ReconnectSupervisorCycleCtsTests.cs index 4513efa6..0c5b02bf 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/ReconnectSupervisorCycleCtsTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/ReconnectSupervisorCycleCtsTests.cs @@ -47,7 +47,7 @@ public sealed class ReconnectSupervisorCycleCtsTests // Positive control: a cycle parked inside reopen still holds its CTS. Volatile.Write(ref hold[0], true); sup.ReportTransportFailure(new IOException("drop 3")); - (await Task.WhenAny(reopenEntered.Task, Task.Delay(WaitMs))).ShouldBe(reopenEntered.Task); + (await Task.WhenAny(reopenEntered.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(reopenEntered.Task); sup.CyclesStarted.ShouldBe(4); sup.CyclesReleased.ShouldBe(3, "an in-flight cycle's CTS is live until its loop exits"); @@ -71,10 +71,10 @@ public sealed class ReconnectSupervisorCycleCtsTests options: FastBackoff()); sup.ReportTransportFailure(new IOException("drop")); - (await Task.WhenAny(reopenEntered.Task, Task.Delay(WaitMs))).ShouldBe(reopenEntered.Task); + (await Task.WhenAny(reopenEntered.Task, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(reopenEntered.Task); var stop = sup.StopAsync(); - (await Task.WhenAny(stop, Task.Delay(WaitMs))).ShouldBe(stop, "StopAsync must cancel the parked reopen and return"); + (await Task.WhenAny(stop, Task.Delay(WaitMs, TestContext.Current.CancellationToken))).ShouldBe(stop, "StopAsync must cancel the parked reopen and return"); sup.CyclesReleased.ShouldBe(1); await Should.NotThrowAsync(sup.StopAsync); // idempotent Should.NotThrow(sup.Dispose); diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests.csproj b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests.csproj index f5134c16..ae99da77 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests.csproj +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Tests.csproj @@ -13,8 +13,8 @@ - - + diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests/ModbusDriverProbeParityTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests/ModbusDriverProbeParityTests.cs index 552795ba..07071366 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests/ModbusDriverProbeParityTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests/ModbusDriverProbeParityTests.cs @@ -51,6 +51,6 @@ public sealed class ModbusDriverProbeParityTests var (target, error) = ModbusDriverProbe.TryParseProbeTarget( "not valid json {{", fallbackTimeout: TimeSpan.FromSeconds(5)); target.ShouldBeNull(); - error.ShouldContain("invalid"); + error.ShouldNotBeNull().ShouldContain("invalid"); } } diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests/ModbusDriverProbeTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests/ModbusDriverProbeTests.cs index 28b66e84..f0925712 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests/ModbusDriverProbeTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests/ModbusDriverProbeTests.cs @@ -181,7 +181,7 @@ public sealed class ModbusDriverProbeTests var result = await _probe.ProbeAsync(Config(port), QuickTimeout, CancellationToken.None); // The server task should have completed (or close enough). - await serverTask.WaitAsync(TimeSpan.FromSeconds(2), TestContext.Current.CancellationToken).ConfigureAwait(false); + await serverTask.WaitAsync(TimeSpan.FromSeconds(2), TestContext.Current.CancellationToken); result.Ok.ShouldBeFalse(); result.Message.ShouldNotBeNull(); @@ -211,7 +211,7 @@ public sealed class ModbusDriverProbeTests var result = await _probe.ProbeAsync(Config(port), QuickTimeout, CancellationToken.None); - await serverTask.WaitAsync(TimeSpan.FromSeconds(3), TestContext.Current.CancellationToken).ConfigureAwait(false); + await serverTask.WaitAsync(TimeSpan.FromSeconds(3), TestContext.Current.CancellationToken); result.Ok.ShouldBeTrue(); result.Message.ShouldBe("Modbus FC03 OK"); @@ -241,7 +241,7 @@ public sealed class ModbusDriverProbeTests var result = await _probe.ProbeAsync(Config(port), QuickTimeout, CancellationToken.None); - await serverTask.WaitAsync(TimeSpan.FromSeconds(3), TestContext.Current.CancellationToken).ConfigureAwait(false); + await serverTask.WaitAsync(TimeSpan.FromSeconds(3), TestContext.Current.CancellationToken); result.Ok.ShouldBeTrue(); result.Message.ShouldNotBeNull(); diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests/ModbusLifecycleHygieneTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests/ModbusLifecycleHygieneTests.cs index 781dd92b..93eb18ed 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests/ModbusLifecycleHygieneTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Tests/ModbusLifecycleHygieneTests.cs @@ -497,8 +497,8 @@ public sealed class ModbusLifecycleHygieneTests(ITestOutputHelper output) }); await Task.WhenAll( - Task.Run(() => drv.InitializeAsync("{}", CancellationToken.None)), - Task.Run(() => drv.InitializeAsync("{}", CancellationToken.None))); + Task.Run(() => drv.InitializeAsync("{}", CancellationToken.None), TestContext.Current.CancellationToken), + Task.Run(() => drv.InitializeAsync("{}", CancellationToken.None), TestContext.Current.CancellationToken)); var built = handed.ToArray(); built.Length.ShouldBe(2); diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Tests/MqttDriverDiscoveryTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Tests/MqttDriverDiscoveryTests.cs index aeef6deb..22ca34f0 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Tests/MqttDriverDiscoveryTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Tests/MqttDriverDiscoveryTests.cs @@ -276,7 +276,7 @@ public sealed class MqttDriverDiscoveryTests // The gate is held by the parked initialize. Dispose must still be waiting. (The gate wait is // bounded by ConnectTimeoutSeconds = 2 s, so this 300 ms window is comfortably inside it — // an ungated dispose returns essentially instantly.) - var raced = await Task.WhenAny(dispose, Task.Delay(TimeSpan.FromMilliseconds(300))); + var raced = await Task.WhenAny(dispose, Task.Delay(TimeSpan.FromMilliseconds(300), TestContext.Current.CancellationToken)); raced.ShouldNotBe(dispose, "DisposeAsync returned while a lifecycle operation held the gate"); release.SetResult(); diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/OpcUaClientBrowseSessionAttributesTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/OpcUaClientBrowseSessionAttributesTests.cs index 928a1e44..c8c13c09 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/OpcUaClientBrowseSessionAttributesTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/OpcUaClientBrowseSessionAttributesTests.cs @@ -20,7 +20,7 @@ public sealed class OpcUaClientBrowseSessionAttributesTests private static Mock SessionReturning(NodeClass nodeClass, NodeId dataType, int valueRank, byte userAccess) { var mock = new Mock(MockBehavior.Loose); - mock.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext()); + mock.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext(BrowseTelemetry.Context)); mock.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable()); mock.Setup(s => s.ReadAsync( It.IsAny(), It.IsAny(), It.IsAny(), diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/OpcUaClientBrowseSessionPaginationTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/OpcUaClientBrowseSessionPaginationTests.cs index 59b5fba9..28811140 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/OpcUaClientBrowseSessionPaginationTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/OpcUaClientBrowseSessionPaginationTests.cs @@ -20,7 +20,7 @@ public sealed class OpcUaClientBrowseSessionPaginationTests private static Mock BuildSession(bool cancelNext) { var mock = new Mock(MockBehavior.Loose); - mock.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext()); + mock.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext(BrowseTelemetry.Context)); mock.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable()); var firstRef = new ReferenceDescription diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/OpcUaClientDriverBrowserTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/OpcUaClientDriverBrowserTests.cs index 5972ed96..2ae84ef6 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/OpcUaClientDriverBrowserTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/OpcUaClientDriverBrowserTests.cs @@ -120,7 +120,7 @@ public sealed class OpcUaClientDriverBrowserTests // A loose mock answers the attribute read with no response, so nothing is known about the node. var mockSession = new Mock(MockBehavior.Loose); mockSession.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable()); - mockSession.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext()); + mockSession.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext(BrowseTelemetry.Context)); var nsMap = NamespaceMap.FromTable(new NamespaceTable()); var sut = new OpcUaClientBrowseSession(mockSession.Object, nsMap, ObjectIds.ObjectsFolder); diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Tests/SqlCatalogGateDriverTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Tests/SqlCatalogGateDriverTests.cs index 017c0bd9..f17b0bde 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Tests/SqlCatalogGateDriverTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Tests/SqlCatalogGateDriverTests.cs @@ -48,7 +48,7 @@ public sealed class SqlCatalogGateDriverTests driver.GetHealth().LastError.ShouldBeNull(); // …and the one that contradicts it. - var report = ((ISkippedTagReporter)driver).GetSkippedTags(); + var report = ((ISkippedTagReporter)driver).GetSkippedTags().ShouldNotBeNull(); report.AuthoredCount.ShouldBe(2); report.SkippedCount.ShouldBe(1, "the gate rejected one tag; the blob mapped both"); report.Sample.Single().RawPath.ShouldBe("Bogus"); @@ -64,7 +64,7 @@ public sealed class SqlCatalogGateDriverTests await driver.InitializeAsync(ConfigJson, CancellationToken.None); - var report = ((ISkippedTagReporter)driver).GetSkippedTags(); + var report = ((ISkippedTagReporter)driver).GetSkippedTags().ShouldNotBeNull(); report.AuthoredCount.ShouldBe(1); report.HasSkips.ShouldBeFalse(); } diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Tests/TwinCATLowFindingsRegressionTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Tests/TwinCATLowFindingsRegressionTests.cs index 63017489..4f6ec752 100644 --- a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Tests/TwinCATLowFindingsRegressionTests.cs +++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Tests/TwinCATLowFindingsRegressionTests.cs @@ -121,7 +121,7 @@ public sealed class TwinCATLowFindingsRegressionTests /// Verifies that Dispose does not block on async operations in the default synchronization context. [Fact] - public void Dispose_does_not_block_on_async_in_default_synchronization_context() + public async Task Dispose_does_not_block_on_async_in_default_synchronization_context() { // Sync-over-async on a single-threaded sync context (like the OPC UA stack thread) can // deadlock. Dispose() must complete without scheduling continuations through a captured @@ -132,7 +132,7 @@ public sealed class TwinCATLowFindingsRegressionTests Devices = [new TwinCATDeviceOptions(DeviceA)], Probe = new TwinCATProbeOptions { Enabled = false }, }, "drv-1"); - drv.InitializeAsync("{}", CancellationToken.None).GetAwaiter().GetResult(); + await drv.InitializeAsync("{}", CancellationToken.None); var ctx = new SingleThreadedSyncContext(); var prev = SynchronizationContext.Current;