From 8d062ca89172ddc3761edbc2ee57e6c659f5e7fb Mon Sep 17 00:00:00 2001 From: jan iversen Date: Fri, 4 Oct 2024 22:46:18 +0200 Subject: [PATCH] AsyncFramer. --- pymodbus/framer/__init__.py | 4 +- pymodbus/framer/framer.py | 2 +- test/framers/conftest.py | 8 ++-- test/framers/test_framer.py | 74 ++++++++++++++++++------------------- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/pymodbus/framer/__init__.py b/pymodbus/framer/__init__.py index e6f8c36e30..7340d1b139 100644 --- a/pymodbus/framer/__init__.py +++ b/pymodbus/framer/__init__.py @@ -7,11 +7,11 @@ "ModbusRtuFramer", "ModbusSocketFramer", "ModbusTlsFramer", - "Framer", + "AsyncFramer", "FramerType", ] -from pymodbus.framer.framer import Framer, FramerType +from pymodbus.framer.framer import AsyncFramer, FramerType from pymodbus.framer.old_framer_ascii import ModbusAsciiFramer from pymodbus.framer.old_framer_base import ModbusFramer from pymodbus.framer.old_framer_rtu import ModbusRtuFramer diff --git a/pymodbus/framer/framer.py b/pymodbus/framer/framer.py index b2f8be8000..18de3a10da 100644 --- a/pymodbus/framer/framer.py +++ b/pymodbus/framer/framer.py @@ -30,7 +30,7 @@ class FramerType(str, Enum): TLS = "tls" -class Framer(ModbusProtocol): +class AsyncFramer(ModbusProtocol): """Framer layer extending transport layer. extends the ModbusProtocol to handle receiving and sending of complete modbus PDU. diff --git a/test/framers/conftest.py b/test/framers/conftest.py index e5cb9304d1..860ec3ffdb 100644 --- a/test/framers/conftest.py +++ b/test/framers/conftest.py @@ -6,7 +6,7 @@ import pytest from pymodbus.factory import ClientDecoder, ServerDecoder -from pymodbus.framer import Framer, FramerType +from pymodbus.framer import AsyncFramer, FramerType from pymodbus.transport import CommParams @@ -20,11 +20,11 @@ def prepare_is_server(): """Return client/server.""" return False -@mock.patch.multiple(Framer, __abstractmethods__=set()) # eliminate abstract methods (callbacks) -@pytest.fixture(name="dummy_framer") +@mock.patch.multiple(AsyncFramer, __abstractmethods__=set()) # eliminate abstract methods (callbacks) +@pytest.fixture(name="dummy_async_framer") async def prepare_test_framer(entry, is_server): """Return framer object.""" - framer = Framer(entry, CommParams(), is_server, [0, 1]) # type: ignore[abstract] + framer = AsyncFramer(entry, CommParams(), is_server, [0, 1]) # type: ignore[abstract] framer.send = mock.Mock() # type: ignore[method-assign] if entry == FramerType.RTU: func_table = (ServerDecoder if is_server else ClientDecoder)().lookup # type: ignore[attr-defined] diff --git a/test/framers/test_framer.py b/test/framers/test_framer.py index 2ba0020ca6..eab689bd44 100644 --- a/test/framers/test_framer.py +++ b/test/framers/test_framer.py @@ -15,9 +15,9 @@ class TestFramer: """Test module.""" @pytest.mark.parametrize(("entry"), list(FramerType)) - async def test_framer_init(self, dummy_framer): + async def test_framer_init(self, dummy_async_framer): """Test framer type.""" - assert dummy_framer.handle + assert dummy_async_framer.handle @pytest.mark.parametrize(("data", "res_len", "cx", "rc"), [ (b'12345', 5, 1, [(5, 0, 0, b'12345')]), # full frame @@ -29,35 +29,35 @@ async def test_framer_init(self, dummy_framer): (b'12345678', 5, 0, [(5, 0, 0, b'')]), # garble first, not full frame (b'12345678', 8, 0, [(8, 0, 0, b'')]), # garble first, faulty frame ]) - async def test_framer_callback(self, dummy_framer, data, res_len, cx, rc): + async def test_framer_callback(self, dummy_async_framer, data, res_len, cx, rc): """Test framer type.""" - dummy_framer.callback_request_response = mock.Mock() - dummy_framer.handle.decode = mock.MagicMock(side_effect=iter(rc)) - assert dummy_framer.callback_data(data) == res_len - assert dummy_framer.callback_request_response.call_count == cx + dummy_async_framer.callback_request_response = mock.Mock() + dummy_async_framer.handle.decode = mock.MagicMock(side_effect=iter(rc)) + assert dummy_async_framer.callback_data(data) == res_len + assert dummy_async_framer.callback_request_response.call_count == cx if cx: - dummy_framer.callback_request_response.assert_called_with(b'12345', 0, 0) + dummy_async_framer.callback_request_response.assert_called_with(b'12345', 0, 0) else: - dummy_framer.callback_request_response.assert_not_called() + dummy_async_framer.callback_request_response.assert_not_called() @pytest.mark.parametrize(("data", "res_len", "rc"), [ (b'12345', 5, [(5, 0, 17, b'12345'), (0, 0, 0, b'')]), # full frame, wrong dev_id ]) - async def test_framer_callback_wrong_id(self, dummy_framer, data, res_len, rc): + async def test_framer_callback_wrong_id(self, dummy_async_framer, data, res_len, rc): """Test framer type.""" - dummy_framer.callback_request_response = mock.Mock() - dummy_framer.handle.decode = mock.MagicMock(side_effect=iter(rc)) - dummy_framer.broadcast = False - assert dummy_framer.callback_data(data) == res_len - dummy_framer.callback_request_response.assert_not_called() + dummy_async_framer.callback_request_response = mock.Mock() + dummy_async_framer.handle.decode = mock.MagicMock(side_effect=iter(rc)) + dummy_async_framer.broadcast = False + assert dummy_async_framer.callback_data(data) == res_len + dummy_async_framer.callback_request_response.assert_not_called() - async def test_framer_build_send(self, dummy_framer): + async def test_framer_build_send(self, dummy_async_framer): """Test framer type.""" - dummy_framer.handle.encode = mock.MagicMock(return_value=(b'decode')) - dummy_framer.build_send(b'decode', 1, 0) - dummy_framer.handle.encode.assert_called_once() - dummy_framer.send.assert_called_once() - dummy_framer.send.assert_called_with(b'decode', None) + dummy_async_framer.handle.encode = mock.MagicMock(return_value=(b'decode')) + dummy_async_framer.build_send(b'decode', 1, 0) + dummy_async_framer.handle.encode.assert_called_once() + dummy_async_framer.send.assert_called_once() + dummy_async_framer.send.assert_called_with(b'decode', None) @pytest.mark.parametrize( ("data", "res_len", "res_id", "res_tid", "res_data"), [ @@ -65,9 +65,9 @@ async def test_framer_build_send(self, dummy_framer): (b'\x01\x02\x03', 3, 1, 2, b'\x03'), (b'\x04\x05\x06\x07\x08\x09\x00\x01\x02\x03', 10, 4, 5, b'\x06\x07\x08\x09\x00\x01\x02\x03'), ]) - async def test_framer_decode(self, dummy_framer, data, res_id, res_tid, res_len, res_data): + async def test_framer_decode(self, dummy_async_framer, data, res_id, res_tid, res_len, res_data): """Test decode method in all types.""" - t_len, t_id, t_tid, t_data = dummy_framer.handle.decode(data) + t_len, t_id, t_tid, t_data = dummy_async_framer.handle.decode(data) assert res_len == t_len assert res_id == t_id assert res_tid == t_tid @@ -78,9 +78,9 @@ async def test_framer_decode(self, dummy_framer, data, res_id, res_tid, res_len (b'\x01\x02', 5, 6, b'\x05\x06\x01\x02'), (b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09', 17, 25, b'\x11\x19\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09'), ]) - async def test_framer_encode(self, dummy_framer, data, dev_id, tr_id, res_data): + async def test_framer_encode(self, dummy_async_framer, data, dev_id, tr_id, res_data): """Test decode method in all types.""" - t_data = dummy_framer.handle.encode(data, dev_id, tr_id) + t_data = dummy_async_framer.handle.encode(data, dev_id, tr_id) assert res_data == t_data @pytest.mark.parametrize( @@ -293,28 +293,28 @@ def test_encode_type(self, frame, frame_expected, data, dev_id, tr_id, inx1, inx "single", ] ) - async def test_decode_type(self, entry, dummy_framer, data, dev_id, tr_id, expected, split): + async def test_decode_type(self, entry, dummy_async_framer, data, dev_id, tr_id, expected, split): """Test encode method.""" if entry == FramerType.TLS and split != "no": return if entry == FramerType.RTU: return - dummy_framer.callback_request_response = mock.MagicMock() + dummy_async_framer.callback_request_response = mock.MagicMock() if split == "no": - used_len = dummy_framer.callback_data(data) + used_len = dummy_async_framer.callback_data(data) elif split == "half": split_len = int(len(data) / 2) - assert not dummy_framer.callback_data(data[0:split_len]) - dummy_framer.callback_request_response.assert_not_called() - used_len = dummy_framer.callback_data(data) + assert not dummy_async_framer.callback_data(data[0:split_len]) + dummy_async_framer.callback_request_response.assert_not_called() + used_len = dummy_async_framer.callback_data(data) else: last = len(data) for i in range(0, last -1): - assert not dummy_framer.callback_data(data[0:i+1]) - dummy_framer.callback_request_response.assert_not_called() - used_len = dummy_framer.callback_data(data) + assert not dummy_async_framer.callback_data(data[0:i+1]) + dummy_async_framer.callback_request_response.assert_not_called() + used_len = dummy_async_framer.callback_data(data) assert used_len == len(data) - dummy_framer.callback_request_response.assert_called_with(expected, dev_id, tr_id) + dummy_async_framer.callback_request_response.assert_called_with(expected, dev_id, tr_id) @pytest.mark.parametrize( ("entry", "data", "exp"), @@ -382,9 +382,9 @@ async def test_decode_type(self, entry, dummy_framer, data, dev_id, tr_id, expec # ]), ] ) - async def test_decode_complicated(self, dummy_framer, data, exp): + async def test_decode_complicated(self, dummy_async_framer, data, exp): """Test encode method.""" for ent in exp: - used_len, _, _, res_data = dummy_framer.handle.decode(data) + used_len, _, _, res_data = dummy_async_framer.handle.decode(data) assert used_len == ent[0] assert res_data == ent[1]