Files
lmxopcua/tests/ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests/Docker/README.md

4.0 KiB

S7 integration-test fixture — python-snap7

python-snap7 Server class wrapped in a pinned python:3.12-slim-bookworm image. Docker is the only supported launch path — a fresh clone needs Docker Desktop and nothing else.

File Purpose
Dockerfile python:3.12-slim-bookworm + python-snap7>=2.0 + the server shim + the profile JSONs
docker-compose.yml One service per profile; currently only s7_1500
server.py Same Python shim the native fallback uses — copy kept in the build context
profiles/*.json Area-seed definitions (DB1 / MB layouts with typed seeds)

Run

From the repo root:

docker compose -f tests\ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests\Docker\docker-compose.yml --profile s7_1500 up

Detached + stop:

docker compose -f tests\...\Docker\docker-compose.yml --profile s7_1500 up -d
docker compose -f tests\...\Docker\docker-compose.yml --profile s7_1500 down

Endpoint

  • Default: localhost:1102 (non-privileged; sidesteps Windows Firewall prompt + Linux's root-required bind on port 102).
  • Override with S7_SIM_ENDPOINT to point at a real S7 CPU on :102.
  • The driver's S7DriverOptions.Port flows through S7netplus's 5-arg Plc(CpuType, host, port, rack, slot) ctor so the non-standard port works end-to-end.

Run the integration tests

In a separate shell with the container up:

cd C:\Users\dohertj2\Desktop\lmxopcua
dotnet test tests\ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests

Snap7ServerFixture probes localhost:1102 at collection init + records a SkipReason when unreachable, so tests stay green on a fresh clone without Docker running.

What's encoded in profiles/s7_1500.json

DB1 (1024 bytes) + MB (256 bytes) with typed seeds at known offsets:

Address Type Seed Purpose
DB1.DBW0 u16 4242 read-back probe
DB1.DBW10 i16 -12345 smoke i16 read
DB1.DBD20 i32 1234567890 smoke i32 read
DB1.DBD30 f32 3.14159 smoke f32 read (big-endian)
DB1.DBX50.3 bool true smoke bool read at bit 3
DB1.DBW100 u16 0 scratch for write-then-read
DB1.STRING[200] S7 STRING "Hello" S7 STRING read
MW0 u16 1 S7ProbeOptions.ProbeAddress default

Seed types supported: u8, i8, u16, i16, u32, i32, f32, bool (with "bit": 0..7), ascii (S7 STRING).

Negotiated PDU size

Snap7's Server always negotiates a fixed 240-byte PDU during the COTP/S7comm handshake (the legacy default — Snap7 does not implement the S7-1500 extended-PDU negotiation). The S7 driver surfaces this value through DriverHealth.Diagnostics["S7.NegotiatedPduSize"], exercised by S7_1500DiagnosticsTests.Driver_exposes_negotiated_pdu_size_post_init.

Operators inspecting a driver against this fixture should therefore see S7.NegotiatedPduSize = 240. Real S7-1500 CPUs running the extended PDU report 480 or 960; that branch is hardware-only and not exercised here.

Known limitations

From the snap7.server.Server docstring upstream:

"Legacy S7 server implementation. Emulates a Siemens S7 PLC for testing and development purposes. [...] pure Python emulator implementation that simulates PLC behaviour for protocol compliance testing rather than full industrial-grade functionality."

Not exercised here — needs a lab rig:

  • S7-1500 Optimized-DB symbolic access
  • PG / OP / S7-Basic session-type differentiation
  • PUT/GET-disabled-by-default enforcement

See docs/drivers/S7-Test-Fixture.md for the full coverage map.

References