예제 #1
0
    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()
예제 #2
0
 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()
예제 #3
0
 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()
예제 #4
0
    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())
예제 #5
0
    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()
예제 #6
0
    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)
예제 #7
0
    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()