fix(ab): Task 22 review r1 — release-note timing and AbLegacy regressions, probe E2E on both transports
- I1: the upgrade restart itself moves every no-key AbCip/AbLegacy driver to Native (every process start constructs drivers, incl. boot-from-cache). Docs + CLAUDE.md now say so and tell operators to set "transport": "Libplctag" BEFORE upgrading (older builds ignore the unknown key). - I2: AbLegacy release note leads with the status-bit write refusal (T4:0.DN, C5:0.CU, R6:0.EN, ...) on defaulted SLC/MicroLogix drivers and the fallback. The real client status is BadCommunicationError, not BadNotSupported (the driver's write catch-all maps the runtime's AbTransportException like any transport failure, as #571 does for PLC-5), with handle eviction and Degraded health; pinned by a driver-level test (no 0xAA write on the wire, with a positive control). ST string byte order stated as unverified. Also corrects the docs' "T4:0/DN" examples: the driver's address grammar is "T4:0.DN" ("/DN" is a malformed address). - I3: DriverProbeHandshakeE2eTests' two AbCip probe tests are a [Theory] over Native and Libplctag. Run against ab_server controllogix: all 4 rows pass with identical exact messages. - M1: documented (docs + resolver XML doc): the AdminUI merges only the probed device, so a mixed-family defaulted AbLegacy driver can probe Native while running Libplctag. - M2: factory ParseEnum rejects undefined integer strings ("7") via Enum.IsDefined (both drivers). - M3: AbCip driver-level bad value reads "AB CIP config in '<id>' has unknown Transport ..."; the named constant is gone (tagName: null now means driver-level). - M4: the explicit-Native limited-family Warning is once per instance, not per (re)init. - Nit: EffectiveTransport docs note that injected factories bypass it. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
+14
-9
@@ -168,8 +168,10 @@ public sealed class DriverProbeHandshakeE2eTests
|
||||
|
||||
// ---- AbCip : libplctag CIP session handshake (skips unless the sim fixture is up) ----
|
||||
|
||||
[Fact]
|
||||
public async Task AbCip_Green_AgainstSim()
|
||||
[Theory]
|
||||
[InlineData("Native")]
|
||||
[InlineData("Libplctag")]
|
||||
public async Task AbCip_Green_AgainstSim(string transport)
|
||||
{
|
||||
SkipUnless(DockerHost, AbCipPort);
|
||||
// Probe an explicit tag that the ab_server ControlLogix sim actually defines
|
||||
@@ -182,9 +184,9 @@ public sealed class DriverProbeHandshakeE2eTests
|
||||
// exercising the one path the comment above says it does not exercise — and reporting it as a
|
||||
// failure of the fixture rather than of the config shape.
|
||||
var result = await new AbCipDriverProbe().ProbeAsync(
|
||||
// Pinned to libplctag (Task 22 flipped the default to Native): the exact messages below were
|
||||
// proven against ab_server on libplctag; the native path's ab_server coverage is TransportMatrix.
|
||||
$"{{\"Transport\":\"Libplctag\",\"Devices\":[{{\"HostAddress\":\"ab://{DockerHost}:{AbCipPort}/1,0\"}}]," +
|
||||
// Run on BOTH transports (Task 22 review r1 I3): Native is the production default, and the
|
||||
// probe's green messages are transport-neutral strings, so each row asserts the same text.
|
||||
$"{{\"Transport\":\"{transport}\",\"Devices\":[{{\"HostAddress\":\"ab://{DockerHost}:{AbCipPort}/1,0\"}}]," +
|
||||
$"\"RawTags\":[{{\"RawPath\":\"Plant/AbCip/dev1/TestDINT\"," +
|
||||
$"\"TagConfig\":\"{{\\\"tagPath\\\":\\\"TestDINT\\\",\\\"dataType\\\":\\\"DInt\\\"}}\"," +
|
||||
$"\"WriteIdempotent\":false,\"DeviceName\":\"ab://{DockerHost}:{AbCipPort}/1,0\"}}]}}",
|
||||
@@ -214,13 +216,16 @@ public sealed class DriverProbeHandshakeE2eTests
|
||||
/// <c>Docker/patches/0002-ab_server-answer-tag-not-found-with-cip-0x04.patch</c> — so this test
|
||||
/// needs the fixture rebuilt from that patch, not merely running.
|
||||
/// </remarks>
|
||||
[Fact]
|
||||
public async Task AbCip_WithNoAuthoredTags_ReportsTheControllerReachable()
|
||||
[Theory]
|
||||
[InlineData("Native")]
|
||||
[InlineData("Libplctag")]
|
||||
public async Task AbCip_WithNoAuthoredTags_ReportsTheControllerReachable(string transport)
|
||||
{
|
||||
SkipUnless(DockerHost, AbCipPort);
|
||||
var result = await new AbCipDriverProbe().ProbeAsync(
|
||||
// Pinned to libplctag (Task 22): the 0x04 → ErrorNotFound reasoning above is libplctag's.
|
||||
$"{{\"Transport\":\"Libplctag\",\"Devices\":[{{\"HostAddress\":\"ab://{DockerHost}:{AbCipPort}/1,0\"}}],\"RawTags\":[]}}",
|
||||
// Both transports (Task 22 review r1 I3): native maps CIP 0x04 to AbStatus.NotFound exactly as
|
||||
// libplctag's ErrorNotFound does, so the reachable classification is the same.
|
||||
$"{{\"Transport\":\"{transport}\",\"Devices\":[{{\"HostAddress\":\"ab://{DockerHost}:{AbCipPort}/1,0\"}}],\"RawTags\":[]}}",
|
||||
Timeout, Ct);
|
||||
|
||||
result.Ok.ShouldBeTrue($"Probe message: {result.Message}");
|
||||
|
||||
Reference in New Issue
Block a user