Files
lmxopcua/tests/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Tests/AbCipDriverTests.cs
2026-04-25 12:44:43 -04:00

135 lines
4.8 KiB
C#

using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using ZB.MOM.WW.OtOpcUa.Driver.AbCip;
using ZB.MOM.WW.OtOpcUa.Driver.AbCip.PlcFamilies;
namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.Tests;
[Trait("Category", "Unit")]
public sealed class AbCipDriverTests
{
[Fact]
public void DriverType_is_AbCip()
{
var drv = new AbCipDriver(new AbCipDriverOptions(), "drv-1");
drv.DriverType.ShouldBe("AbCip");
drv.DriverInstanceId.ShouldBe("drv-1");
}
[Fact]
public async Task InitializeAsync_with_empty_devices_succeeds_and_marks_healthy()
{
var drv = new AbCipDriver(new AbCipDriverOptions(), "drv-1");
await drv.InitializeAsync("{}", CancellationToken.None);
drv.GetHealth().State.ShouldBe(DriverState.Healthy);
}
[Fact]
public async Task InitializeAsync_registers_each_device_with_its_family_profile()
{
var drv = new AbCipDriver(new AbCipDriverOptions
{
Devices =
[
new AbCipDeviceOptions("ab://10.0.0.5/1,0", AbCipPlcFamily.ControlLogix),
new AbCipDeviceOptions("ab://10.0.0.6/", AbCipPlcFamily.Micro800),
],
}, "drv-1");
await drv.InitializeAsync("{}", CancellationToken.None);
drv.DeviceCount.ShouldBe(2);
drv.GetDeviceState("ab://10.0.0.5/1,0")!.Profile.ShouldBe(AbCipPlcFamilyProfile.ControlLogix);
drv.GetDeviceState("ab://10.0.0.6/")!.Profile.ShouldBe(AbCipPlcFamilyProfile.Micro800);
}
[Fact]
public async Task InitializeAsync_with_malformed_host_address_faults()
{
var drv = new AbCipDriver(new AbCipDriverOptions
{
Devices = [new AbCipDeviceOptions("not-a-valid-address")],
}, "drv-1");
await Should.ThrowAsync<InvalidOperationException>(
() => drv.InitializeAsync("{}", CancellationToken.None));
drv.GetHealth().State.ShouldBe(DriverState.Faulted);
}
[Fact]
public async Task ShutdownAsync_clears_devices_and_marks_unknown()
{
var drv = new AbCipDriver(new AbCipDriverOptions
{
Devices = [new AbCipDeviceOptions("ab://10.0.0.5/1,0")],
}, "drv-1");
await drv.InitializeAsync("{}", CancellationToken.None);
drv.DeviceCount.ShouldBe(1);
await drv.ShutdownAsync(CancellationToken.None);
drv.DeviceCount.ShouldBe(0);
drv.GetHealth().State.ShouldBe(DriverState.Unknown);
}
[Fact]
public async Task ReinitializeAsync_cycles_devices()
{
var drv = new AbCipDriver(new AbCipDriverOptions
{
Devices = [new AbCipDeviceOptions("ab://10.0.0.5/1,0")],
}, "drv-1");
await drv.InitializeAsync("{}", CancellationToken.None);
await drv.ReinitializeAsync("{}", CancellationToken.None);
drv.DeviceCount.ShouldBe(1);
drv.GetHealth().State.ShouldBe(DriverState.Healthy);
}
[Fact]
public void Family_profiles_expose_expected_defaults()
{
AbCipPlcFamilyProfile.ControlLogix.LibplctagPlcAttribute.ShouldBe("controllogix");
AbCipPlcFamilyProfile.ControlLogix.DefaultConnectionSize.ShouldBe(4002);
AbCipPlcFamilyProfile.ControlLogix.DefaultCipPath.ShouldBe("1,0");
AbCipPlcFamilyProfile.Micro800.DefaultCipPath.ShouldBe(""); // no backplane routing
AbCipPlcFamilyProfile.Micro800.SupportsRequestPacking.ShouldBeFalse();
AbCipPlcFamilyProfile.Micro800.SupportsConnectedMessaging.ShouldBeFalse();
AbCipPlcFamilyProfile.CompactLogix.DefaultConnectionSize.ShouldBe(504);
AbCipPlcFamilyProfile.GuardLogix.LibplctagPlcAttribute.ShouldBe("controllogix");
}
[Fact]
public void PlcTagHandle_IsInvalid_for_zero_or_negative_native_id()
{
PlcTagHandle.FromNative(-5).IsInvalid.ShouldBeTrue();
PlcTagHandle.FromNative(0).IsInvalid.ShouldBeTrue();
PlcTagHandle.FromNative(42).IsInvalid.ShouldBeFalse();
}
[Fact]
public void PlcTagHandle_Dispose_is_idempotent()
{
var h = PlcTagHandle.FromNative(42);
h.Dispose();
h.Dispose(); // must not throw
}
[Fact]
public void AbCipDataType_maps_atomics_to_driver_types()
{
AbCipDataType.Bool.ToDriverDataType().ShouldBe(DriverDataType.Boolean);
AbCipDataType.DInt.ToDriverDataType().ShouldBe(DriverDataType.Int32);
AbCipDataType.LInt.ToDriverDataType().ShouldBe(DriverDataType.Int64);
AbCipDataType.ULInt.ToDriverDataType().ShouldBe(DriverDataType.UInt64);
AbCipDataType.Real.ToDriverDataType().ShouldBe(DriverDataType.Float32);
AbCipDataType.LReal.ToDriverDataType().ShouldBe(DriverDataType.Float64);
AbCipDataType.String.ToDriverDataType().ShouldBe(DriverDataType.String);
AbCipDataType.Dt.ToDriverDataType().ShouldBe(DriverDataType.Int64);
}
}