Files
wago-modbustcp-simulator-py/tests/test_integration_pymodbus.py
T
2026-10-03 09:46:11 +02:00

87 lines
3.2 KiB
Python

"""Integration test: pymodbus as an independent Modbus TCP master.
Verifies the simulator against a third-party client implementation
(rather than our own codec) — the strongest interop check for FAT use.
Uses the pymodbus 3.15 async client API (device_id= keyword).
"""
from __future__ import annotations
import asyncio
import pytest
pymodbus = pytest.importorskip("pymodbus")
from pymodbus.client import AsyncModbusTcpClient # noqa: E402
async def _start(app, port=15021):
app.server.host, app.server.port = "127.0.0.1", port
await app.server.start()
await asyncio.sleep(0.05)
class TestPymodbusInterop:
async def test_constants_via_pymodbus(self, app):
await _start(app)
client = AsyncModbusTcpClient("127.0.0.1", port=15021)
assert await client.connect()
try:
rr = await client.read_holding_registers(0x2000, count=9, device_id=1)
assert not rr.isError()
assert rr.registers == [0x0000, 0xFFFF, 0x1234, 0xAAAA, 0x5555,
0x7FFF, 0x8000, 0x3FFF, 0x4000]
finally:
client.close()
await app.server.stop()
async def test_write_read_process_image(self, app):
await _start(app)
client = AsyncModbusTcpClient("127.0.0.1", port=15021)
assert await client.connect()
try:
# write holding register 0 (-> output %QW0)
await client.write_register(0, 0x1234, device_id=1)
# read back via the input-register mirror at +0x0200
rr = await client.read_input_registers(0x0200, count=1, device_id=1)
assert rr.registers == [0x1234]
# coil write & read-back mirror at 0x0200
await client.write_coil(3, True, device_id=1)
rr = await client.read_coils(0x0200, count=8, device_id=1)
assert rr.bits[3] is True
finally:
client.close()
await app.server.stop()
async def test_illegal_address_exception(self, app):
await _start(app)
client = AsyncModbusTcpClient("127.0.0.1", port=15021)
assert await client.connect()
try:
rr = await client.read_holding_registers(0x0100, count=1, device_id=1)
assert rr.isError()
assert rr.exception_code == 0x02
finally:
client.close()
await app.server.stop()
async def test_read_write_multiple_registers(self, app):
await _start(app)
client = AsyncModbusTcpClient("127.0.0.1", port=15021)
assert await client.connect()
try:
# FC23: read the constant 0x1234 at 0x2002 while writing %QW0
rr = await client.readwrite_registers(
read_address=0x2002, read_count=1,
write_address=0x0000, values=[0xBEEF],
device_id=1,
)
assert not rr.isError()
assert rr.registers == [0x1234]
# the write part landed in the output image -> mirror at 0x0200
rr = await client.read_input_registers(0x0200, count=1, device_id=1)
assert rr.registers == [0xBEEF]
finally:
client.close()
await app.server.stop()