Пример #1
0
    def test_json_rpc_response_positive(self):
        err_responses = [
            # message / data is optional
            ('{"jsonrpc": "2.0", "error": {"code": -32600}, "id": null}',
             JsonRpc20Error.INVALID_REQUEST),
            # data is primitive / structured
            ('{"jsonrpc": "2.0", "error": {"code": -32600, "data": "somedata"}, "id": null}',
             JsonRpc20Error.INVALID_REQUEST),
            ('{"jsonrpc": "2.0", "error": {"code": -32600, "data": {"key": "somedata"}}, "id": null}',
             JsonRpc20Error.INVALID_REQUEST),

            ('{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": null}',
             JsonRpc20Error.INVALID_REQUEST),
            ('{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error."}, "id": null}',
             JsonRpc20Error.PARSE_ERROR),
            ('{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found."}, "id": "1"}',
             JsonRpc20Error.METHOD_NOT_FOUND),
            ('{"jsonrpc": "2.0", "error": {"code": -32602, "message": "Invalid params."}, "id": "1"}',
             JsonRpc20Error.INVALID_PARAMS),
            ('{"jsonrpc": "2.0", "error": {"code": -32603, "message": "Internal error."}, "id": 1}',
             JsonRpc20Error.INTERNAL_ERROR),
        ]
        for response_str, error_code in err_responses:
            response = deserialize_response(response_str)
            self.assertTrue(response.error.code == error_code)
            response.serialize()
Пример #2
0
    def test_json_rpc_positive(self):
        requests = [
            # id can be null, number, string, or omitted
            ('{"jsonrpc": "2.0", "method": "subtract", "id": null}', None),
            ('{"jsonrpc": "2.0", "method": "subtract", "id": 3}',
             '{"jsonrpc": "2.0", "result": 0, "id": 3}'),
            ('{"jsonrpc": "2.0", "method": "subtract", "id": "string_id"}',
             '{"jsonrpc": "2.0", "result": 0, "id": "string_id"}'),

            # Accept keyed parameters. Do not accept array parameters
            ('{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}',
             '{"jsonrpc": "2.0", "result": 19, "id": 3}'),
        ]

        for request_str, response_str in requests:
            request = deserialize_request(request_str)
            self.assertFalse(request.notification)
            if response_str:
                response = deserialize_response(response_str)
                request.validate_response(response)
                request.serialize()

        notifications = [
            '{"jsonrpc": "2.0", "method": "subtract"}',
        ]
        for notification_str in notifications:
            request = deserialize_request(notification_str)
            self.assertTrue(request.notification)
            request.serialize_notification()
Пример #3
0
 def test_json_rpc_response_negative(self):
     responses = [
         ('', JsonRpc20Error.PARSE_ERROR),
         ('sjlfskfdl', JsonRpc20Error.PARSE_ERROR),
         ('{"jsonrpc": "2.0", "result": "foobar, "error": "bar"}',
          JsonRpc20Error.PARSE_ERROR),
         ('{"jsonrpc": "2.0", "result": "foobar, "error": "bar", "id": null}',
          JsonRpc20Error.PARSE_ERROR),
         ('{"jsonrpc": "2.0", "result": "foobar, "error": {"code": -32603}, "id": null}',
          JsonRpc20Error.PARSE_ERROR),
         ('{"result": 19, "id": 3}', JsonRpc20Error.INVALID_PARAMS),
     ]
     for response_str, error_code in responses:
         try:
             logging.info("response str: %s", response_str)
             deserialize_response(response_str)
             self.assertTrue(False)
         except JsonRpc20Error as err:
             logging.info("err: %s", str(err))
             self.assertTrue(err.code == error_code)
