72 lines
3.5 KiB
C#
72 lines
3.5 KiB
C#
using Microsoft.Extensions.Logging.Abstractions;
|
|
using Opc.Ua;
|
|
using Opc.Ua.Client;
|
|
using Opc.Ua.Server;
|
|
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests;
|
|
|
|
/// <summary>Local loopback evidence that late binding replaces the SDK default on the wire.</summary>
|
|
public sealed class ServiceLevelBindingReplayTests
|
|
{
|
|
[Theory]
|
|
[InlineData((byte)100)]
|
|
[InlineData((byte)0)]
|
|
public async Task Late_binding_replays_latest_request_to_standard_ServiceLevel_read(byte latest)
|
|
{
|
|
using var deadline = CancellationTokenSource.CreateLinkedTokenSource(TestContext.Current.CancellationToken);
|
|
deadline.CancelAfter(TimeSpan.FromSeconds(15));
|
|
var ct = deadline.Token;
|
|
var pki = Path.Combine(Path.GetTempPath(), $"otopcua-replay-{Guid.NewGuid():N}");
|
|
var clientPki = TestClientSecurity.AllocatePkiRoot();
|
|
var port = 0;
|
|
try
|
|
{
|
|
var deferred = new DeferredServiceLevelPublisher();
|
|
deferred.Publish(240);
|
|
deferred.Publish(latest);
|
|
var started = await OpcUaHostStart.StartAsync(p =>
|
|
{
|
|
port = p;
|
|
return new OpcUaApplicationHost(new OpcUaApplicationHostOptions
|
|
{
|
|
ApplicationName = "OtOpcUa.Replay",
|
|
ApplicationUri = $"urn:OtOpcUa.Replay:{Path.GetFileName(pki)}",
|
|
OpcUaPort = p, PublicHostname = "localhost", PkiStoreRoot = pki,
|
|
}, NullLogger<OpcUaApplicationHost>.Instance);
|
|
}, () => new StandardServer(), ct);
|
|
await using var host = started.Host;
|
|
deferred.SetInner(new SdkServiceLevelPublisher(started.Server.CurrentInstance,
|
|
NullLogger<SdkServiceLevelPublisher>.Instance));
|
|
var config = new ApplicationConfiguration
|
|
{
|
|
ApplicationName = "OtOpcUa.ReplayClient",
|
|
ApplicationUri = $"urn:OtOpcUa.ReplayClient:{Guid.NewGuid():N}",
|
|
ApplicationType = ApplicationType.Client,
|
|
SecurityConfiguration = TestClientSecurity.Build(clientPki),
|
|
ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 10_000 },
|
|
TransportQuotas = new TransportQuotas { OperationTimeout = 5_000 },
|
|
};
|
|
await config.ValidateAsync(ApplicationType.Client, ct);
|
|
config.CertificateValidator.CertificateValidation += (_, e) => e.Accept = true;
|
|
var endpoint = await CoreClientUtils.SelectEndpointAsync(config,
|
|
$"opc.tcp://localhost:{port}/OtOpcUa", false, DefaultTelemetry.Create(_ => { }), ct);
|
|
using var session = await new DefaultSessionFactory(DefaultTelemetry.Create(_ => { })).CreateAsync(
|
|
config, new ConfiguredEndpoint(null, endpoint, EndpointConfiguration.Create(config)),
|
|
updateBeforeConnect: false, checkDomain: false, sessionName: "ServiceLevelReplay",
|
|
sessionTimeout: 10_000, identity: new UserIdentity(new AnonymousIdentityToken()),
|
|
preferredLocales: null, ct: ct);
|
|
var read = await session.ReadValueAsync(new Opc.Ua.NodeId(2267u), ct);
|
|
read.StatusCode.ShouldBe(StatusCodes.Good);
|
|
read.Value.ShouldBe(latest);
|
|
}
|
|
finally
|
|
{
|
|
if (Directory.Exists(pki)) Directory.Delete(pki, recursive: true);
|
|
if (Directory.Exists(clientPki)) Directory.Delete(clientPki, recursive: true);
|
|
}
|
|
}
|
|
}
|