AB CIP integration-test fixture — ab_server (Docker)
libplctag's ab_server — a
MIT-licensed C program that emulates a ControlLogix / CompactLogix CIP
endpoint over EtherNet/IP. Docker is the only supported launch path;
ab_server ships as a source-only tool under libplctag's
src/tools/ab_server/ so the Dockerfile's multi-stage build is the only
reproducible way to get a working binary across developer boxes. A fresh
clone needs Docker Desktop and nothing else.
| File | Purpose |
|---|---|
Dockerfile |
Multi-stage: build from libplctag at pinned tag → copy binary into debian:bookworm-slim runtime image |
docker-compose.yml |
One service per family (controllogix / compactlogix / micro800 / guardlogix); all bind :44818 |
Run
From the repo root:
# ControlLogix — widest-coverage profile
docker compose -f tests\ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests\Docker\docker-compose.yml --profile controllogix up
# Per-family
docker compose -f tests\...\Docker\docker-compose.yml --profile compactlogix up
docker compose -f tests\...\Docker\docker-compose.yml --profile micro800 up
docker compose -f tests\...\Docker\docker-compose.yml --profile guardlogix up
Detached + stop:
docker compose -f tests\...\Docker\docker-compose.yml --profile controllogix up -d
docker compose -f tests\...\Docker\docker-compose.yml --profile controllogix down
First run builds the image (~3-5 minutes — clones libplctag + compiles
ab_server + its dependencies). Subsequent runs are fast because the
multi-stage build layer-caches the checkout + compile.
Endpoint
- Default:
localhost:44818(EtherNet/IP standard; non-privileged) - Override with
AB_SERVER_ENDPOINT=host:portto point at a real PLC.
Run the integration tests
In a separate shell with a container up:
cd C:\Users\dohertj2\Desktop\lmxopcua
dotnet test tests\ZB.MOM.WW.OtOpcUa.Driver.AbCip.IntegrationTests
AbServerFixture TCP-probes localhost:44818 at collection init +
records a skip reason when unreachable, so tests stay green on a fresh
clone without the container running. Tests use [AbServerFact] /
[AbServerTheory] which check the same probe.
What each family seeds
Tag sets match AbServerProfile.cs exactly — changing seeds in one
place means updating both.
| Family | Seeded tags | Notes |
|---|---|---|
| ControlLogix | TestDINT TestREAL TestBOOL TestSINT TestString TestArray |
Widest-coverage; PR 9 baseline. UDT emulation missing from ab_server |
| CompactLogix | TestDINT TestREAL TestBOOL |
Narrow ConnectionSize cap enforced driver-side; ab_server accepts any size |
| Micro800 | TestDINT TestREAL |
ab_server has no micro800 mode; falls back to controllogix emulation |
| GuardLogix | TestDINT SafetyDINT_S |
ab_server has no safety subsystem; _S suffix triggers driver-side classification only |
Known limitations
- No UDT / CIP Template Object emulation —
ab_servercovers atomic types only. UDT reads + task #194 whole-UDT optimization verify via unit tests with golden byte buffers. - Family-specific quirks trust driver-side code — ab_server emulates a generic Logix CPU; the ConnectionSize cap, empty-path unconnected mode, and safety-partition write rejection all need lab rigs for wire-level proof.
See docs/drivers/AbServer-Test-Fixture.md
for the full coverage map.
References
- libplctag on GitHub
docs/drivers/AbServer-Test-Fixture.md— coverage mapdocs/v2/dev-environment.md§Docker fixtures