using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Core.Abstractions; using ZB.MOM.WW.OtOpcUa.Driver.TwinCAT; namespace ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Tests; /// /// CONV-4 — must resolve an authored raw tag to its OWN /// device host so per-host breaker keys are correct for equipment tags, not the first-device /// fallback. Under v3 the tag is delivered as a whose /// names the owning device; the driver threads that onto the /// def's host at Initialize, and ResolveHost reads it back by RawPath. /// [Trait("Category", "Unit")] public sealed class TwinCATResolveHostTests { private const string DeviceA = "ads://5.23.91.23.1.1:851"; private const string DeviceB = "ads://5.23.91.23.1.2:851"; private static async Task NewDriverAsync(params RawTagEntry[] rawTags) { var drv = new TwinCATDriver( new TwinCATDriverOptions { Devices = [new TwinCATDeviceOptions(DeviceA), new TwinCATDeviceOptions(DeviceB)], RawTags = rawTags, Probe = new TwinCATProbeOptions { Enabled = false }, EnableControllerBrowse = false, }, "twincat-1", new FakeTwinCATClientFactory()); await drv.InitializeAsync("{}", CancellationToken.None); return drv; } /// A raw tag naming device B resolves to device B's host, not the first device. [Fact] public async Task ResolveHost_RawTagOnDeviceB_ReturnsItsOwnDeviceHost() { var blob = """{"symbolPath":"MAIN.Speed","dataType":"DInt"}"""; var drv = await NewDriverAsync(new RawTagEntry("equip/Speed", blob, WriteIdempotent: false, DeviceName: DeviceB)); drv.ResolveHost("equip/Speed").ShouldBe(DeviceB); } /// An unresolvable ref keeps the current first-device fallback. [Fact] public async Task ResolveHost_UnknownRef_KeepsCurrentFallback() { var drv = await NewDriverAsync(); drv.ResolveHost("totally-unknown").ShouldBe(DeviceA); } }