64e3fbe035
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public members surfaced by commentchecker — resolves 5,847 of 5,869 issues (99.6%) across three /fixdocs passes.
83 lines
4.1 KiB
C#
83 lines
4.1 KiB
C#
using Shouldly;
|
|
using Xunit;
|
|
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.
|
|
/// </summary>
|
|
[Trait("Category", "Unit")]
|
|
public sealed class OpcUaClientDiscoveryTests
|
|
{
|
|
/// <summary>Verifies that DiscoverAsync throws InvalidOperationException when not initialized.</summary>
|
|
[Fact]
|
|
public async Task DiscoverAsync_without_initialize_throws_InvalidOperationException()
|
|
{
|
|
using var drv = new OpcUaClientDriver(new OpcUaClientDriverOptions(), "opcua-disco");
|
|
var builder = new NullAddressSpaceBuilder();
|
|
await Should.ThrowAsync<InvalidOperationException>(async () =>
|
|
await drv.DiscoverAsync(builder, TestContext.Current.CancellationToken));
|
|
}
|
|
|
|
/// <summary>Verifies that DiscoverAsync rejects null builder argument.</summary>
|
|
[Fact]
|
|
public void DiscoverAsync_rejects_null_builder()
|
|
{
|
|
using var drv = new OpcUaClientDriver(new OpcUaClientDriverOptions(), "opcua-disco");
|
|
Should.ThrowAsync<ArgumentNullException>(async () =>
|
|
await drv.DiscoverAsync(null!, TestContext.Current.CancellationToken));
|
|
}
|
|
|
|
/// <summary>Verifies that discovery configuration has sensible defaults.</summary>
|
|
[Fact]
|
|
public void Discovery_caps_are_sensible_defaults()
|
|
{
|
|
var opts = new OpcUaClientDriverOptions();
|
|
opts.MaxDiscoveredNodes.ShouldBe(10_000, "bounds memory on runaway servers without clipping normal models");
|
|
opts.MaxBrowseDepth.ShouldBe(10, "deep enough for realistic info models; shallow enough for cycle safety");
|
|
opts.BrowseRoot.ShouldBeNull("null = default to ObjectsFolder i=85");
|
|
}
|
|
|
|
/// <summary>Test builder that provides no-op implementations for discovery tests.</summary>
|
|
private sealed class NullAddressSpaceBuilder : IAddressSpaceBuilder
|
|
{
|
|
/// <summary>Returns this builder (no-op).</summary>
|
|
/// <param name="browseName">The browse name of the folder.</param>
|
|
/// <param name="displayName">The display name of the folder.</param>
|
|
public IAddressSpaceBuilder Folder(string browseName, string displayName) => this;
|
|
|
|
/// <summary>Returns a stub handle.</summary>
|
|
/// <param name="browseName">The browse name of the variable.</param>
|
|
/// <param name="displayName">The display name of the variable.</param>
|
|
/// <param name="attributeInfo">The attribute information for the variable.</param>
|
|
public IVariableHandle Variable(string browseName, string displayName, DriverAttributeInfo attributeInfo)
|
|
=> new StubHandle();
|
|
|
|
/// <summary>No-op property addition.</summary>
|
|
/// <param name="browseName">The browse name of the property.</param>
|
|
/// <param name="dataType">The data type of the property.</param>
|
|
/// <param name="value">The property value.</param>
|
|
public void AddProperty(string browseName, DriverDataType dataType, object? value) { }
|
|
|
|
/// <summary>No-op alarm condition attachment.</summary>
|
|
/// <param name="sourceVariable">The source variable handle.</param>
|
|
/// <param name="alarmName">The alarm name.</param>
|
|
/// <param name="alarmInfo">The alarm attribute information.</param>
|
|
public void AttachAlarmCondition(IVariableHandle sourceVariable, string alarmName, DriverAttributeInfo alarmInfo) { }
|
|
|
|
/// <summary>Stub variable handle for testing.</summary>
|
|
private sealed class StubHandle : IVariableHandle
|
|
{
|
|
/// <summary>Gets the full reference as "stub".</summary>
|
|
public string FullReference => "stub";
|
|
|
|
/// <summary>Throws NotSupportedException.</summary>
|
|
/// <param name="info">The alarm condition information (unused).</param>
|
|
public IAlarmConditionSink MarkAsAlarmCondition(AlarmConditionInfo info) => throw new NotSupportedException();
|
|
}
|
|
}
|
|
}
|