132 lines
4.6 KiB
C#
132 lines
4.6 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.Real.ToDriverDataType().ShouldBe(DriverDataType.Float32);
|
|
AbCipDataType.LReal.ToDriverDataType().ShouldBe(DriverDataType.Float64);
|
|
AbCipDataType.String.ToDriverDataType().ShouldBe(DriverDataType.String);
|
|
}
|
|
}
|