def testUdpServerException(self): ''' Test sending garbage data on a TCP socket should drop the connection ''' garbage = b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' server = yield from StartUdpServer(context=self.context,address=("127.0.0.1", 0),loop=self.loop) if PYTHON_VERSION >= (3, 7): server_task = asyncio.create_task(server.serve_forever()) else: server_task = asyncio.ensure_future(server.serve_forever()) yield from server.serving with patch('pymodbus.transaction.ModbusSocketFramer.processIncomingPacket', new_callable=lambda: Mock(side_effect=Exception)) as process: connect, receive, eof = self.loop.create_future(),self.loop.create_future(),self.loop.create_future() received_data = None random_port = server.protocol._sock.getsockname()[1] # get the random server port class BasicClient(asyncio.DatagramProtocol): def connection_made(self, transport): _logger.debug("Client connected") self.transport = transport transport.sendto(garbage) connect.set_result(True) def datagram_received(self, data, addr): nonlocal receive _logger.debug("Client received data") receive.set_result(True) received_data = data transport, protocol = yield from self.loop.create_datagram_endpoint(BasicClient, remote_addr=('127.0.0.1', random_port)) yield from asyncio.wait_for(connect, timeout=0.1) self.assertFalse(receive.done()) self.assertFalse(server.protocol._sock._closed) server.server_close()
def testStartUdpServer(self): ''' Test that the modbus udp asyncio server starts correctly ''' identity = ModbusDeviceIdentification(info={0x00: 'VendorName'}) self.loop = asynctest.Mock(self.loop) server = yield from StartUdpServer(context=self.context,loop=self.loop,identity=identity) self.assertEqual(server.control.Identity.VendorName, 'VendorName') if PYTHON_VERSION >= (3, 6): self.loop.create_datagram_endpoint.assert_called_once()
def testUdpServerServeForeverTwice(self): ''' Call on serve_forever() twice should result in a runtime error ''' identity = ModbusDeviceIdentification(info={0x00: 'VendorName'}) server = yield from StartUdpServer(context=self.context,address=("127.0.0.1", 0), loop=self.loop,identity=identity) if PYTHON_VERSION >= (3, 7): server_task = asyncio.create_task(server.serve_forever()) else: server_task = asyncio.ensure_future(server.serve_forever()) yield from server.serving with self.assertRaises(RuntimeError): yield from server.serve_forever() server.server_close()
def testUdpServerServeForeverClose(self): ''' Test StartUdpServer serve_forever() method ''' server = yield from StartUdpServer(context=self.context,address=("127.0.0.1", 0), loop=self.loop) if PYTHON_VERSION >= (3, 7): server_task = asyncio.create_task(server.serve_forever()) else: server_task = asyncio.ensure_future(server.serve_forever()) yield from server.serving self.assertTrue(asyncio.isfuture(server.on_connection_terminated)) self.assertFalse(server.on_connection_terminated.done()) server.server_close() self.assertTrue(server.protocol.is_closing())
def testUdpServerReceiveData(self): ''' Test that the sending data on datagram socket gets data pushed to framer ''' server = yield from StartUdpServer(context=self.context,address=("127.0.0.1", 0),loop=self.loop) if PYTHON_VERSION >= (3, 7): server_task = asyncio.create_task(server.serve_forever()) else: server_task = asyncio.ensure_future(server.serve_forever()) yield from server.serving with patch('pymodbus.transaction.ModbusSocketFramer.processIncomingPacket',new_callable=Mock) as process: server.endpoint.datagram_received(data=b"12345", addr=("127.0.0.1", 12345)) yield from asyncio.sleep(0.1) process.seal() if PYTHON_VERSION >= (3, 6): process.assert_called_once() self.assertTrue( process.call_args[1]["data"] == b"12345" ) server.server_close()
def testUdpServerSendData(self): ''' Test that the modbus udp asyncio server correctly sends data outbound ''' identity = ModbusDeviceIdentification(info={0x00: 'VendorName'}) data = b'x\01\x00\x00\x00\x00\x06\x01\x03\x00\x00\x00\x19' server = yield from StartUdpServer(context=self.context, address=("127.0.0.1", 0)) if PYTHON_VERSION >= (3, 7): server_task = asyncio.create_task(server.serve_forever()) else: server_task = asyncio.ensure_future(server.serve_forever()) yield from server.serving random_port = server.protocol._sock.getsockname()[1] received = server.endpoint.datagram_received = Mock( wraps=server.endpoint.datagram_received) done = self.loop.create_future() received_value = None class BasicClient(asyncio.DatagramProtocol): def connection_made(self, transport): self.transport = transport self.transport.sendto(data) def datagram_received(self, data, addr): nonlocal received_value, done print("received") received_value = data done.set_result(True) self.transport.close() transport, protocol = yield from self.loop.create_datagram_endpoint( BasicClient, remote_addr=('127.0.0.1', random_port)) yield from asyncio.sleep(0.1) if PYTHON_VERSION >= (3, 6): received.assert_called_once() self.assertEqual(received.call_args[0][0], data) server.server_close() self.assertTrue(server.protocol.is_closing()) yield from asyncio.sleep(0.1)
def testUdpServerRoundtrip(self): ''' Test sending and receiving data on udp socket''' data = b"\x01\x00\x00\x00\x00\x06\x01\x03\x00\x00\x00\x01" # unit 1, read register expected_response = b'\x01\x00\x00\x00\x00\x05\x01\x03\x02\x00\x11' # value of 17 as per context server = yield from StartUdpServer(context=self.context, address=("127.0.0.1", 0), loop=self.loop) if PYTHON_VERSION >= (3, 7): server_task = asyncio.create_task(server.serve_forever()) else: server_task = asyncio.ensure_future(server.serve_forever()) yield from server.serving random_port = server.protocol._sock.getsockname()[1] connected, done = self.loop.create_future(), self.loop.create_future() received_value = None class BasicClient(asyncio.DatagramProtocol): def connection_made(self, transport): self.transport = transport self.transport.sendto(data) def datagram_received(self, data, addr): nonlocal received_value, done print("received") received_value = data done.set_result(True) transport, protocol = yield from self.loop.create_datagram_endpoint( BasicClient, remote_addr=('127.0.0.1', random_port)) yield from asyncio.wait_for(done, timeout=0.1) self.assertEqual(received_value, expected_response) transport.close() yield from asyncio.sleep(0) server.server_close()