docs(audit): AbServer-Test-Fixture.md — accuracy pass
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.
This commit is contained in:
@@ -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) |
|
||||
|
||||
Reference in New Issue
Block a user