def setUp(self): ''' Sets up the test environment ''' self.client = None self.decoder = ServerDecoder() self._tcp = ModbusSocketFramer(decoder=self.decoder) self._rtu = ModbusRtuFramer(decoder=self.decoder) self._ascii = ModbusAsciiFramer(decoder=self.decoder) self._binary = ModbusBinaryFramer(decoder=self.decoder) self._manager = DictTransactionManager(self.client) self._queue_manager = FifoTransactionManager(self.client) self._tm = ModbusTransactionManager(self.client)
def __init__(self, framer=None): ''' Initializes the framer module :param framer: The framer to use for the protocol ''' self.framer = framer or ModbusSocketFramer(ClientDecoder()) self._requests = deque() # link queue to tid
class ModbusTcpClientProtocol(ModbusClientProtocol): """ Async TCP Client protocol based on twisted. Default framer: ModbusSocketFramer """ framer = ModbusSocketFramer(ClientDecoder())
def __init__(self, framer=ModbusSocketFramer(ClientDecoder())): ''' Initializes the framer module :param framer: The framer to use for the protocol ''' self.done = False self.framer = framer
def main(): """ The main runner function """ options = get_options() if options.debug: try: log.setLevel(logging.DEBUG) logging.basicConfig() except Exception as ex: print("Logging is not supported on this system") # split the query into a starting and ending range query = [int(p) for p in options.query.split(':')] try: log.debug("Initializing the client") framer = ModbusSocketFramer(ClientDecoder()) reader = LoggingContextReader(options.output) factory = ScraperFactory(framer, reader, query) # how to connect based on TCP vs Serial clients if isinstance(framer, ModbusSocketFramer): reactor.connectTCP(options.host, options.port, factory) else: SerialModbusClient(factory, options.port, reactor) log.debug("Starting the client") reactor.run() log.debug("Finished scraping the client") except Exception as ex: print(ex)
def __init__(self, framer=None): ''' Initializes the framer module :param framer: The framer to use for the protocol ''' self.framer = framer or ModbusSocketFramer(ClientDecoder()) serial = not isinstance(framer, ModbusSocketFramer) self.transaction = ModbusTransactionManager(self, serial)
def testClientProtocolConnect(self): ''' Test the client protocol connect ''' decoder = object() framer = ModbusSocketFramer(decoder) protocol = ModbusClientProtocol(framer=framer) self.assertFalse(protocol._connected) protocol.connectionMade() self.assertTrue(protocol._connected)
def __init__(self, framer=None, **kwargs): self._connected = False self.framer = framer or ModbusSocketFramer(ClientDecoder()) if isinstance(self.framer, type): # Framer class not instance self.framer = self.framer(ClientDecoder(), client=None) if isinstance(self.framer, ModbusSocketFramer): self.transaction = DictTransactionManager(self, **kwargs) else: self.transaction = FifoTransactionManager(self, **kwargs)
def __init__(self, host='127.0.0.1', port=Defaults.Port): ''' Initialize a client instance :param host: The host to connect to (default 127.0.0.1) :param port: The modbus port to connect to (default 502) ''' self.host = host self.port = port self.socket = None BaseModbusClient.__init__(self, ModbusSocketFramer(ClientDecoder()))
def __init__(self, framer=None): ''' Initializes the framer module :param framer: The framer to use for the protocol ''' self.framer = framer or ModbusSocketFramer(ClientDecoder()) if isinstance(self.framer, ModbusSocketFramer): self.transaction = DictTransactionManager(self) else: self.transaction = FifoTransactionManager(self)
def setUp(self): """ Sets up the test environment """ self.client = None self.decoder = ServerDecoder() self._tcp = ModbusSocketFramer(decoder=self.decoder, client=None) self._rtu = ModbusRtuFramer(decoder=self.decoder, client=None) self._ascii = ModbusAsciiFramer(decoder=self.decoder, client=None) self._binary = ModbusBinaryFramer(decoder=self.decoder, client=None) self._manager = DictTransactionManager(self.client) self._queue_manager = FifoTransactionManager(self.client) self._tm = ModbusTransactionManager(self.client)
def __init__(self, framer=None, **kwargs): """ Initializes the framer module :param framer: The framer to use for the protocol """ deprecated(self.__class__.__name__) self.framer = framer or ModbusSocketFramer(ClientDecoder()) if isinstance(self.framer, ModbusSocketFramer): self.transaction = DictTransactionManager(self, **kwargs) else: self.transaction = FifoTransactionManager(self, **kwargs)
def __init__(self, framer=None, **kwargs): """ Initializes the framer module :param framer: The framer to use for the protocol. Default: ModbusSocketFramer :type framer: pymodbus.transaction.ModbusSocketFramer """ self._connected = False super(BaseAsyncModbusClient, self).__init__(framer or ModbusSocketFramer(ClientDecoder()), **kwargs)
def testClientProtocolExecute(self): ''' Test the client protocol execute method ''' framer = ModbusSocketFramer(None) protocol = ModbusClientProtocol(framer=framer) protocol.connectionMade() protocol.transport = Mock() protocol.transport.write = Mock() request = ReadCoilsRequest(1, 1) d = protocol.execute(request) tid = request.transaction_id self.assertEqual(d, protocol.transaction.getTransaction(tid))
def __implementation(method): ''' Returns the requested framer :method: The serial framer to instantiate :returns: The requested serial framer ''' method = method.lower() if method == 'ascii': return ModbusAsciiFramer(ClientDecoder()) elif method == 'rtu': return ModbusRtuFramer(ClientDecoder()) elif method == 'binary': return ModbusBinaryFramer(ClientDecoder()) elif method == 'socket': return ModbusSocketFramer(ClientDecoder()) raise ParameterException("Invalid framer method requested")
def _framer(method): if method == "ascii": framer = ModbusAsciiFramer(ClientDecoder()) elif method == "rtu": framer = ModbusRtuFramer(ClientDecoder()) elif method == "binary": framer = ModbusBinaryFramer(ClientDecoder()) elif method == "socket": framer = ModbusSocketFramer(ClientDecoder()) else: framer = None return framer
def testClientProtocolExecute(self, protocol): ''' Test the client protocol execute method ''' framer = ModbusSocketFramer(None) protocol = protocol(framer=framer) transport = mock.MagicMock() protocol.connection_made(transport) protocol.transport.write = mock.Mock() request = ReadCoilsRequest(1, 1) d = protocol.execute(request) tid = request.transaction_id assert d == protocol.transaction.getTransaction(tid)
def testClientProtocolDataReceived(self): ''' Test the client protocol data received ''' protocol = ModbusClientProtocol(ModbusSocketFramer(ClientDecoder())) protocol.connectionMade() out = [] data = b'\x00\x00\x12\x34\x00\x06\xff\x01\x01\x02\x00\x04' # setup existing request d = protocol._buildResponse(0x00) d.addCallback(lambda v: out.append(v)) protocol.dataReceived(data) self.assertTrue(isinstance(out[0], ReadCoilsResponse))
def __init__(self, framer=None, **kwargs): ''' Initializes the framer module :param framer: The framer to use for the protocol ''' self._connected = False self.framer = framer or ModbusSocketFramer(ClientDecoder()) if isinstance(self.framer, type): # Framer class not instance self.framer = self.framer(ClientDecoder(), client=None) if isinstance(self.framer, ModbusSocketFramer): self.transaction = DictTransactionManager(self, **kwargs) else: self.transaction = FifoTransactionManager(self, **kwargs)
def testClientProtocolConnectionMade(self, protocol): """ Test the client protocol close :return: """ protocol = protocol(ModbusSocketFramer(ClientDecoder())) transport = mock.MagicMock() factory = mock.MagicMock() if isinstance(protocol, ModbusUdpClientProtocol): protocol.factory = factory protocol.connection_made(transport) assert protocol.transport == transport assert protocol.connected if isinstance(protocol, ModbusUdpClientProtocol): assert protocol.factory.protocol_made_connection.call_count == 1
def testTcpTwistedClient(self): """ Test the TCP Twisted client :return: """ from twisted.internet import reactor with patch("twisted.internet.reactor") as mock_reactor: def test_callback(client): pass def test_errback(client): pass AsyncModbusTCPClient(schedulers.REACTOR, framer=ModbusSocketFramer(ClientDecoder()), callback=test_callback, errback=test_errback)
def testClientProtocolClose(self, protocol): """ Test the client protocol close :return: """ protocol = protocol(ModbusSocketFramer(ClientDecoder())) transport = mock.MagicMock() factory = mock.MagicMock() if isinstance(protocol, ModbusUdpClientProtocol): protocol.factory = factory protocol.connection_made(transport) assert protocol.transport == transport assert protocol.connected protocol.close() transport.close.assert_called_once_with() assert not protocol.connected
def testClientProtocolDataReceived(self, protocol): ''' Test the client protocol data received ''' protocol = protocol(ModbusSocketFramer(ClientDecoder())) transport = mock.MagicMock() protocol.connection_made(transport) assert protocol.transport == transport assert protocol.connected data = b'\x00\x00\x12\x34\x00\x06\xff\x01\x01\x02\x00\x04' # setup existing request d = protocol._buildResponse(0x00) if isinstance(protocol, ModbusClientProtocol): protocol.data_received(data) else: protocol.datagram_received(data, None) result = d.result() assert isinstance(result, ReadCoilsResponse)
def generator(max_num): framer = ModbusSocketFramer(None) for index in range(0, len(choosed_function)): path = 'GeneratedDataModbus\OriginDataModbus\Modbus_' + choosed_function[ index].func_name + '.txt' f_txt = open(path, 'w') for i in range(0, max_num): _arguments = dict() _arguments['protocol'] = 0x0000 _arguments['transaction'] = random_integer(1, pow(2, 16 - 1)) _arguments['unit'] = random_integer(1, 247) result = choosed_function[index](framer, _arguments) f_txt.write(str(result[0]) + '\n') f_txt.close()
def generator(max_num): framer = ModbusSocketFramer(None) for index in range(0, len(choosed_function)): path = 'Modbus_data\Origin_generated_data\Modbus_' + choosed_function[index].func_name + '_' \ + str(files_number('Modbus_data\Origin_generated_data', 'Modbus_' + choosed_function[index].func_name)+1) + '.txt' f_txt = open(path, 'w') for i in range(0, max_num): _arguments = dict() _arguments['protocol'] = 0x0000 _arguments['transaction'] = random_integer(1, pow(2, 16 - 1)) _arguments['unit'] = random_integer(1, 247) result = choosed_function[index](framer, _arguments) f_txt.write(str(result[0]) + '\n') # Just save request packets f_txt.close()
def iterate_generator(max_num): f_txt = open('Modbus_data\Origin_generated_data\modbus.txt', 'w') # field_names = ['request', 'response'] # writer = csv.DictWriter(f, fieldnames=field_names) # writer.writeheader() framer = ModbusSocketFramer(None) for i in range(0, max_num): index = random_integer(0, len(functions) - 1) _arguments = dict() _arguments['protocol'] = 0x0000 _arguments['transaction'] = random_integer(1, pow(2, 16 - 1)) _arguments['unit'] = random_integer(1, 247) result = functions[index](framer, _arguments) # writer.writerow({'request':result[0], 'response': result[1]}) f_txt.write(str(result[0]) + '\n') f_txt.close()
def testClientProtocolConnectionLost(self, protocol): ''' Test the client protocol connection lost''' framer = ModbusSocketFramer(None) protocol = protocol(framer=framer) transport = mock.MagicMock() factory = mock.MagicMock() if isinstance(protocol, ModbusUdpClientProtocol): protocol.factory = factory protocol.connection_made(transport) protocol.transport.write = mock.Mock() request = ReadCoilsRequest(1, 1) d = protocol.execute(request) protocol.connection_lost("REASON") excp = d.exception() assert (isinstance(excp, ConnectionException)) if isinstance(protocol, ModbusUdpClientProtocol): assert protocol.factory.protocol_lost_connection.call_count == 1
async def testClientProtocolExecute(self, protocol): ''' Test the client protocol execute method ''' import asyncio framer = ModbusSocketFramer(None) protocol = protocol(framer=framer) protocol.create_future = mock.MagicMock() fut = asyncio.Future() fut.set_result(fut) protocol.create_future.return_value = fut transport = mock.MagicMock() protocol.connection_made(transport) protocol.transport.write = mock.Mock() request = ReadCoilsRequest(1, 1) d = await protocol.execute(request) tid = request.transaction_id f = protocol.transaction.getTransaction(tid) assert d == f
def testUdpTornadoClient(self, mock_iostream, mock_ioloop): """ Test the udp tornado client client initialize """ protocol, future = AsyncModbusUDPClient(schedulers.IO_LOOP, framer=ModbusSocketFramer(ClientDecoder())) client = future.result() assert(isinstance(client, AsyncTornadoModbusUdoClient)) assert(0 == len(list(client.transaction))) assert(isinstance(client.framer, ModbusSocketFramer)) assert(client.port == 502) assert(client._connected) def handle_failure(failure): assert(isinstance(failure.exception(), ConnectionException)) d = client._build_response(0x00) d.add_done_callback(handle_failure) assert(client._connected) client.close() protocol.stop() assert(not client._connected)
def testClientProtocolConnectionLost(self, protocol): ''' Test the client protocol connection lost''' framer = ModbusSocketFramer(None) protocol = protocol(framer=framer, timeout=0) protocol.execute = mock.MagicMock() # future = asyncio.Future() # future.set_result(ReadCoilsResponse([1])) # protocol._execute = mock.MagicMock(side_effect=future) transport = mock.MagicMock() factory = mock.MagicMock() if isinstance(protocol, ModbusUdpClientProtocol): protocol.factory = factory protocol.connection_made(transport) protocol.transport.write = mock.Mock() request = ReadCoilsRequest(1, 1) d = protocol.execute(request) # d = await d protocol.connection_lost("REASON") excp = d.exception() assert (isinstance(excp, ConnectionException)) if isinstance(protocol, ModbusUdpClientProtocol): assert protocol.factory.protocol_lost_connection.call_count == 1
def main(output='datastore.pickle', port=502, host='127.0.0.1', device=0x01, range='0:1000', debug=False): """ The main runner function """ if debug: try: log.setLevel(logging.DEBUG) logging.basicConfig() except Exception as ex: print("Logging is not supported on this system") # split the query into a starting and ending range query = [int(p) for p in range.split(':')] global SLAVE SLAVE = device try: log.debug("Initializing the client") framer = ModbusSocketFramer(ClientDecoder()) reader = LoggingContextReader(output) factory = ScraperFactory(framer, reader, query) # how to connect based on TCP vs Serial clients if isinstance(framer, ModbusSocketFramer): reactor.connectTCP(host, port, factory) else: SerialModbusClient(factory, options.port, reactor) log.debug("Starting the client") reactor.run() log.debug("Finished scraping the client") except Exception as ex: print(ex)
class ModbusTransactionTest(unittest.TestCase): """ This is the unittest for the pymodbus.transaction module """ # ----------------------------------------------------------------------- # # Test Construction # ----------------------------------------------------------------------- # def setUp(self): """ Sets up the test environment """ self.client = None self.decoder = ServerDecoder() self._tcp = ModbusSocketFramer(decoder=self.decoder, client=None) self._rtu = ModbusRtuFramer(decoder=self.decoder, client=None) self._ascii = ModbusAsciiFramer(decoder=self.decoder, client=None) self._binary = ModbusBinaryFramer(decoder=self.decoder, client=None) self._manager = DictTransactionManager(self.client) self._queue_manager = FifoTransactionManager(self.client) self._tm = ModbusTransactionManager(self.client) def tearDown(self): """ Cleans up the test environment """ del self._manager del self._tcp del self._rtu del self._ascii # ----------------------------------------------------------------------- # # Base transaction manager # ----------------------------------------------------------------------- # def testCalculateExpectedResponseLength(self): self._tm.client = MagicMock() self._tm.client.framer = MagicMock() self._tm._set_adu_size() self.assertEqual(self._tm._calculate_response_length(0), None) self._tm.base_adu_size = 10 self.assertEqual(self._tm._calculate_response_length(5), 15) def testCalculateExceptionLength(self): for framer, exception_length in [('ascii', 11), ('binary', 7), ('rtu', 5), ('tcp', 9), ('dummy', None)]: self._tm.client = MagicMock() if framer == "ascii": self._tm.client.framer = self._ascii elif framer == "binary": self._tm.client.framer = self._binary elif framer == "rtu": self._tm.client.framer = self._rtu elif framer == "tcp": self._tm.client.framer = self._tcp else: self._tm.client.framer = MagicMock() self._tm._set_adu_size() self.assertEqual(self._tm._calculate_exception_length(), exception_length) def testExecute(self): client = MagicMock() client.framer = self._ascii client.framer._buffer = b'deadbeef' client.framer.processIncomingPacket = MagicMock() client.framer.processIncomingPacket.return_value = None client.framer.buildPacket = MagicMock() client.framer.buildPacket.return_value = b'deadbeef' client.framer.sendPacket = MagicMock() client.framer.sendPacket.return_value = len(b'deadbeef') request = MagicMock() request.get_response_pdu_size.return_value = 10 request.unit_id = 1 tm = ModbusTransactionManager(client) tm._recv = MagicMock(return_value=b'abcdef') self.assertEqual(tm.retries, 3) self.assertEqual(tm.retry_on_empty, False) # tm._transact = MagicMock() # some response # tm._transact.return_value = (b'abcdef', None) tm.getTransaction = MagicMock() tm.getTransaction.return_value = 'response' response = tm.execute(request) self.assertEqual(response, 'response') # No response tm._recv = MagicMock(return_value=b'abcdef') # tm._transact.return_value = (b'', None) tm.transactions = [] tm.getTransaction = MagicMock() tm.getTransaction.return_value = None response = tm.execute(request) self.assertIsInstance(response, ModbusIOException) # No response with retries tm.retry_on_empty = True tm._recv = MagicMock(side_effect=iter([b'', b'abcdef'])) # tm._transact.side_effect = [(b'', None), (b'abcdef', None)] response = tm.execute(request) self.assertIsInstance(response, ModbusIOException) # Unable to decode response tm._recv = MagicMock(side_effect=ModbusIOException()) # tm._transact.side_effect = [(b'abcdef', None)] client.framer.processIncomingPacket.side_effect = MagicMock(side_effect=ModbusIOException()) self.assertIsInstance(tm.execute(request), ModbusIOException) # ----------------------------------------------------------------------- # # Dictionary based transaction manager # ----------------------------------------------------------------------- # def testDictTransactionManagerTID(self): """ Test the dict transaction manager TID """ for tid in range(1, self._manager.getNextTID() + 10): self.assertEqual(tid+1, self._manager.getNextTID()) self._manager.reset() self.assertEqual(1, self._manager.getNextTID()) def testGetDictTransactionManagerTransaction(self): """ Test the dict transaction manager """ class Request: pass self._manager.reset() handle = Request() handle.transaction_id = self._manager.getNextTID() handle.message = b"testing" self._manager.addTransaction(handle) result = self._manager.getTransaction(handle.transaction_id) self.assertEqual(handle.message, result.message) def testDeleteDictTransactionManagerTransaction(self): """ Test the dict transaction manager """ class Request: pass self._manager.reset() handle = Request() handle.transaction_id = self._manager.getNextTID() handle.message = b"testing" self._manager.addTransaction(handle) self._manager.delTransaction(handle.transaction_id) self.assertEqual(None, self._manager.getTransaction(handle.transaction_id)) # ----------------------------------------------------------------------- # # Queue based transaction manager # ----------------------------------------------------------------------- # def testFifoTransactionManagerTID(self): """ Test the fifo transaction manager TID """ for tid in range(1, self._queue_manager.getNextTID() + 10): self.assertEqual(tid+1, self._queue_manager.getNextTID()) self._queue_manager.reset() self.assertEqual(1, self._queue_manager.getNextTID()) def testGetFifoTransactionManagerTransaction(self): """ Test the fifo transaction manager """ class Request: pass self._queue_manager.reset() handle = Request() handle.transaction_id = self._queue_manager.getNextTID() handle.message = b"testing" self._queue_manager.addTransaction(handle) result = self._queue_manager.getTransaction(handle.transaction_id) self.assertEqual(handle.message, result.message) def testDeleteFifoTransactionManagerTransaction(self): """ Test the fifo transaction manager """ class Request: pass self._queue_manager.reset() handle = Request() handle.transaction_id = self._queue_manager.getNextTID() handle.message = b"testing" self._queue_manager.addTransaction(handle) self._queue_manager.delTransaction(handle.transaction_id) self.assertEqual(None, self._queue_manager.getTransaction(handle.transaction_id)) # ----------------------------------------------------------------------- # # TCP tests # ----------------------------------------------------------------------- # def testTCPFramerTransactionReady(self): """ Test a tcp frame transaction """ msg = b"\x00\x01\x12\x34\x00\x04\xff\x02\x12\x34" self.assertFalse(self._tcp.isFrameReady()) self.assertFalse(self._tcp.checkFrame()) self._tcp.addToFrame(msg) self.assertTrue(self._tcp.isFrameReady()) self.assertTrue(self._tcp.checkFrame()) self._tcp.advanceFrame() self.assertFalse(self._tcp.isFrameReady()) self.assertFalse(self._tcp.checkFrame()) self.assertEqual(b'', self._ascii.getFrame()) def testTCPFramerTransactionFull(self): """ Test a full tcp frame transaction """ msg = b"\x00\x01\x12\x34\x00\x04\xff\x02\x12\x34" self._tcp.addToFrame(msg) self.assertTrue(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(msg[7:], result) self._tcp.advanceFrame() def testTCPFramerTransactionHalf(self): """ Test a half completed tcp frame transaction """ msg1 = b"\x00\x01\x12\x34\x00" msg2 = b"\x04\xff\x02\x12\x34" self._tcp.addToFrame(msg1) self.assertFalse(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(b'', result) self._tcp.addToFrame(msg2) self.assertTrue(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(msg2[2:], result) self._tcp.advanceFrame() def testTCPFramerTransactionHalf2(self): """ Test a half completed tcp frame transaction """ msg1 = b"\x00\x01\x12\x34\x00\x04\xff" msg2 = b"\x02\x12\x34" self._tcp.addToFrame(msg1) self.assertFalse(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(b'', result) self._tcp.addToFrame(msg2) self.assertTrue(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(msg2, result) self._tcp.advanceFrame() def testTCPFramerTransactionHalf3(self): """ Test a half completed tcp frame transaction """ msg1 = b"\x00\x01\x12\x34\x00\x04\xff\x02\x12" msg2 = b"\x34" self._tcp.addToFrame(msg1) self.assertFalse(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(msg1[7:], result) self._tcp.addToFrame(msg2) self.assertTrue(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(msg1[7:] + msg2, result) self._tcp.advanceFrame() def testTCPFramerTransactionShort(self): """ Test that we can get back on track after an invalid message """ msg1 = b"\x99\x99\x99\x99\x00\x01\x00\x01" msg2 = b"\x00\x01\x12\x34\x00\x04\xff\x02\x12\x34" self._tcp.addToFrame(msg1) self.assertFalse(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(b'', result) self._tcp.advanceFrame() self._tcp.addToFrame(msg2) self.assertEqual(10, len(self._tcp._buffer)) self.assertTrue(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(msg2[7:], result) self._tcp.advanceFrame() def testTCPFramerPopulate(self): """ Test a tcp frame packet build """ expected = ModbusRequest() expected.transaction_id = 0x0001 expected.protocol_id = 0x1234 expected.unit_id = 0xff msg = b"\x00\x01\x12\x34\x00\x04\xff\x02\x12\x34" self._tcp.addToFrame(msg) self.assertTrue(self._tcp.checkFrame()) actual = ModbusRequest() self._tcp.populateResult(actual) for name in ['transaction_id', 'protocol_id', 'unit_id']: self.assertEqual(getattr(expected, name), getattr(actual, name)) self._tcp.advanceFrame() def testTCPFramerPacket(self): """ Test a tcp frame packet build """ old_encode = ModbusRequest.encode ModbusRequest.encode = lambda self: b'' message = ModbusRequest() message.transaction_id = 0x0001 message.protocol_id = 0x1234 message.unit_id = 0xff message.function_code = 0x01 expected = b"\x00\x01\x12\x34\x00\x02\xff\x01" actual = self._tcp.buildPacket(message) self.assertEqual(expected, actual) ModbusRequest.encode = old_encode # ----------------------------------------------------------------------- # # RTU tests # ----------------------------------------------------------------------- # def testRTUFramerTransactionReady(self): """ Test if the checks for a complete frame work """ self.assertFalse(self._rtu.isFrameReady()) msg_parts = [b"\x00\x01\x00", b"\x00\x00\x01\xfc\x1b"] self._rtu.addToFrame(msg_parts[0]) self.assertTrue(self._rtu.isFrameReady()) self.assertFalse(self._rtu.checkFrame()) self._rtu.addToFrame(msg_parts[1]) self.assertTrue(self._rtu.isFrameReady()) self.assertTrue(self._rtu.checkFrame()) def testRTUFramerTransactionFull(self): """ Test a full rtu frame transaction """ msg = b"\x00\x01\x00\x00\x00\x01\xfc\x1b" stripped_msg = msg[1:-2] self._rtu.addToFrame(msg) self.assertTrue(self._rtu.checkFrame()) result = self._rtu.getFrame() self.assertEqual(stripped_msg, result) self._rtu.advanceFrame() def testRTUFramerTransactionHalf(self): """ Test a half completed rtu frame transaction """ msg_parts = [b"\x00\x01\x00", b"\x00\x00\x01\xfc\x1b"] stripped_msg = b"".join(msg_parts)[1:-2] self._rtu.addToFrame(msg_parts[0]) self.assertFalse(self._rtu.checkFrame()) self._rtu.addToFrame(msg_parts[1]) self.assertTrue(self._rtu.isFrameReady()) self.assertTrue(self._rtu.checkFrame()) result = self._rtu.getFrame() self.assertEqual(stripped_msg, result) self._rtu.advanceFrame() def testRTUFramerPopulate(self): """ Test a rtu frame packet build """ request = ModbusRequest() msg = b"\x00\x01\x00\x00\x00\x01\xfc\x1b" self._rtu.addToFrame(msg) self._rtu.populateHeader() self._rtu.populateResult(request) header_dict = self._rtu._header self.assertEqual(len(msg), header_dict['len']) self.assertEqual(byte2int(msg[0]), header_dict['uid']) self.assertEqual(msg[-2:], header_dict['crc']) self.assertEqual(0x00, request.unit_id) def testRTUFramerPacket(self): """ Test a rtu frame packet build """ old_encode = ModbusRequest.encode ModbusRequest.encode = lambda self: b'' message = ModbusRequest() message.unit_id = 0xff message.function_code = 0x01 expected = b"\xff\x01\x81\x80" # only header + CRC - no data actual = self._rtu.buildPacket(message) self.assertEqual(expected, actual) ModbusRequest.encode = old_encode def testRTUDecodeException(self): """ Test that the RTU framer can decode errors """ message = b"\x00\x90\x02\x9c\x01" actual = self._rtu.addToFrame(message) result = self._rtu.checkFrame() self.assertTrue(result) def testProcess(self): class MockResult(object): def __init__(self, code): self.function_code = code def mock_callback(self): pass mock_result = MockResult(code=0) self._rtu.getRawFrame = self._rtu.getFrame = MagicMock() self._rtu.decoder = MagicMock() self._rtu.decoder.decode = MagicMock(return_value=mock_result) self._rtu.populateResult = MagicMock() self._rtu.advanceFrame = MagicMock() self._rtu._process(mock_callback) self._rtu.populateResult.assert_called_with(mock_result) self._rtu.advanceFrame.assert_called_with() self.assertTrue(self._rtu.advanceFrame.called) #Check errors self._rtu.decoder.decode = MagicMock(return_value=None) self.assertRaises(ModbusIOException, lambda: self._rtu._process(mock_callback)) def testRTUProcessIncomingPAkcets(self): mock_data = b"\x00\x01\x00\x00\x00\x01\xfc\x1b" unit = 0x00 def mock_callback(self): pass self._rtu.addToFrame = MagicMock() self._rtu._process = MagicMock() self._rtu.isFrameReady = MagicMock(return_value=False) self._rtu._buffer = mock_data self._rtu.processIncomingPacket(mock_data, mock_callback, unit) # ----------------------------------------------------------------------- # # ASCII tests # ----------------------------------------------------------------------- # def testASCIIFramerTransactionReady(self): """ Test a ascii frame transaction """ msg = b':F7031389000A60\r\n' self.assertFalse(self._ascii.isFrameReady()) self.assertFalse(self._ascii.checkFrame()) self._ascii.addToFrame(msg) self.assertTrue(self._ascii.isFrameReady()) self.assertTrue(self._ascii.checkFrame()) self._ascii.advanceFrame() self.assertFalse(self._ascii.isFrameReady()) self.assertFalse(self._ascii.checkFrame()) self.assertEqual(b'', self._ascii.getFrame()) def testASCIIFramerTransactionFull(self): """ Test a full ascii frame transaction """ msg = b'sss:F7031389000A60\r\n' pack = a2b_hex(msg[6:-4]) self._ascii.addToFrame(msg) self.assertTrue(self._ascii.checkFrame()) result = self._ascii.getFrame() self.assertEqual(pack, result) self._ascii.advanceFrame() def testASCIIFramerTransactionHalf(self): """ Test a half completed ascii frame transaction """ msg1 = b'sss:F7031389' msg2 = b'000A60\r\n' pack = a2b_hex(msg1[6:] + msg2[:-4]) self._ascii.addToFrame(msg1) self.assertFalse(self._ascii.checkFrame()) result = self._ascii.getFrame() self.assertEqual(b'', result) self._ascii.addToFrame(msg2) self.assertTrue(self._ascii.checkFrame()) result = self._ascii.getFrame() self.assertEqual(pack, result) self._ascii.advanceFrame() def testASCIIFramerPopulate(self): """ Test a ascii frame packet build """ request = ModbusRequest() self._ascii.populateResult(request) self.assertEqual(0x00, request.unit_id) def testASCIIFramerPacket(self): """ Test a ascii frame packet build """ old_encode = ModbusRequest.encode ModbusRequest.encode = lambda self: b'' message = ModbusRequest() message.unit_id = 0xff message.function_code = 0x01 expected = b":FF0100\r\n" actual = self._ascii.buildPacket(message) self.assertEqual(expected, actual) ModbusRequest.encode = old_encode def testAsciiProcessIncomingPakcets(self): mock_data = msg = b':F7031389000A60\r\n' unit = 0x00 def mock_callback(mock_data, *args, **kwargs): pass self._ascii.processIncomingPacket(mock_data, mock_callback, unit) # Test failure: self._ascii.checkFrame = MagicMock(return_value=False) self._ascii.processIncomingPacket(mock_data, mock_callback, unit) # ----------------------------------------------------------------------- # # Binary tests # ----------------------------------------------------------------------- # def testBinaryFramerTransactionReady(self): """ Test a binary frame transaction """ msg = b'\x7b\x01\x03\x00\x00\x00\x05\x85\xC9\x7d' self.assertFalse(self._binary.isFrameReady()) self.assertFalse(self._binary.checkFrame()) self._binary.addToFrame(msg) self.assertTrue(self._binary.isFrameReady()) self.assertTrue(self._binary.checkFrame()) self._binary.advanceFrame() self.assertFalse(self._binary.isFrameReady()) self.assertFalse(self._binary.checkFrame()) self.assertEqual(b'', self._binary.getFrame()) def testBinaryFramerTransactionFull(self): """ Test a full binary frame transaction """ msg = b'\x7b\x01\x03\x00\x00\x00\x05\x85\xC9\x7d' pack = msg[2:-3] self._binary.addToFrame(msg) self.assertTrue(self._binary.checkFrame()) result = self._binary.getFrame() self.assertEqual(pack, result) self._binary.advanceFrame() def testBinaryFramerTransactionHalf(self): """ Test a half completed binary frame transaction """ msg1 = b'\x7b\x01\x03\x00' msg2 = b'\x00\x00\x05\x85\xC9\x7d' pack = msg1[2:] + msg2[:-3] self._binary.addToFrame(msg1) self.assertFalse(self._binary.checkFrame()) result = self._binary.getFrame() self.assertEqual(b'', result) self._binary.addToFrame(msg2) self.assertTrue(self._binary.checkFrame()) result = self._binary.getFrame() self.assertEqual(pack, result) self._binary.advanceFrame() def testBinaryFramerPopulate(self): """ Test a binary frame packet build """ request = ModbusRequest() self._binary.populateResult(request) self.assertEqual(0x00, request.unit_id) def testBinaryFramerPacket(self): """ Test a binary frame packet build """ old_encode = ModbusRequest.encode ModbusRequest.encode = lambda self: b'' message = ModbusRequest() message.unit_id = 0xff message.function_code = 0x01 expected = b'\x7b\xff\x01\x81\x80\x7d' actual = self._binary.buildPacket(message) self.assertEqual(expected, actual) ModbusRequest.encode = old_encode def testBinaryProcessIncomingPacket(self): mock_data = b'\x7b\x01\x03\x00\x00\x00\x05\x85\xC9\x7d' unit = 0x00 def mock_callback(mock_data): pass self._binary.processIncomingPacket(mock_data, mock_callback, unit) # Test failure: self._binary.checkFrame = MagicMock(return_value=False) self._binary.processIncomingPacket(mock_data, mock_callback, unit)
class ModbusTransactionTest(unittest.TestCase): ''' This is the unittest for the pymodbus.transaction module ''' #---------------------------------------------------------------------------# # Test Construction #---------------------------------------------------------------------------# def setUp(self): ''' Sets up the test environment ''' self.client = None self.decoder = ServerDecoder() self._tcp = ModbusSocketFramer(decoder=self.decoder) self._rtu = ModbusRtuFramer(decoder=self.decoder) self._ascii = ModbusAsciiFramer(decoder=self.decoder) self._binary = ModbusBinaryFramer(decoder=self.decoder) self._manager = DictTransactionManager(self.client) self._queue_manager = FifoTransactionManager(self.client) self._tm = ModbusTransactionManager(self.client) def tearDown(self): ''' Cleans up the test environment ''' del self._manager del self._tcp del self._rtu del self._ascii #---------------------------------------------------------------------------# # Dictionary based transaction manager #---------------------------------------------------------------------------# def testDictTransactionManagerTID(self): ''' Test the dict transaction manager TID ''' for tid in range(1, self._manager.getNextTID() + 10): self.assertEqual(tid+1, self._manager.getNextTID()) self._manager.reset() self.assertEqual(1, self._manager.getNextTID()) def testGetDictTransactionManagerTransaction(self): ''' Test the dict transaction manager ''' class Request: pass self._manager.reset() handle = Request() handle.transaction_id = self._manager.getNextTID() handle.message = b"testing" self._manager.addTransaction(handle) result = self._manager.getTransaction(handle.transaction_id) self.assertEqual(handle.message, result.message) def testDeleteDictTransactionManagerTransaction(self): ''' Test the dict transaction manager ''' class Request: pass self._manager.reset() handle = Request() handle.transaction_id = self._manager.getNextTID() handle.message = b"testing" self._manager.addTransaction(handle) self._manager.delTransaction(handle.transaction_id) self.assertEqual(None, self._manager.getTransaction(handle.transaction_id)) #---------------------------------------------------------------------------# # Queue based transaction manager #---------------------------------------------------------------------------# def testFifoTransactionManagerTID(self): ''' Test the fifo transaction manager TID ''' for tid in range(1, self._queue_manager.getNextTID() + 10): self.assertEqual(tid+1, self._queue_manager.getNextTID()) self._queue_manager.reset() self.assertEqual(1, self._queue_manager.getNextTID()) def testGetFifoTransactionManagerTransaction(self): ''' Test the fifo transaction manager ''' class Request: pass self._queue_manager.reset() handle = Request() handle.transaction_id = self._queue_manager.getNextTID() handle.message = b"testing" self._queue_manager.addTransaction(handle) result = self._queue_manager.getTransaction(handle.transaction_id) self.assertEqual(handle.message, result.message) def testDeleteFifoTransactionManagerTransaction(self): ''' Test the fifo transaction manager ''' class Request: pass self._queue_manager.reset() handle = Request() handle.transaction_id = self._queue_manager.getNextTID() handle.message = b"testing" self._queue_manager.addTransaction(handle) self._queue_manager.delTransaction(handle.transaction_id) self.assertEqual(None, self._queue_manager.getTransaction(handle.transaction_id)) #---------------------------------------------------------------------------# # TCP tests #---------------------------------------------------------------------------# def testTCPFramerTransactionReady(self): ''' Test a tcp frame transaction ''' msg = b"\x00\x01\x12\x34\x00\x04\xff\x02\x12\x34" self.assertFalse(self._tcp.isFrameReady()) self.assertFalse(self._tcp.checkFrame()) self._tcp.addToFrame(msg) self.assertTrue(self._tcp.isFrameReady()) self.assertTrue(self._tcp.checkFrame()) self._tcp.advanceFrame() self.assertFalse(self._tcp.isFrameReady()) self.assertFalse(self._tcp.checkFrame()) self.assertEqual(b'', self._ascii.getFrame()) def testTCPFramerTransactionFull(self): ''' Test a full tcp frame transaction ''' msg = b"\x00\x01\x12\x34\x00\x04\xff\x02\x12\x34" self._tcp.addToFrame(msg) self.assertTrue(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(msg[7:], result) self._tcp.advanceFrame() def testTCPFramerTransactionHalf(self): ''' Test a half completed tcp frame transaction ''' msg1 = b"\x00\x01\x12\x34\x00" msg2 = b"\x04\xff\x02\x12\x34" self._tcp.addToFrame(msg1) self.assertFalse(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(b'', result) self._tcp.addToFrame(msg2) self.assertTrue(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(msg2[2:], result) self._tcp.advanceFrame() def testTCPFramerTransactionHalf2(self): ''' Test a half completed tcp frame transaction ''' msg1 = b"\x00\x01\x12\x34\x00\x04\xff" msg2 = b"\x02\x12\x34" self._tcp.addToFrame(msg1) self.assertFalse(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(b'', result) self._tcp.addToFrame(msg2) self.assertTrue(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(msg2, result) self._tcp.advanceFrame() def testTCPFramerTransactionHalf3(self): ''' Test a half completed tcp frame transaction ''' msg1 = b"\x00\x01\x12\x34\x00\x04\xff\x02\x12" msg2 = b"\x34" self._tcp.addToFrame(msg1) self.assertFalse(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(msg1[7:], result) self._tcp.addToFrame(msg2) self.assertTrue(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(msg1[7:] + msg2, result) self._tcp.advanceFrame() def testTCPFramerTransactionShort(self): ''' Test that we can get back on track after an invalid message ''' msg1 = b"\x99\x99\x99\x99\x00\x01\x00\x01" msg2 = b"\x00\x01\x12\x34\x00\x04\xff\x02\x12\x34" self._tcp.addToFrame(msg1) self.assertFalse(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(b'', result) self._tcp.advanceFrame() self._tcp.addToFrame(msg2) self.assertEqual(10, len(self._tcp._buffer)) self.assertTrue(self._tcp.checkFrame()) result = self._tcp.getFrame() self.assertEqual(msg2[7:], result) self._tcp.advanceFrame() def testTCPFramerPopulate(self): ''' Test a tcp frame packet build ''' expected = ModbusRequest() expected.transaction_id = 0x0001 expected.protocol_id = 0x1234 expected.unit_id = 0xff msg = b"\x00\x01\x12\x34\x00\x04\xff\x02\x12\x34" self._tcp.addToFrame(msg) self.assertTrue(self._tcp.checkFrame()) actual = ModbusRequest() self._tcp.populateResult(actual) for name in ['transaction_id', 'protocol_id', 'unit_id']: self.assertEqual(getattr(expected, name), getattr(actual, name)) self._tcp.advanceFrame() def testTCPFramerPacket(self): ''' Test a tcp frame packet build ''' old_encode = ModbusRequest.encode ModbusRequest.encode = lambda self: b'' message = ModbusRequest() message.transaction_id = 0x0001 message.protocol_id = 0x1234 message.unit_id = 0xff message.function_code = 0x01 expected = b"\x00\x01\x12\x34\x00\x02\xff\x01" actual = self._tcp.buildPacket(message) self.assertEqual(expected, actual) ModbusRequest.encode = old_encode #---------------------------------------------------------------------------# # RTU tests #---------------------------------------------------------------------------# def testRTUFramerTransactionReady(self): ''' Test if the checks for a complete frame work ''' self.assertFalse(self._rtu.isFrameReady()) msg_parts = [b"\x00\x01\x00", b"\x00\x00\x01\xfc\x1b"] self._rtu.addToFrame(msg_parts[0]) self.assertTrue(self._rtu.isFrameReady()) self.assertFalse(self._rtu.checkFrame()) self._rtu.addToFrame(msg_parts[1]) self.assertTrue(self._rtu.isFrameReady()) self.assertTrue(self._rtu.checkFrame()) def testRTUFramerTransactionFull(self): ''' Test a full rtu frame transaction ''' msg = b"\x00\x01\x00\x00\x00\x01\xfc\x1b" stripped_msg = msg[1:-2] self._rtu.addToFrame(msg) self.assertTrue(self._rtu.checkFrame()) result = self._rtu.getFrame() self.assertEqual(stripped_msg, result) self._rtu.advanceFrame() def testRTUFramerTransactionHalf(self): ''' Test a half completed rtu frame transaction ''' msg_parts = [b"\x00\x01\x00", b"\x00\x00\x01\xfc\x1b"] stripped_msg = b"".join(msg_parts)[1:-2] self._rtu.addToFrame(msg_parts[0]) self.assertFalse(self._rtu.checkFrame()) self._rtu.addToFrame(msg_parts[1]) self.assertTrue(self._rtu.isFrameReady()) self.assertTrue(self._rtu.checkFrame()) result = self._rtu.getFrame() self.assertEqual(stripped_msg, result) self._rtu.advanceFrame() def testRTUFramerPopulate(self): ''' Test a rtu frame packet build ''' request = ModbusRequest() msg = b"\x00\x01\x00\x00\x00\x01\xfc\x1b" self._rtu.addToFrame(msg) self._rtu.populateHeader() self._rtu.populateResult(request) header_dict = self._rtu._header self.assertEqual(len(msg), header_dict['len']) self.assertEqual(byte2int(msg[0]), header_dict['uid']) self.assertEqual(msg[-2:], header_dict['crc']) self.assertEqual(0x00, request.unit_id) def testRTUFramerPacket(self): ''' Test a rtu frame packet build ''' old_encode = ModbusRequest.encode ModbusRequest.encode = lambda self: b'' message = ModbusRequest() message.unit_id = 0xff message.function_code = 0x01 expected = b"\xff\x01\x81\x80" # only header + CRC - no data actual = self._rtu.buildPacket(message) self.assertEqual(expected, actual) ModbusRequest.encode = old_encode def testRTUDecodeException(self): ''' Test that the RTU framer can decode errors ''' message = b"\x00\x90\x02\x9c\x01" actual = self._rtu.addToFrame(message) result = self._rtu.checkFrame() self.assertTrue(result) def testProcess(self): class MockResult(object): def __init__(self, code): self.function_code = code def mock_callback(self): pass mock_result = MockResult(code=0) self._rtu.getRawFrame = self._rtu.getFrame = MagicMock() self._rtu.decoder = MagicMock() self._rtu.decoder.decode = MagicMock(return_value=mock_result) self._rtu.populateResult = MagicMock() self._rtu.advanceFrame = MagicMock() self._rtu._process(mock_callback) self._rtu.populateResult.assert_called_with(mock_result) self._rtu.advanceFrame.assert_called_with() self.assertTrue(self._rtu.advanceFrame.called) #Check errors self._rtu.decoder.decode = MagicMock(return_value=None) self.assertRaises(ModbusIOException, lambda: self._rtu._process(mock_callback)) def testRTUProcessIncomingPAkcets(self): mock_data = b"\x00\x01\x00\x00\x00\x01\xfc\x1b" def mock_callback(self): pass self._rtu.addToFrame = MagicMock() self._rtu._process = MagicMock() self._rtu.isFrameReady = MagicMock(return_value=False) self._rtu._buffer = mock_data self._rtu.processIncomingPacket(mock_data, mock_callback) #---------------------------------------------------------------------------# # ASCII tests #---------------------------------------------------------------------------# def testASCIIFramerTransactionReady(self): ''' Test a ascii frame transaction ''' msg = b':F7031389000A60\r\n' self.assertFalse(self._ascii.isFrameReady()) self.assertFalse(self._ascii.checkFrame()) self._ascii.addToFrame(msg) self.assertTrue(self._ascii.isFrameReady()) self.assertTrue(self._ascii.checkFrame()) self._ascii.advanceFrame() self.assertFalse(self._ascii.isFrameReady()) self.assertFalse(self._ascii.checkFrame()) self.assertEqual(b'', self._ascii.getFrame()) def testASCIIFramerTransactionFull(self): ''' Test a full ascii frame transaction ''' msg = b'sss:F7031389000A60\r\n' pack = a2b_hex(msg[6:-4]) self._ascii.addToFrame(msg) self.assertTrue(self._ascii.checkFrame()) result = self._ascii.getFrame() self.assertEqual(pack, result) self._ascii.advanceFrame() def testASCIIFramerTransactionHalf(self): ''' Test a half completed ascii frame transaction ''' msg1 = b'sss:F7031389' msg2 = b'000A60\r\n' pack = a2b_hex(msg1[6:] + msg2[:-4]) self._ascii.addToFrame(msg1) self.assertFalse(self._ascii.checkFrame()) result = self._ascii.getFrame() self.assertEqual(b'', result) self._ascii.addToFrame(msg2) self.assertTrue(self._ascii.checkFrame()) result = self._ascii.getFrame() self.assertEqual(pack, result) self._ascii.advanceFrame() def testASCIIFramerPopulate(self): ''' Test a ascii frame packet build ''' request = ModbusRequest() self._ascii.populateResult(request) self.assertEqual(0x00, request.unit_id) def testASCIIFramerPacket(self): ''' Test a ascii frame packet build ''' old_encode = ModbusRequest.encode ModbusRequest.encode = lambda self: b'' message = ModbusRequest() message.unit_id = 0xff message.function_code = 0x01 expected = b":FF0100\r\n" actual = self._ascii.buildPacket(message) self.assertEqual(expected, actual) ModbusRequest.encode = old_encode def testAsciiProcessIncomingPakcets(self): mock_data = msg = b':F7031389000A60\r\n' def mock_callback(mock_data): pass self._ascii.processIncomingPacket(mock_data, mock_callback) # Test failure: self._ascii.checkFrame = MagicMock(return_value=False) self._ascii.processIncomingPacket(mock_data, mock_callback) #---------------------------------------------------------------------------# # Binary tests #---------------------------------------------------------------------------# def testBinaryFramerTransactionReady(self): ''' Test a binary frame transaction ''' msg = b'\x7b\x01\x03\x00\x00\x00\x05\x85\xC9\x7d' self.assertFalse(self._binary.isFrameReady()) self.assertFalse(self._binary.checkFrame()) self._binary.addToFrame(msg) self.assertTrue(self._binary.isFrameReady()) self.assertTrue(self._binary.checkFrame()) self._binary.advanceFrame() self.assertFalse(self._binary.isFrameReady()) self.assertFalse(self._binary.checkFrame()) self.assertEqual(b'', self._binary.getFrame()) def testBinaryFramerTransactionFull(self): ''' Test a full binary frame transaction ''' msg = b'\x7b\x01\x03\x00\x00\x00\x05\x85\xC9\x7d' pack = msg[2:-3] self._binary.addToFrame(msg) self.assertTrue(self._binary.checkFrame()) result = self._binary.getFrame() self.assertEqual(pack, result) self._binary.advanceFrame() def testBinaryFramerTransactionHalf(self): ''' Test a half completed binary frame transaction ''' msg1 = b'\x7b\x01\x03\x00' msg2 = b'\x00\x00\x05\x85\xC9\x7d' pack = msg1[2:] + msg2[:-3] self._binary.addToFrame(msg1) self.assertFalse(self._binary.checkFrame()) result = self._binary.getFrame() self.assertEqual(b'', result) self._binary.addToFrame(msg2) self.assertTrue(self._binary.checkFrame()) result = self._binary.getFrame() self.assertEqual(pack, result) self._binary.advanceFrame() def testBinaryFramerPopulate(self): ''' Test a binary frame packet build ''' request = ModbusRequest() self._binary.populateResult(request) self.assertEqual(0x00, request.unit_id) def testBinaryFramerPacket(self): ''' Test a binary frame packet build ''' old_encode = ModbusRequest.encode ModbusRequest.encode = lambda self: b'' message = ModbusRequest() message.unit_id = 0xff message.function_code = 0x01 expected = b'\x7b\xff\x01\x81\x80\x7d' actual = self._binary.buildPacket(message) self.assertEqual(expected, actual) ModbusRequest.encode = old_encode def testBinaryProcessIncomingPacket(self): mock_data = b'\x7b\x01\x03\x00\x00\x00\x05\x85\xC9\x7d' def mock_callback(mock_data): pass self._binary.processIncomingPacket(mock_data, mock_callback) # Test failure: self._binary.checkFrame = MagicMock(return_value=False) self._binary.processIncomingPacket(mock_data, mock_callback)