Task #222 partial — unblock AB Legacy PCCC via cip-path workaround (5/5 stages) #223
Reference in New Issue
Block a user
Delete Branch "task-222-ablegacy-pccc-unblock"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The README's "ab_server PCCC dispatcher is upstream-broken" claim turned out to be wrong. Actual root cause: libplctag's
ab_serverrejects empty CIP routing paths at the unconnected-send layer before forwarding to the PCCC dispatcher.pccc.citself (merged upstream in 2020 via libplctag PR #175) actually works — it just never gets called with an empty path.The demo
The
/1,0path is port-1/slot-0 (conventional ControlLogix backplane route) — any well-formed path passes ab_server's gate. Real SLC/PLC-5 hardware has no backplane and accepts empty, so operators targeting real PLCs override via env var.Changes
Fixture:
AbLegacyServerFixture.cs— dropAB_LEGACY_TRUST_WIRE; addAB_LEGACY_CIP_PATH(default1,0, set=empty for real hardware). ExposeCipPathproperty.AbLegacyReadSmokeTests.cs— usesim.CipPath; newAB_LEGACY_COMPOSE_PROFILEfilter (only one container binds:44818at a time, so the parametric theory runs only the matching family).Scripts + seed:
scripts/e2e/test-ablegacy.ps1— drop the TRUST_WIRE skip gate.scripts/e2e/e2e-config.sample.json— default gateway flipped from192.168.1.10placeholder to127.0.0.1/1,0(Docker fixture).scripts/e2e/README.md— AB Legacy row: SKIP → PASS.scripts/smoke/seed-ablegacy-smoke.sql— default HostAddress points at the Docker fixture.Docs:
tests/.../Docker/README.md— "Known limitations" section rewritten from "upstream-broken" to the cip-path explanation; env-var table updated.docs/drivers/AbLegacy-Test-Fixture.md,docs/drivers/README.md,docs/DriverClis.md— status flipped; residual bit-write gap documented.Verified
AB_LEGACY_COMPOSE_PROFILEset to the running container.Residual gap (not fixed — documented)
B3:0/5-style bit-file writes surface0x803D0000againstab_server --plc=SLC500(bit reads work). Real hardware / RSEmulate 500 path for bit-write fidelity. Documented in Docker/README.md §"Known limitations".Test plan
dotnet test tests/.../AbLegacy.IntegrationTestsper-profile: all passReplaced the "ab_server PCCC upstream-broken" skip gate with the actual root cause: libplctag's ab_server rejects empty CIP routing paths at the unconnected-send layer before the PCCC dispatcher runs. Real SLC/ MicroLogix/PLC-5 hardware accepts empty paths (no backplane); ab_server does not. With `/1,0` in place, N (Int16), F (Float32), and L (Int32) file reads + writes round-trip cleanly across all three compose profiles. ## Fixture changes - `AbLegacyServerFixture.cs`: - Drop `AB_LEGACY_TRUST_WIRE` env var + the reachable-but-untrusted skip branch. Fixture now only skips on TCP unreachability. - Add `AB_LEGACY_CIP_PATH` env var (default `1,0`) + expose `CipPath` property. Set `AB_LEGACY_CIP_PATH=` (empty) against real hardware. - Shorter skip messages on the `[AbLegacyFact]` / `[AbLegacyTheory]` attributes — one reason: endpoint not reachable. - `AbLegacyReadSmokeTests.cs`: - Device URI built from `sim.CipPath` instead of hardcoded empty path. - New `AB_LEGACY_COMPOSE_PROFILE` env var filters the parametric theory to the running container's family. Only one container binds `:44818` at a time, so cross-family params would otherwise fail. - `Slc500_write_then_read_round_trip` skips cleanly when the running profile isn't `slc500`. ## E2E + seed + docs - `scripts/e2e/test-ablegacy.ps1` — drop the `AB_LEGACY_TRUST_WIRE` skip gate; synopsis calls out the `/1,0` vs empty cip-path split between the Docker fixture and real hardware. - `scripts/e2e/e2e-config.sample.json` — sample gateway flipped from the hardware placeholder (`192.168.1.10`) to the Docker fixture (`127.0.0.1/1,0`); comment rewritten. - `scripts/e2e/README.md` — AB Legacy expected-matrix row goes from SKIP to PASS. - `scripts/smoke/seed-ablegacy-smoke.sql` — default HostAddress points at the Docker fixture + header / footer text reflect the new state. - `tests/.../Docker/README.md` — "Known limitations" section rewritten to describe the cip-path gate (not a dispatcher gap); env-var table picks up `AB_LEGACY_CIP_PATH` + `AB_LEGACY_COMPOSE_PROFILE`. - `docs/drivers/AbLegacy-Test-Fixture.md` + `docs/drivers/README.md` + `docs/DriverClis.md` — flip status from blocked to functional; residual bit-file-write gap (B3:0/5 → 0x803D0000) documented. ## Residual gap Bit-file writes (`B3:0/5` style) surface `0x803D0000` against `ab_server --plc=SLC500`; bit reads work. Non-blocking for smoke coverage — N/F/L round-trip is enough. Real hardware / RSEmulate 500 for bit-write fidelity. Documented in `Docker/README.md` §"Known limitations" + the `AbLegacy-Test-Fixture.md` follow-ups list. ## Verified - Full-solution build: 0 errors, 334 pre-existing warnings. - Integration suite passes per-profile with `AB_LEGACY_COMPOSE_PROFILE=<slc500|micrologix|plc5>` + matching compose container up. - All four non-hardware e2e scripts (Modbus / AB CIP / AB Legacy / S7) now 5/5 against the respective docker-compose fixtures. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>