Пример #4
0
    def test_json_rpc_request_negative(self):
        requests = [
            ('', JsonRpc20Error.PARSE_ERROR),
            ('sjlfskfdl', JsonRpc20Error.PARSE_ERROR),
            ('{"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz"]',
             JsonRpc20Error.PARSE_ERROR),
            ('{"jsonrpc": "2.0", "method": 1, "params": "bar"}',
             JsonRpc20Error.INVALID_REQUEST),
            ('{"jsonrpc": "2.0", "method": "a_method", "params": "bar"}',
             JsonRpc20Error.INVALID_REQUEST),
        ]

        for request_str, error_code in requests:
            try:
                logging.info("request str: %s", request_str)
                deserialize_request(request_str)
                self.assertTrue(False)
            except JsonRpc20Error as err:
                logging.info("err: %s", str(err))
                self.assertTrue(err.code == error_code)

        # Negative validate test
        requests = [
            # Mismatch version
            ('{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}',
             '{"version": "1.1", "result": 19, "id": 3}', JsonRpc20Error.INVALID_PARAMS),

            # Mismatch id
            ('{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}',
             '{"jsonrpc": "2.0", "result": 19, "id": 4}', JsonRpc20Error.INVALID_PARAMS),
            # Mismatch id type
            ('{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}',
             '{"jsonrpc": "2.0", "result": 19, "id": "3"}', JsonRpc20Error.INVALID_PARAMS),

            # Notification should have no response
            ('{"jsonrpc": "2.0", "method": "subtract"}',
             '{"jsonrpc": "2.0", "result": 0}',
             JsonRpc20Error.INVALID_PARAMS),
        ]
        for request_str, response_str, error_code in requests:
            request = deserialize_request(request_str)
            if response_str:
                try:
                    response = deserialize_response(response_str)
                except JsonRpc20Error as err:
                    self.assertTrue(err.code == error_code)
                    continue

                try:
                    request.validate_response(response)
                    self.assertTrue(False)
                except JsonRpc20Error as err:
                    logging.info("err: %s", str(err))
                    self.assertTrue(err.code == error_code)
Пример #5
0
    def _do_request(self, method, params=None):
        """
        Perform json rpc request

        :type  method: :class:`str`
        :param method: json rpc method name
        :type  params: :class:`dict` or None
        :param params: json rpc method params
        :rtype: :class:`vmware.vapi.data.serializer.jsonrpc.JsonRpcResponse`
        :return: json rpc response
        """

        logger.debug('_do_request: request %s', method)

        if not self.http_provider.connect():
            logger.error('Connection refused')
            raise vapi_jsonrpc_error_transport_error()
        request_headers = {'Content-Type': 'application/json'}
        id_ = six.advance_iterator(self.counter)  # atomic increment
        id_ = str(id_)  # TODO: Bypass java barf temporary
        request = vapi_jsonrpc_request_factory(method=method,
                                               params=params,
                                               id=id_)
        request_body = request.serialize()
        if six.text_type:
            request_body = request_body.encode('utf-8')
        for processor in self.post_processors:
            request_body = processor.process(request_body)

        request_logger.debug('_do_request: request %s', request_body)
        # do_request returns http_response
        http_response = self.http_provider.do_request(
            HTTPRequest(method=HTTPMethod.POST,
                        url_path=None,
                        headers=request_headers,
                        body=request_body))
        if http_response.data is not None:
            # Currently only RequestsProvider returns the requests Response
            # object as data back. We need to raise exception if error is
            # returned to keep existing behavior.
            http_response.data.raise_for_status()
        request_logger.debug('_do_request: response %s', http_response.body)
        response = deserialize_response(http_response.body)
        request.validate_response(response)
        if response.error is not None:
            logger.error('_do_request: method %s response with error %s',
                         method, response.error)
            raise response.error  # pylint: disable=E0702
        return response
Пример #6
0
 def test_decimal_json_request(self):
     ctx = ExecutionContext()
     template_request = (
         '{"params":{"input":%s,"serviceId":"mock","ctx":{"appCtx":{}},' +
         '"operationId":"mock"},"jsonrpc":' +
         '"2.0","method":"invoke","id":1}'
     )
     template_response = (
         '{"jsonrpc":"2.0","id":1,"result":{"output": %s}}'
     )
     for val, canonical_val in [
                 ('-12.34e4', '-1.234E5'),
                 ('1E-130', '1.0E-130'),
                 ('0.0E-0', '0.0E0'),
                 ('1.2', '1.2E0'),
                 ('1111111.1111100021e-30', '1.1111111111100021E-24'),
                 ('12312423.0', '1.2312423E7'),
                 ('0.000234E-10', '2.34E-14'),
                 ('17', '1.7E1')]:
         decimal_val = decimal.Decimal(val)
         canonical_decimal_val = canonicalize_double(decimal_val)
         data_value = DoubleValue(decimal_val)
         params = {
             'ctx': ctx,
             'serviceId': 'mock',
             'operationId': 'mock',
             'input': data_value
         }
         actual_request = vapi_jsonrpc_request_factory(
             method=VAPI_INVOKE, params=params, id=1).serialize()
         expected_request = template_request % canonical_decimal_val
         self.assertEqual(
             json.loads(actual_request, parse_float=decimal.Decimal),
             json.loads(expected_request, parse_float=decimal.Decimal))
         response_msg = template_response % canonical_val
         response = deserialize_response(response_msg)
         method_result = JsonRpcDictToVapi.method_result(response.result)
         self.assertTrue(method_result.success())
         self.assertTrue(isinstance(method_result.output, DoubleValue))
         self.assertEqual(method_result.output,
                          DoubleValue(decimal.Decimal(canonical_val)))
