Files
lmxopcua/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/AdminUiSource.cs
T
Joseph Doherty a04196d725 fix(adminui): evict unconfigured drivers from status stores; isolate throwing subscribers (R04 L1, L5)
The driver-status and resilience stores had no removal path, so a deleted
driver stayed on /hosts as a frozen row until restart. Both stores gain
RetainOnly, which /hosts calls after each successful config load (never on a
failed one).

The stores and InProcessBroadcaster now raise their events one subscriber at a
time, so a throwing handler cannot starve later subscribers or escape onto the
bridge actor. The alert/script-log bridges publish inside their try, and the
resilience bridge catches a store failure instead of restarting.

Refs #745
Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
2026-10-22 17:24:04 -04:00

26 lines
1.2 KiB
C#

using Shouldly;
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests;
/// <summary>
/// Reads an AdminUI source file for a source-scan pin. The repo has no bUnit, so Razor wiring that a
/// unit test cannot render is pinned by scanning the markup; it proves the wiring exists, not that it
/// renders correctly (the docker-dev live pass covers that).
/// </summary>
internal static class AdminUiSource
{
/// <summary>Reads a file under <c>src/Server/ZB.MOM.WW.OtOpcUa.AdminUI</c>.</summary>
/// <param name="relativeSegments">Path segments below the AdminUI project directory.</param>
/// <returns>The file text.</returns>
public static string Read(params string[] relativeSegments)
{
var dir = new DirectoryInfo(AppContext.BaseDirectory);
while (dir is not null && !File.Exists(Path.Combine(dir.FullName, "ZB.MOM.WW.OtOpcUa.slnx")))
dir = dir.Parent;
dir.ShouldNotBeNull("could not locate the repository root (no ZB.MOM.WW.OtOpcUa.slnx above the test binary)");
var parts = new[] { dir!.FullName, "src", "Server", "ZB.MOM.WW.OtOpcUa.AdminUI" }.Concat(relativeSegments).ToArray();
return File.ReadAllText(Path.Combine(parts));
}
}