using System.IO; using System.Net.Sockets; using System.Net; using Microsoft.Extensions.Logging.Abstractions; using Opc.Ua; using Opc.Ua.Server; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.OpcUaServer; namespace ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests; /// /// Audit gap closeout — verifies /// is reflected in Server.ServerArray after start. Single-server in-process check; the /// cross-server visibility check lives in OtOpcUa.OpcUaServer.IntegrationTests. /// public sealed class OpcUaApplicationHostServerArrayTests { [Fact] public async Task ServerArray_contains_local_uri_and_configured_peers_after_start() { var pkiRoot = Path.Combine(Path.GetTempPath(), $"otopcua-pki-{Guid.NewGuid():N}"); try { var options = new OpcUaApplicationHostOptions { ApplicationName = "OtOpcUa.UnitTest", ApplicationUri = "urn:OtOpcUa.UnitTest.NodeA", OpcUaPort = AllocateFreePort(), PublicHostname = "127.0.0.1", PkiStoreRoot = pkiRoot, PeerApplicationUris = new[] { "urn:OtOpcUa.UnitTest.NodeB" }, }; var server = new StandardServer(); await using var host = new OpcUaApplicationHost(options, NullLogger.Instance); await host.StartAsync(server, CancellationToken.None); var serverArray = server.CurrentInstance.ServerObject.ServerArray.Value; serverArray.ShouldNotBeNull(); serverArray.ShouldContain("urn:OtOpcUa.UnitTest.NodeA"); serverArray.ShouldContain("urn:OtOpcUa.UnitTest.NodeB"); } finally { if (Directory.Exists(pkiRoot)) Directory.Delete(pkiRoot, recursive: true); } } private static int AllocateFreePort() { var listener = new TcpListener(IPAddress.Loopback, 0); listener.Start(); var port = ((IPEndPoint)listener.LocalEndpoint).Port; listener.Stop(); return port; } }