refactor(runtime,opcuaserver): device-host normalization re-homed to Commons DeviceConfigIntent (R2-11)

This commit is contained in:
Joseph Doherty
2026-07-13 10:46:30 -04:00
parent a452a20947
commit 7bbec77716
7 changed files with 19 additions and 90 deletions
@@ -8,8 +8,11 @@ namespace ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests;
/// Covers follow-up E projection: <see cref="EquipmentNode"/> carries the equipment's
/// <c>DriverInstanceId</c> / <c>DeviceId</c> bindings and the resolved <c>DeviceHost</c> (parsed from
/// the bound <see cref="Device"/>'s schemaless <c>DeviceConfig</c> JSON via the shared
/// <see cref="AddressSpaceComposer.TryExtractDeviceHost"/>). A later task grafts a driver's discovered
/// <c>DeviceConfigIntent.TryExtractHost</c>). A later task grafts a driver's discovered
/// FixedTree onto a zero-tag equipment and partitions a multi-device driver by host using these.
/// <para>The direct host-extraction + normalization unit tests moved to
/// <c>Commons.Tests/DeviceConfigIntentTests</c> (R2-11) — this suite keeps the Compose-level projection
/// coverage.</para>
/// </summary>
public sealed class AddressSpaceComposerDeviceHostTests
{
@@ -75,36 +78,6 @@ public sealed class AddressSpaceComposerDeviceHostTests
noHost.DeviceHost.ShouldBeNull();
}
/// <summary>The shared host extractor normalizes (trim + lower-case) and tolerates every malformed
/// shape (blank / non-object / no string HostAddress / blank value / non-JSON) by returning null.</summary>
[Theory]
[InlineData("{\"HostAddress\":\"10.201.31.5:8193\"}", "10.201.31.5:8193")]
[InlineData("{\"HostAddress\":\" HOST-A:8193 \"}", "host-a:8193")] // trimmed + lower-cased
[InlineData("{\"HostAddress\":\"\"}", null)] // blank value
[InlineData("{\"HostAddress\":1234}", null)] // non-string
[InlineData("{\"Port\":502}", null)] // absent
[InlineData("[]", null)] // non-object root
[InlineData("not json", null)] // malformed
[InlineData("", null)] // blank
public void TryExtractDeviceHost_normalizes_and_tolerates(string? deviceConfig, string? expected)
{
AddressSpaceComposer.TryExtractDeviceHost(deviceConfig).ShouldBe(expected);
}
/// <summary>The extracted-out shared normalizer (the single source of truth the FixedTree-partition path
/// reuses on a driver-discovered device-host folder segment) trims + lower-cases, and is idempotent on an
/// already-normalized value — so a segment like <c>" HOST-A:8193 "</c> matches a stored
/// <c>"host-a:8193"</c> DeviceHost.</summary>
[Theory]
[InlineData("10.201.31.5:8193", "10.201.31.5:8193")]
[InlineData(" HOST-A:8193 ", "host-a:8193")]
[InlineData("host-a:8193", "host-a:8193")] // idempotent
[InlineData("H1", "h1")]
public void NormalizeDeviceHost_trims_and_lowercases(string raw, string expected)
{
AddressSpaceComposer.NormalizeDeviceHost(raw).ShouldBe(expected);
}
private static Equipment NewEquipment(string id, string? driver, string? device) => new()
{
EquipmentId = id,