Esempio n. 1
0
def test_basic_server_client():
    # Start server
    server = Server()
    server.bind()
    assert server._listening is False
    server.serve()
    assert server._listening is True
    assert server.active_connections == 0
    assert server.accepted_connections == 0

    # No connection to accept
    assert server.accept_connection(timeout=0) == -1

    # Connect client
    client = Client(host=server.ip, port=server.port)
    client.connect()

    # Server accepts connection
    conn_idx = server.accept_connection()
    assert conn_idx == 0
    assert server.active_connections == 1
    assert server.accepted_connections == 1

    # Client sends message
    msg = b'Hello'
    _, size = client.send(msg)
    assert size == len(msg)

    # Server receives
    received = server.receive(size, conn_idx=conn_idx)
    assert received == msg

    # Server sends reply
    msg = b'World'
    server.send(msg, conn_idx)
    received = client.receive(1024)
    assert received == msg

    client.close()
    server.close()
Esempio n. 2
0
def test_two_clients():
    server = Server()
    server.bind()
    server.serve()

    client1 = Client(host=server.ip, port=server.port)
    client2 = Client(host=server.ip, port=server.port)

    # Client 1 connect and send message
    client1.connect()
    conn_1 = server.accept_connection(5)
    msg1 = b'Hello!'
    _, size1 = client1.send(msg1)

    # Client 2 connect and send message before server received msg from 1
    client2.connect()
    conn_2 = server.accept_connection(5)
    msg2 = b'Hey'
    _, size2 = client2.send(msg2)

    # Server responds to 1
    assert server.receive(size1, conn_idx=conn_1) == msg1
    resp1 = b'Yo1'
    server.send(resp1, conn_idx=conn_1)

    # Server responds to 2
    assert server.receive(size2, conn_idx=conn_2) == msg2
    resp2 = b'Yo2'
    server.send(resp2, conn_idx=conn_2)

    # Clients receiving responses
    assert client1.recv(1024) == resp1
    assert client2.recv(1024) == resp2

    client1.close()
    client2.close()
    server.close()
Esempio n. 3
0
class TCPServer(Driver):
    """
    Driver for a server that can send and receive messages over TCP.
    Supports multiple connections.

    This is built on top of the
    :py:class:`testplan.common.utils.sockets.server.Server` class, which
    provides equivalent functionality and may be used outside of MultiTest.

    :param host: Host name to bind to. Default: 'localhost'
    :type host: ``str``
    :param port: Port number to bind to. Default: 0 (Random port)
    :type port: ``int``

    Also inherits all
    :py:class:`~testplan.testing.multitest.driver.base.Driver`` options.
    """

    CONFIG = TCPServerConfig

    def __init__(self, **options):
        super(TCPServer, self).__init__(**options)
        self._host = None
        self._port = None
        self._server = None

    @property
    def host(self):
        """Target host name."""
        return self._host

    @property
    def port(self):
        """Port number assigned."""
        return self._port

    @property
    def socket(self):
        """
        Returns the underlying ``socket`` object
        """
        return self._server.socket

    def accept_connection(self, timeout=10):
        """Doc from Server."""
        return self._server.accept_connection(timeout=timeout)

    accept_connection.__doc__ = Server.accept_connection.__doc__

    def send_text(self, msg, standard='utf-8', **kwargs):
        """
        Encodes to bytes and calls
        :py:meth:`TCPServer.send
        <testplan.testing.multitest.driver.tcp.server.TCPServer.send>`.
        """
        return self.send(bytes(msg.encode(standard)), **kwargs)

    def send(self, msg, conn_idx=None, timeout=30):
        """Doc from Server."""
        return self._server.send(msg=msg, conn_idx=conn_idx, timeout=timeout)

    send.__doc__ = Server.send.__doc__

    def receive_text(self, standard='utf-8', **kwargs):
        """
        Calls
        :py:meth:`TCPServer.receive
        <testplan.testing.multitest.driver.tcp.server.TCPServer.receive>`
        and decodes received bytes.
        """
        return self.receive(**kwargs).decode(standard)

    def receive(self, size=None, conn_idx=None, timeout=30):
        """Receive bytes from the given connection."""
        received = None
        timeout_info = TimeoutExceptionInfo()
        try:
            receive_kwargs = dict(conn_idx=conn_idx, timeout=timeout or 0)
            if size is None:
                receive_kwargs['size'] = 1024
                receive_kwargs['wait_full_size'] = False
            else:
                receive_kwargs['size'] = size
                receive_kwargs['wait_full_size'] = True

            received = self._server.receive(**receive_kwargs)
        except socket.timeout:
            if timeout is not None:
                raise TimeoutException(
                    'Timed out waiting for message on {0}. {1}'.format(
                        self.cfg.name, timeout_info.msg()))
        return received

    def starting(self):
        """Starts the TCP server."""
        super(TCPServer, self).starting()
        self._server = Server(host=self.cfg.host, port=self.cfg.port)
        self._server.bind()
        self._server.serve()
        self._host = self.cfg.host
        self._port = self._server.port

    def _stop_logic(self):
        if self._server:
            self._server.close()

    def stopping(self):
        """Stops the TCP server."""
        super(TCPServer, self).stopping()
        self._stop_logic()

    def aborting(self):
        """Abort logic that stops the server."""
        self._stop_logic()