Merge #622/#621/#606: OpcUaClient driver wire tests against the in-process server; SDK telemetry ctors in driver/browser; TreatWarningsAsErrors on the last 4 src projects

Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
Joseph Doherty
2026-10-08 07:10:55 -04:00
18 changed files with 366 additions and 33 deletions
@@ -37,7 +37,7 @@ public sealed class OpcUaClientContinuationPointReleaseTests
private static Mock<ISession> BuildCancellingSessionMock()
{
var mock = new Mock<ISession>(MockBehavior.Loose);
mock.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext());
mock.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext(ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.SdkTelemetry.Context));
mock.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable());
// BrowseAsync — return one Object child plus a non-empty continuation point so
@@ -148,7 +148,7 @@ public sealed class OpcUaClientContinuationPointReleaseTests
using var drv = new OpcUaClientDriver(new OpcUaClientDriverOptions(), "opcua-cp-norelease");
var mock = new Mock<ISession>(MockBehavior.Loose);
mock.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext());
mock.SetupGet(s => s.MessageContext).Returns(new ServiceMessageContext(ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.SdkTelemetry.Context));
mock.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable());
// BrowseAsync — return a result with a continuation point so the loop is entered.
@@ -5,9 +5,9 @@ using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests;
/// <summary>
/// Scaffold tests for <see cref="OpcUaClientDriver"/>'s <see cref="ITagDiscovery"/>
/// surface that don't require a live remote server. Live-browse coverage lands in a
/// follow-up PR once the in-process OPC UA server fixture is scaffolded.
/// Unit tests for <see cref="OpcUaClientDriver"/>'s <see cref="ITagDiscovery"/>
/// surface that don't require a live remote server. Live-browse coverage lives in
/// <c>OpcUaServer.IntegrationTests/OpcUaClientDriverWireTests</c>.
/// </summary>
[Trait("Category", "Unit")]
public sealed class OpcUaClientDiscoveryTests
@@ -6,8 +6,8 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests;
/// <summary>
/// Scaffold-level tests for <see cref="OpcUaClientDriver"/> that don't require a live
/// remote OPC UA server. PR 67+ adds IReadable/IWritable/ITagDiscovery/ISubscribable
/// tests against a local in-process OPC UA server fixture.
/// remote OPC UA server. The IReadable/IWritable/ITagDiscovery/ISubscribable wire-level
/// tests live in <c>OpcUaServer.IntegrationTests/OpcUaClientDriverWireTests</c>.
/// </summary>
[Trait("Category", "Unit")]
public sealed class OpcUaClientDriverScaffoldTests
@@ -6,8 +6,8 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests;
/// <summary>
/// Unit tests for the IReadable/IWritable surface that don't need a live remote OPC UA
/// server. Wire-level round-trips against a local in-process server fixture land in a
/// follow-up PR once we have one scaffolded.
/// server (the uninitialised-guard contract). The wire-level read/write round-trips live in
/// <c>OpcUaServer.IntegrationTests/OpcUaClientDriverWireTests</c>, against the in-process server.
/// </summary>
[Trait("Category", "Unit")]
public sealed class OpcUaClientReadWriteTests
@@ -53,7 +53,7 @@ public sealed class OpcUaClientStaleSessionRaceTests
// MessageContext. This getter is read in the driver's synchronous prologue (before the
// gate), so signalling here proves the pre-gate capture path has run.
mock.SetupGet(s => s.MessageContext)
.Returns(new ServiceMessageContext())
.Returns(new ServiceMessageContext(ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.SdkTelemetry.Context))
.Callback(() => prologueReached?.TrySetResult());
mock.SetupGet(s => s.NamespaceUris).Returns(new NamespaceTable());
mock.Setup(s => s.HistoryReadAsync(
@@ -5,10 +5,9 @@ using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests;
/// <summary>
/// Scaffold tests for <c>ISubscribable</c> + <c>IHostConnectivityProbe</c> that don't
/// need a live remote server. Live-session tests (subscribe/unsubscribe round-trip,
/// keep-alive transitions) land in a follow-up PR once the in-process OPC UA server
/// fixture is scaffolded.
/// Unit tests for <c>ISubscribable</c> + <c>IHostConnectivityProbe</c> that don't need a
/// live remote server. The live-session tests (subscribe/unsubscribe round-trip,
/// keep-alive transitions) live in <c>OpcUaServer.IntegrationTests/OpcUaClientDriverWireTests</c>.
/// </summary>
[Trait("Category", "Unit")]
public sealed class OpcUaClientSubscribeAndProbeTests