From 9726a58213f14201845431c6bbac93ea7c1fcdcc Mon Sep 17 00:00:00 2001 From: Stuart Longland Date: Thu, 4 Jun 2015 09:44:27 +1000 Subject: [PATCH 1/4] WriteMultipleRegistersRequest: Handle values=None case Currently, if None is passed in explicitly, or if values is not given, the 'values' object is correctly identified as *not* having an __iter__ attribute, but is incorrectly identified as being a valid register value. This breaks testInvalidWriteMultipleRegistersRequest. Solution: if we see None, replace this with [] and skip the check for __iter__. --- pymodbus/register_write_message.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pymodbus/register_write_message.py b/pymodbus/register_write_message.py index 4ff21ac9c..b49db4901 100644 --- a/pymodbus/register_write_message.py +++ b/pymodbus/register_write_message.py @@ -132,9 +132,11 @@ def __init__(self, address=None, values=None, **kwargs): ''' ModbusRequest.__init__(self, **kwargs) self.address = address - self.values = values or [] - if not hasattr(values, '__iter__'): - self.values = [values] + if values is None: + values = [] + elif not hasattr(values, '__iter__'): + values = [values] + self.values = values self.count = len(self.values) self.byte_count = self.count * 2 From 356b2255688931ef38fb556375300c6c6e630bfe Mon Sep 17 00:00:00 2001 From: Stuart Longland Date: Thu, 4 Jun 2015 12:52:47 +1000 Subject: [PATCH 2/4] Fix payload tests. Looking at the "encoded" string, it looks identical to that of the big endian encoding string, and my understanding is that the data shown in "encoded" *IS* big-endian, not little-endian. I have no idea how this passed before, but it passes now. --- test/test_payload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_payload.py b/test/test_payload.py index 453d82fce..302df5824 100644 --- a/test/test_payload.py +++ b/test/test_payload.py @@ -144,7 +144,7 @@ def testPayloadDecoderRegisterFactory(self): ''' Test the payload decoder reset functionality ''' payload = [1,2,3,4] decoder = BinaryPayloadDecoder.fromRegisters(payload, endian=Endian.Little) - encoded = '\x00\x01\x00\x02\x00\x03\x00\x04' + encoded = '\x01\x00\x02\x00\x03\x00\x04\x00' self.assertEqual(encoded, decoder.decode_string(8)) decoder = BinaryPayloadDecoder.fromRegisters(payload, endian=Endian.Big) From 32638011c4f81ed1b1475cb1a6c08f2f2525bc83 Mon Sep 17 00:00:00 2001 From: Stuart Longland Date: Thu, 4 Jun 2015 13:06:32 +1000 Subject: [PATCH 3/4] sync.ModbusUdpClient: Correct reference to settimeout. I could not find a 'settimeout' (case-insensitive) anywhere in the codebase other than on this line, but I *did* see it was a method of socket.socket. So I'll assume that this was *supposed* to be calling socket.socket.settimeout. --- pymodbus/client/sync.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymodbus/client/sync.py b/pymodbus/client/sync.py index 9f05c1151..079b4e9b7 100644 --- a/pymodbus/client/sync.py +++ b/pymodbus/client/sync.py @@ -228,7 +228,7 @@ def connect(self): try: family = ModbusUdpClient._get_address_family(self.host) self.socket = socket.socket(family, socket.SOCK_DGRAM) - self.settimeout(self.timeout) + self.socket.settimeout(self.timeout) except socket.error, ex: _logger.error('Unable to create udp socket %s' % ex) self.close() From e27dbb4de7ab2c1af58caf3d276a164815255b16 Mon Sep 17 00:00:00 2001 From: Stuart Longland Date: Thu, 4 Jun 2015 13:07:50 +1000 Subject: [PATCH 4/4] test-client-sync: Fix UDP connection test. Rather than passing in a vanilla object, we should pass in something that implements the settimeout method. --- test/test_client_sync.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/test_client_sync.py b/test/test_client_sync.py index e03ecaf98..6f118d282 100644 --- a/test/test_client_sync.py +++ b/test/test_client_sync.py @@ -97,7 +97,10 @@ def testUdpClientAddressFamily(self): def testUdpClientConnect(self): ''' Test the Udp client connection method''' with patch.object(socket, 'socket') as mock_method: - mock_method.return_value = object() + class DummySocket(object): + def settimeout(self, *a, **kwa): + pass + mock_method.return_value = DummySocket() client = ModbusUdpClient() self.assertTrue(client.connect())