Skip to content

Commit

Permalink
Client more robust against faulty response. (#1547)
Browse files Browse the repository at this point in the history
  • Loading branch information
janiversen authored May 24, 2023
1 parent d347bc8 commit 4334930
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
1 change: 1 addition & 0 deletions pymodbus/framer/socket_framer.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ def _process(self, callback, tid, error=False):
"""Process incoming packets irrespective error condition."""
data = self.getRawFrame() if error else self.getFrame()
if (result := self.decoder.decode(data)) is None:
self.resetFrame()
raise ModbusIOException("Unable to decode request")
if error and result.function_code < 0x80:
raise InvalidMessageReceivedException(result)
Expand Down
40 changes: 40 additions & 0 deletions test/test_client_faulty_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Test server working as slave on a multidrop RS485 line."""
from unittest import mock

import pytest

from pymodbus.exceptions import ModbusIOException
from pymodbus.factory import ClientDecoder
from pymodbus.framer import ModbusSocketFramer


class TestFaultyResponses:
"""Test that server works on a multidrop line."""

slaves = [0]

good_frame = b"\x00\x01\x00\x00\x00\x05\x00\x03\x02\x00\x01"

@pytest.fixture(name="framer")
def fixture_framer(self):
"""Prepare framer."""
return ModbusSocketFramer(ClientDecoder())

@pytest.fixture(name="callback")
def fixture_callback(self):
"""Prepare dummy callback."""
return mock.Mock()

def test_ok_frame(self, framer, callback):
"""Test ok frame."""
framer.processIncomingPacket(self.good_frame, callback, self.slaves)
callback.assert_called_once()

def test_faulty_frame1(self, framer, callback):
"""Test ok frame."""
faulty_frame = b"\x00\x04\x00\x00\x00\x05\x00\x03\x0a\x00\x04"
with pytest.raises(ModbusIOException):
framer.processIncomingPacket(faulty_frame, callback, self.slaves)
callback.assert_not_called()
framer.processIncomingPacket(self.good_frame, callback, self.slaves)
callback.assert_called_once()
File renamed without changes.

0 comments on commit 4334930

Please sign in to comment.