def test_function_method_executor_request():
    """test of requests in FunctionMethodExecutor class
    """

    name = 'test_method'

    executor = FunctionMethodExecutor(PythonLogger(), name, add)

    assert executor.name == name
    assert executor.function == add  # pylint: disable=comparison-with-callable

    session = MockSession()

    msgid = 37
    params = [2, 3]
    request = Request(MsgType.REQUEST, msgid, name, params)

    response_data = executor.process_request(session, request)
    response = validate_message(unpack_object(response_data))

    assert response.msgtype == MsgType.RESPONSE
    assert response.msgid == msgid
    assert response.error is None
    assert response.result == 5

    msgid = 37
    params = [2]
    request = Request(MsgType.REQUEST, msgid, name, params)

    response_data = executor.process_request(session, request)
    response = validate_message(unpack_object(response_data))

    assert response.msgtype == MsgType.RESPONSE
    assert response.msgid == msgid
    assert response.error is not None
def _check_parse_error(data: Any):
    """check that parse error is raised when parsing data

    Parameters
    ----------
    data : Any
        data
    """

    with pytest.raises(MPRPCException) as err:
        validate_message(data)
    assert isinstance(err.value.args[0], ErrorInfo)
    assert err.value.args[0].code == int(ErrorCode.PARSE_ERROR)
def test_parse_notification():
    """test of parsing notification messages
    """

    msgtype = 2
    method = 'abc'
    params = [1, 'test', 3.14]
    data = [msgtype, method, params]

    notification = validate_message(data)
    assert isinstance(notification, Notification)
    assert notification.msgtype == MsgType.NOTIFICATION
    assert notification.method == method
    assert notification.params == params

    data = [msgtype, method]
    _check_parse_error(data)

    data = [msgtype, method, params, None]
    _check_parse_error(data)

    data = [msgtype, b'abc', params]
    _check_parse_error(data)

    data = [msgtype, method, {'abc': 0}]
    _check_parse_error(data)
def test_parse_response():
    """test of parsing response messages
    """

    msgtype = 1
    msgid = 37
    error = None
    result = 'result text'
    data = [msgtype, msgid, error, result]

    res = validate_message(data)
    assert isinstance(res, Response)
    assert res.msgtype == int(MsgType.RESPONSE)
    assert res.msgid == msgid
    assert res.error == error
    assert res.result == result

    data = [msgtype, msgid, error]
    _check_parse_error(data)

    data = [msgtype, msgid, error, result, None]
    _check_parse_error(data)

    data = [msgtype, '37', error, result]
    _check_parse_error(data)

    data = [msgtype, -1, error, result]
    _check_parse_error(data)
def test_parse_request():
    """test of parsing request messages
    """

    msgtype = 0
    msgid = 37
    method = 'abc'
    params = [1, 'test', 3.14]
    data = [msgtype, msgid, method, params]

    req = validate_message(data)
    assert isinstance(req, Request)
    assert req.msgtype == MsgType.REQUEST
    assert req.msgid == msgid
    assert req.method == method
    assert req.params == params

    data = [msgtype, msgid, method]
    _check_parse_error(data)

    data = [msgtype, msgid, method, params, None]
    _check_parse_error(data)

    data = [msgtype, '37', method, params]
    _check_parse_error(data)

    data = [msgtype, -1, method, params]
    _check_parse_error(data)

    data = [msgtype, msgid, b'abc', params]
    _check_parse_error(data)

    data = [msgtype, msgid, method, 5]
    _check_parse_error(data)
Exemplo n.º 6
0
def test_pack_notification():
    """test of pack_notification function
    """

    method = 'abc'
    params = [1, 'param']

    data = pack_notification(method=method, params=params)
    notification = validate_message(unpack_object(data))
    assert notification == Notification(MsgType.NOTIFICATION, method, params)
Exemplo n.º 7
0
def test_pack_request():
    """test of pack_request function
    """

    msgid = 37
    method = 'abc'
    params = [1, 'param']

    data = pack_request(msgid=msgid, method=method, params=params)
    req = validate_message(unpack_object(data))
    assert req == Request(MsgType.REQUEST, msgid, method, params)
Exemplo n.º 8
0
def test_pack_response():
    """test of pack_response function
    """

    msgid = 37

    data = pack_response(msgid=msgid)
    res = validate_message(unpack_object(data))
    assert res == Response(MsgType.RESPONSE, msgid, None, None)

    result = 'abc'

    data = pack_response(msgid=msgid, result=result)
    res = validate_message(unpack_object(data))
    assert res == Response(MsgType.RESPONSE, msgid, None, result)

    error = 123

    data = pack_response(msgid=msgid, error=error)
    res = validate_message(unpack_object(data))
    assert res == Response(MsgType.RESPONSE, msgid, error, None)