Пример #7
0
    def test_json_handle_request_negative(self):
        protocol_handler = get_protocol_handler(self.provider)
        rpc_provider = LocalRpcProvider(protocol_handler)
        rpc_provider.connect()

        id_ = 12
        requests = [
            (vapi_jsonrpc_request_factory(method="bogus", params=None, id=id_),
             JsonRpc20Error.METHOD_NOT_FOUND),
            (vapi_jsonrpc_request_factory(method=VAPI_INVOKE,
                                          params={"bogus": 12}, id=id_),
             JsonRpc20Error.INVALID_PARAMS),
        ]

        for request, error_code in requests:
            http_response = rpc_provider.do_request(
                HTTPRequest(method=HTTPMethod.POST, body=request.serialize()))
            response = deserialize_response(http_response.body)
            request.validate_response(response)
            error = response.error
            logging.info("error: %s", error)
            self.assertTrue(error)
            self.assertTrue(error.code == error_code)
Пример #8
0
    def _do_request(self, method, ctx, params=None):
        """
        Perform json rpc request

        :type  method: :class:`str`
        :param method: json rpc method name
        :type  ctx: :class:`vmware.vapi.core.ExecutionContext`
        :param ctx: execution context object
        :type  params: :class:`dict` or None
        :param params: json rpc method params
        :rtype: :class:`vmware.vapi.data.serializer.jsonrpc.JsonRpcResponse`
        :return: json rpc response
        """

        logger.debug('_do_request: request %s', method)

        if not self.http_provider.connect():
            logger.error('Connection refused')
            raise vapi_jsonrpc_error_transport_error()
        request_headers = {
            HTTP_CONTENT_TYPE_HEADER: JSON_CONTENT_TYPE,
            HTTP_USER_AGENT_HEADER: get_user_agent()
        }
        id_ = six.advance_iterator(self.counter)  # atomic increment
        id_ = str(id_)  # TODO: Bypass java barf temporary
        request = vapi_jsonrpc_request_factory(method=method,
                                               params=params,
                                               id=id_)
        request_body = request.serialize()
        if six.text_type:
            request_body = request_body.encode('utf-8')
        for processor in self.post_processors:
            request_body = processor.process(request_body)

        request_logger.debug('_do_request: request %s', request_body)
        # do_request returns http_response
        http_response = self.http_provider.do_request(
            HTTPRequest(method=HTTPMethod.POST,
                        url_path=None,
                        headers=request_headers,
                        body=request_body))
        if http_response.data is not None:
            # Currently only RequestsProvider returns the requests Response
            # object as data back. We need to raise exception if error is
            # returned to keep existing behavior.
            http_response.data.raise_for_status()
        request_logger.debug('_do_request: response %s', http_response.body)

        if ctx.runtime_data is not None:
            response_extractor = ctx.runtime_data.get('response_extractor')
            if response_extractor is not None:
                response_extractor.set_http_status(http_response.status)
                response_extractor.set_http_headers(http_response.headers)
                response_extractor.set_http_body(http_response.body)
                response_extractor.set_http_method(HTTPMethod.POST)
                response_extractor.set_http_url(self.http_provider._base_url)  # pylint: disable=protected-access

        response = deserialize_response(http_response.body)
        request.validate_response(response)
        if response.error is not None:
            logger.error('_do_request: method %s response with error %s',
                         method, response.error)
            raise response.error  # pylint: disable=E0702
        return response