using System; using System.Collections.Generic; using System.Net; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Host; using ZB.MOM.WW.OtOpcUa.Host.Configuration; using ZB.MOM.WW.OtOpcUa.Host.Domain; using ZB.MOM.WW.OtOpcUa.Tests.Helpers; namespace ZB.MOM.WW.OtOpcUa.Tests.Wiring { /// /// Regression for stability review 2026-04-13 Finding 2. Confirms that when the dashboard /// port is already bound, the service continues to start (degraded mode) and the /// flag is raised. /// public class OpcUaServiceDashboardFailureTests { [Fact] public void Start_DashboardPortInUse_ContinuesInDegradedMode() { var dashboardPort = new Random().Next(19500, 19999); using var blocker = new HttpListener(); blocker.Prefixes.Add($"http://localhost:{dashboardPort}/"); blocker.Start(); var config = new AppConfiguration { OpcUa = new OpcUaConfiguration { Port = 14842, GalaxyName = "TestGalaxy", EndpointPath = "/LmxOpcUa" }, MxAccess = new MxAccessConfiguration { ClientName = "Test" }, GalaxyRepository = new GalaxyRepositoryConfiguration(), Dashboard = new DashboardConfiguration { Enabled = true, Port = dashboardPort } }; var proxy = new FakeMxProxy(); var repo = new FakeGalaxyRepository { Hierarchy = new List { new() { GobjectId = 1, TagName = "TestObj", BrowseName = "TestObj", ParentGobjectId = 0, IsArea = false } }, Attributes = new List { new() { GobjectId = 1, TagName = "TestObj", AttributeName = "TestAttr", FullTagReference = "TestObj.TestAttr", MxDataType = 5, IsArray = false } } }; var service = new OpcUaService(config, proxy, repo); service.Start(); try { // Service continues despite dashboard bind failure — degraded mode policy. service.ServerHost.ShouldNotBeNull(); service.DashboardStartFailed.ShouldBeTrue(); service.StatusWeb.ShouldBeNull(); } finally { service.Stop(); } } } }