def test_simple_method_server_request_invalid_method():
    """test of requests for non-existing methods to SimpleMethodServer class
    """

    name = 'test_method'
    executor = FunctionMethodExecutor(PythonLogger(), name, add)
    server = SimpleMethodServer(PythonLogger(), [executor])

    session = MockSession()

    msgid = 37
    name = 'invalid_method'
    params = [2, 3]
    request = pack_request(msgid, name, params)

    err = None
    has_response = None
    response = None
    processed = Event()

    def handler(err_in: ErrorInfo, has_response_in: bool,
                response_in: MessageData):
        """handler
        """

        nonlocal err
        nonlocal has_response
        nonlocal response
        nonlocal processed

        err = err_in
        has_response = has_response_in
        response = response_in
        processed.set()

    server.async_process_message(session, request, handler)

    timeout = 10.0
    processed.wait(timeout=timeout)
    assert processed.is_set()

    assert err is not None
    assert not err
    assert has_response
    assert response is not None

    response = validate_message(unpack_object(response))

    assert response.msgtype == MsgType.RESPONSE
    assert response.msgid == msgid
    assert response.error is not None
Exemplo n.º 10
0
    def process_message(self, session: Session,
                        data: MessageData) -> MessageData:
        """process a message

        Parameters
        ----------
        session : Session
            session
        data : MessageData
            message

        Returns
        -------
        MessageData
            response data (if exists).
        """

        try:
            msg = validate_message(unpack_object(data))

            if isinstance(msg, Request):
                if msg.method not in self.__methods:
                    self.__logger.error('method %s not found', msg.method)
                    return pack_response(msg.msgid,
                                         error='method {} not found'.format(
                                             msg.method))

                return self.__methods[msg.method].process_request(session, msg)

            if isinstance(msg, Notification):
                if msg.method not in self.__methods:
                    self.__logger.error('method %s not found', msg.method)
                    return None

                self.__methods[msg.method].process_notification(session, msg)
                return None

            raise MPRPCException(
                ErrorInfo(ErrorCode.INVALID_MESSAGE,
                          'message must be a request or response'))
        except MPRPCException as err:
            self.__logger.error('%s', err)
            raise
        except Exception as err:
            self.__logger.error('%s', err)
            raise MPRPCException(
                ErrorInfo(ErrorCode.UNEXPECTED_ERROR,
                          'error in server: {}'.format(err))) from err
Exemplo n.º 11
0
    def _process_message(self, err: ErrorInfo, data: MessageData):
        """process a message

        Parameters
        ----------
        err : ErrorInfo
            error
        data : MessageData
            message data
        """

        try:
            if err:
                raise MPRPCException(err)

            msg = validate_message(unpack_object(data))
            if not isinstance(msg, Response):
                raise MPRPCException(
                    ErrorInfo(ErrorCode.INVALID_MESSAGE,
                              'received a message which is not a response'))

            msgid = msg.msgid
            with self.__lock:
                if msgid not in self.__requests:
                    self.__logger.warn(
                        'invalid msgid in received response: %d', msgid)
                future = self.__requests[msgid]
                del self.__requests[msgid]

            if msg.error:
                future.set_exception(ServerError(msg.error))
                return

            future.set_result(msg.result)

        except MPRPCException as exc:
            self.__logger.error('%s', exc)
            with self.__lock:
                for future in self.__requests.values():
                    future.set_exception(MPRPCException(err))
                self.__requests = dict()
            return
Exemplo n.º 12
0
def test_server():
    """test of Server class
    """

    logger = PythonLogger(LogLevel.TRACE)

    name = 'add'
    logger = PythonLogger()
    executor = FunctionMethodExecutor(logger, name, add)
    method_server = SimpleMethodServer(logger, [executor])

    server_config = ServerConfig()
    server_config.tcp_acceptors = [TCPAcceptorConfig()]
    server = Server(logger, server_config, method_server)
    server.start()

    client_config = ClientConfig()

    response_error = None
    response_data = None
    response_received_event = Event()

    def client_process_message(error: ErrorInfo, data: MessageData):
        nonlocal response_error
        nonlocal response_data
        nonlocal response_received_event
        response_error = error
        response_data = data
        response_received_event.set()

    client = PythonClientHelper(logger, client_config, client_process_message)
    client.start()

    request_error = None
    request_sent_event = Event()

    def on_request_sent(error: ErrorInfo):
        nonlocal request_error
        nonlocal request_sent_event
        request_error = error
        request_sent_event.set()

    msgid = 37
    data = pack_request(msgid, name, [2, 3])
    client.async_send(data, on_request_sent)

    timeout = 10.0
    request_sent_event.wait(timeout=timeout)
    assert request_sent_event.is_set()
    assert not request_error

    response_received_event.wait(timeout=timeout)
    assert response_received_event.is_set()
    assert not response_error

    response = validate_message(unpack_object(response_data))
    assert response.msgtype == MsgType.RESPONSE
    assert response.msgid == msgid
    assert response.error is None
    assert response.result == 5

    client.stop()
    server.stop()