fix(abcip): CompactLogix native default connection size matches libplctag's Large Forward Open (found by T21 latency harness)
This commit is contained in:
@@ -44,7 +44,7 @@ public static class KnownProfiles
|
||||
public static readonly AbServerProfile CompactLogix = new(
|
||||
Family: AbCipPlcFamily.CompactLogix,
|
||||
ComposeProfile: "compactlogix",
|
||||
Notes: "ab_server doesn't enforce the narrower ConnectionSize; driver-side profile caps it per PR 10.");
|
||||
Notes: "Large Forward Open (4002) like libplctag since T21; ab_server accepts any size, so the regular-open fallback is unit-tested only.");
|
||||
|
||||
/// <summary>Gets the Micro800 profile.</summary>
|
||||
public static readonly AbServerProfile Micro800 = new(
|
||||
|
||||
@@ -202,4 +202,26 @@ public sealed class AbCipDriverProbeTests
|
||||
result.Ok.ShouldBeTrue();
|
||||
result.Message!.ShouldContain("probe tag not found");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// T21: the probe builds its handle from the family profile, so a CompactLogix device with no
|
||||
/// ConnectionSize opens Large (4002) like libplctag; an explicit device ConnectionSize still wins.
|
||||
/// </summary>
|
||||
[Theory]
|
||||
[InlineData("", 4002)]
|
||||
[InlineData(",\"connectionSize\":504", 504)]
|
||||
public async Task CompactLogix_probe_uses_the_profile_default_unless_the_device_overrides_it(string extra, int expected)
|
||||
{
|
||||
using var listener = new TcpListener(IPAddress.Loopback, 0);
|
||||
listener.Start();
|
||||
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
|
||||
var factory = new FakeAbCipTagFactory();
|
||||
|
||||
await new AbCipDriverProbe(factory).ProbeAsync(
|
||||
$"{{\"devices\":[{{\"hostAddress\":\"ab://127.0.0.1:{port}/1,0\",\"plcFamily\":\"CompactLogix\"{extra}}}]}}",
|
||||
TimeSpan.FromSeconds(3),
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
factory.Tags.Values.ShouldHaveSingleItem().CreationParams.ConnectionSize.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ public sealed class AbCipDriverTests
|
||||
AbCipPlcFamilyProfile.Micro800.SupportsRequestPacking.ShouldBeFalse();
|
||||
AbCipPlcFamilyProfile.Micro800.SupportsConnectedMessaging.ShouldBeFalse();
|
||||
|
||||
AbCipPlcFamilyProfile.CompactLogix.DefaultConnectionSize.ShouldBe(504);
|
||||
AbCipPlcFamilyProfile.CompactLogix.DefaultConnectionSize.ShouldBe(4002); // Large, as libplctag opens it
|
||||
AbCipPlcFamilyProfile.GuardLogix.LibplctagPlcAttribute.ShouldBe("controllogix");
|
||||
}
|
||||
|
||||
|
||||
+23
@@ -117,6 +117,29 @@ public sealed class AbCipPerDeviceConnectionOptionsTests
|
||||
factory.Tags["Speed"].CreationParams.ConnectionSize.ShouldBe(4002);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// T21: a CompactLogix device with no override opens Large (4002), matching libplctag's
|
||||
/// <c>plc=compactlogix</c>; the per-device override still wins.
|
||||
/// </summary>
|
||||
[Theory]
|
||||
[InlineData(null, 4002)]
|
||||
[InlineData(504, 504)]
|
||||
public async Task CompactLogix_ConnectionSize_defaults_to_large_unless_overridden(int? overrideSize, int expected)
|
||||
{
|
||||
var factory = new FakeAbCipTagFactory();
|
||||
var drv = new AbCipDriver(new AbCipDriverOptions
|
||||
{
|
||||
Devices = [new AbCipDeviceOptions(Device, AbCipPlcFamily.CompactLogix, ConnectionSize: overrideSize)],
|
||||
RawTags = AbCipRawTags.From(new AbCipTagDefinition("Speed", Device, "Speed", AbCipDataType.DInt)),
|
||||
Probe = new AbCipProbeOptions { Enabled = false },
|
||||
}, "drv-1", factory);
|
||||
await drv.InitializeAsync("{}", CancellationToken.None);
|
||||
|
||||
await drv.ReadAsync(["Speed"], CancellationToken.None);
|
||||
|
||||
factory.Tags["Speed"].CreationParams.ConnectionSize.ShouldBe(expected);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that AllowPacking and ConnectionSize round-trip correctly through JSON parsing.</summary>
|
||||
[Fact]
|
||||
public void AbCipDriverFactoryExtensions_ParseOptions_round_trips_AllowPacking_and_ConnectionSize()
|
||||
|
||||
@@ -40,22 +40,26 @@ public sealed class AbCipPlcFamilyTests
|
||||
|
||||
// ---- CompactLogix ----
|
||||
|
||||
/// <summary>Verifies that the CompactLogix profile uses a narrower connection size than ControlLogix.</summary>
|
||||
/// <summary>
|
||||
/// Verifies that the CompactLogix profile defaults to a Large Forward Open (4002), matching what
|
||||
/// libplctag opens for <c>plc=compactlogix</c>. A target that refuses Large falls back to a regular
|
||||
/// 504 open inside CipConnection (pinned by the Ab.Transport CipConnectionTests fallback tests).
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void CompactLogix_profile_uses_narrower_connection_size()
|
||||
public void CompactLogix_profile_defaults_to_a_large_forward_open_like_libplctag()
|
||||
{
|
||||
var p = AbCipPlcFamilyProfile.CompactLogix;
|
||||
p.LibplctagPlcAttribute.ShouldBe("compactlogix");
|
||||
p.DefaultConnectionSize.ShouldBe(504); // 5069-L3x narrow-window safety
|
||||
p.DefaultConnectionSize.ShouldBe(4002); // T21: 504 cost the native transport ~3x the round trips per poll
|
||||
p.DefaultCipPath.ShouldBe("1,0");
|
||||
p.SupportsRequestPacking.ShouldBeTrue();
|
||||
p.SupportsConnectedMessaging.ShouldBeTrue();
|
||||
p.MaxFragmentBytes.ShouldBe(500);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that a CompactLogix device initializes with a narrow connection size.</summary>
|
||||
/// <summary>Verifies that a CompactLogix device initializes with the Large connection size libplctag opens (T21).</summary>
|
||||
[Fact]
|
||||
public async Task CompactLogix_device_initialises_with_narrow_ConnectionSize()
|
||||
public async Task CompactLogix_device_initialises_with_large_ConnectionSize()
|
||||
{
|
||||
var drv = new AbCipDriver(new AbCipDriverOptions
|
||||
{
|
||||
@@ -65,7 +69,7 @@ public sealed class AbCipPlcFamilyTests
|
||||
await drv.InitializeAsync("{}", CancellationToken.None);
|
||||
|
||||
var profile = drv.GetDeviceState("ab://192.168.1.10/1,0")!.Profile;
|
||||
profile.DefaultConnectionSize.ShouldBeLessThan(AbCipPlcFamilyProfile.ControlLogix.DefaultConnectionSize);
|
||||
profile.DefaultConnectionSize.ShouldBe(4002);
|
||||
profile.MaxFragmentBytes.ShouldBeLessThan(AbCipPlcFamilyProfile.ControlLogix.MaxFragmentBytes);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user