test(opcuaclient.browser): unit + opc-plc live coverage
This commit is contained in:
+76
@@ -0,0 +1,76 @@
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.Commons.Browsing;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Live-server tests against the opc-plc Docker fixture. Bring up with
|
||||
/// `lmxopcua-fix up opcuaclient` from PowerShell before running. These tests
|
||||
/// drive the internal <c>OpcUaClientBrowseSession</c> through its public factory
|
||||
/// <see cref="OpcUaClientDriverBrowser"/> so no InternalsVisibleTo is needed.
|
||||
/// Filter out with <c>--filter "Category!=RequiresOpcPlc"</c> when the fixture
|
||||
/// is unreachable.
|
||||
/// </summary>
|
||||
[Trait("Category", "RequiresOpcPlc")]
|
||||
public sealed class OpcUaClientBrowseSessionTests
|
||||
{
|
||||
private static string Endpoint =>
|
||||
Environment.GetEnvironmentVariable("OPCUA_SIM_ENDPOINT") ?? "opc.tcp://10.100.0.35:50000";
|
||||
|
||||
// Enum values use their numeric ordinal because the browser uses default
|
||||
// System.Text.Json with no JsonStringEnumConverter. SecurityPolicy.None,
|
||||
// SecurityMode.None, OpcUaAuthType.Anonymous are all index 0, so omitting them
|
||||
// also works — keeping them explicit for documentation value.
|
||||
private static string ConfigJson => $$"""
|
||||
{
|
||||
"EndpointUrl":"{{Endpoint}}",
|
||||
"SecurityPolicy":0,
|
||||
"SecurityMode":0,
|
||||
"AuthType":0,
|
||||
"SessionTimeout":"00:01:00",
|
||||
"Timeout":"00:00:10",
|
||||
"PerEndpointConnectTimeout":"00:00:10"
|
||||
}
|
||||
""";
|
||||
|
||||
/// <summary>RootAsync should surface at least one node under ObjectsFolder
|
||||
/// (opc-plc exposes a non-empty top level).</summary>
|
||||
[Fact]
|
||||
public async Task RootAsync_returns_at_least_one_node()
|
||||
{
|
||||
var ct = TestContext.Current.CancellationToken;
|
||||
var browser = new OpcUaClientDriverBrowser();
|
||||
await using var session = await browser.OpenAsync(ConfigJson, ct);
|
||||
var roots = await session.RootAsync(ct);
|
||||
roots.Count.ShouldBeGreaterThan(0);
|
||||
}
|
||||
|
||||
/// <summary>ExpandAsync should accept a stable NodeId returned by RootAsync
|
||||
/// and round-trip through the live namespace table.</summary>
|
||||
[Fact]
|
||||
public async Task ExpandAsync_round_trips_stable_NodeId()
|
||||
{
|
||||
var ct = TestContext.Current.CancellationToken;
|
||||
var browser = new OpcUaClientDriverBrowser();
|
||||
await using var session = await browser.OpenAsync(ConfigJson, ct);
|
||||
var roots = await session.RootAsync(ct);
|
||||
var folder = roots.FirstOrDefault(n => n.Kind == BrowseNodeKind.Folder);
|
||||
folder.ShouldNotBeNull("expected at least one Folder under ObjectsFolder");
|
||||
var children = await session.ExpandAsync(folder!.NodeId, ct);
|
||||
children.ShouldNotBeNull();
|
||||
}
|
||||
|
||||
/// <summary>The OPC UA picker treats variables as terminal leaves, so
|
||||
/// AttributesAsync must always be empty for this driver.</summary>
|
||||
[Fact]
|
||||
public async Task AttributesAsync_is_empty_for_opcuaclient()
|
||||
{
|
||||
var ct = TestContext.Current.CancellationToken;
|
||||
var browser = new OpcUaClientDriverBrowser();
|
||||
await using var session = await browser.OpenAsync(ConfigJson, ct);
|
||||
var attrs = await session.AttributesAsync("nsu=http://opcfoundation.org/UA/;i=85", ct);
|
||||
attrs.ShouldBeEmpty();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user