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
Esempio n. 2
0
def test_unpack_object():
    """test of unpack_object function
    """

    data = MessageData(b'\x93\x01\x02\x03')
    obj = unpack_object(data)
    assert isinstance(obj, list)
    assert obj == [1, 2, 3]

    data = MessageData(b'\x93\x01\x02')
    with pytest.raises(MPRPCException) as err:
        unpack_object(data)
    assert isinstance(err.value.args[0], ErrorInfo)
    assert err.value.args[0].code == int(ErrorCode.PARSE_ERROR)
Esempio n. 3
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)
Esempio n. 4
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)
Esempio n. 5
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
Esempio n. 7
0
def test_pack_object():
    """test of pack_object function
    """

    origin = [1, 'test']
    data = pack_object(origin)
    assert isinstance(data, MessageData)
    assert unpack_object(data) == origin

    origin = int
    with pytest.raises(MPRPCException) as err:
        pack_object(origin)
    assert isinstance(err.value.args[0], ErrorInfo)
    assert err.value.args[0].code == int(ErrorCode.UNEXPECTED_ERROR)
    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
Esempio n. 9
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
Esempio n. 10
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()