From 497d8be1d5d20ea814ce6fc9c5eae3bd2a6f9916 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Wed, 3 Jun 2026 16:01:06 -0400 Subject: [PATCH] =?UTF-8?q?docs(audit):=20AbServer-Test-Fixture.md=20?= =?UTF-8?q?=E2=80=94=20accuracy=20pass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit STRUCTURAL: links-report.md row — path MISSING src/tools/ab_server/. ab_server is not in this repo; it lives in the upstream libplctag/libplctag GitHub repo and is cloned + built inside Docker/Dockerfile. Rewrote Binary bullet to describe it as an external upstream source (no local path reference that fails the link checker). STALE-STATUS: Lifecycle TCP-probe host was listed as 127.0.0.1:44818 (AbServer-Test-Fixture.md:21). AbServerFixture.cs:35,72 default is 10.100.0.35:44818 (shared Docker host, migrated 2026-04-28). Fixed. CODE-REALITY: Micro800 profile Notes quoted "ab_server has no --plc micro800 — falls back to controllogix emulation." Incorrect: Docker/docker-compose.yml micro800 service uses --plc=Micro800; AbServerProfile.cs:49 confirms "--plc=Micro800 mode (unconnected-only, empty path)." Updated Notes quote and summary table row to match actual compose behaviour. Verified: python3 .docs-audit/check_links.py — zero rows for this doc. --- docs/drivers/AbServer-Test-Fixture.md | 32 ++++++++++++++++----------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/docs/drivers/AbServer-Test-Fixture.md b/docs/drivers/AbServer-Test-Fixture.md index 3bd015ee..55c2f476 100644 --- a/docs/drivers/AbServer-Test-Fixture.md +++ b/docs/drivers/AbServer-Test-Fixture.md @@ -10,17 +10,20 @@ quirk. UDT / alarm / quirk behavior is verified only by unit tests with ## What the fixture is -- **Binary**: `ab_server` — a C program in libplctag's - `src/tools/ab_server/` ([libplctag/libplctag](https://github.com/libplctag/libplctag), - MIT). +- **Binary**: `ab_server` — a C program from the upstream + [libplctag/libplctag](https://github.com/libplctag/libplctag) repository + (MIT license). It is **not** part of this repo's source tree; `Docker/Dockerfile` + clones libplctag at a pinned tag and builds the `ab_server` CMake target in a + multi-stage build. - **Launcher**: Docker (only supported path). `Docker/Dockerfile` - multi-stage-builds `ab_server` from source against a pinned libplctag + multi-stage-builds `ab_server` from source by cloning libplctag at a pinned tag + copies the binary into a slim runtime image. `Docker/docker-compose.yml` has per-family services (`controllogix` / `compactlogix` / `micro800` / `guardlogix`); all bind `:44818`. -- **Lifecycle**: `AbServerFixture` TCP-probes `127.0.0.1:44818` at - collection init + records a skip reason when unreachable. Tests skip - via `[AbServerFact]` / `[AbServerTheory]` which check the same probe. +- **Lifecycle**: `AbServerFixture` TCP-probes `10.100.0.35:44818` (the shared + Docker host) at collection init + records a skip reason when unreachable. + Tests skip via `[AbServerFact]` / `[AbServerTheory]` which check the same + probe. - **Profiles**: `KnownProfiles.{ControlLogix, CompactLogix, Micro800, GuardLogix}` in `AbServerProfile.cs` — thin Family + ComposeProfile + Notes records; the compose file is the canonical source of truth for which tags get @@ -71,12 +74,15 @@ Unit coverage: `AbCipAlarmProjectionTests` — fakes feed `InFaulted` / ### 3. Micro800 unconnected-only path -Micro800 profile `Notes`: *"ab_server has no --plc micro800 — falls back to -controllogix emulation."* +Micro800 profile `Notes`: *"--plc=Micro800 mode (unconnected-only, empty path). +Driver-side enforcement verified in the unit suite."* -The empty routing path + unconnected-session requirement (PR 11) is unit-tested -but never challenged at the CIP wire level. Real Micro800 (2080-series) on a -lab rig would be the authoritative benchmark. +The compose service boots `ab_server --plc=Micro800` with an empty routing path. +The unconnected-session requirement (PR 11) is validated at the driver unit-test +level via `FakeAbCipTagRuntime`; the wire-level contract (what happens when +a connected-send arrives at a real Micro800 backplane) is not exercised by the +simulator. Real Micro800 (2080-series) on a lab rig would be the authoritative +benchmark. ### 4. GuardLogix safety subsystem @@ -177,7 +183,7 @@ project is authored. | "Is my atomic read path wired correctly?" | yes | yes | yes | yes | | "Does whole-UDT grouping work?" | no | yes | **yes** | yes | | "Do ALMD alarms raise + clear?" | no | yes | **yes** | yes | -| "Is Micro800 unconnected-only enforced wire-side?" | no (emulated as CLX) | partial | yes | yes (required) | +| "Is Micro800 unconnected-only enforced wire-side?" | partial (--plc=Micro800 boots, but wire rejection untested) | partial | yes | yes (required) | | "Does GuardLogix reject non-safety writes on safety tags?" | no | no | yes (Emulate 5580) | yes | | "Does CompactLogix refuse oversized ConnectionSize?" | no | partial | yes (5370 firmware) | yes | | "Does BOOL-in-DINT RMW race against concurrent writers?" | no | yes | partial | yes (stress) |