def test_keywords(self): methods = {'get_name': lambda **kwargs: kwargs['name']} req = Request({ 'jsonrpc': '2.0', 'method': 'get_name', 'params': { 'name': 'foo' }, 'id': 1 }) self.assertEqual('foo', req.call(methods)['result'])
def test_object_method(self): methods = {'foo': Foo().foo} req = Request({ 'jsonrpc': '2.0', 'method': 'foo', 'params': [1, 2], 'id': 1 }) response = req.call(methods) self.assertIsInstance(response, RequestResponse) self.assertEqual('bar', response['result'])
def test_list_partials(self): multiply = lambda x, y: x * y double = partial(multiply, 2) double.__name__ = 'double' req = Request({ 'jsonrpc': '2.0', 'method': 'double', 'params': [3], 'id': 1 }) self.assertEqual(6, req.call([double])['result'])
def test_methods_partials(self): multiply = lambda x, y: x * y double = partial(multiply, 2) methods = Methods() methods.add(double, 'double') req = Request({ 'jsonrpc': '2.0', 'method': 'double', 'params': [3], 'id': 1 }) self.assertEqual(6, req.call(methods)['result'])
def test_keywords(self): def get_name(**kwargs): return kwargs['name'] req = Request({ 'jsonrpc': '2.0', 'method': 'get_name', 'params': { 'name': 'foo' }, 'id': 1 }) self.assertEqual('foo', req.call([get_name])['result'])
def test_to_response_ErrorResult(): assert ( to_response( Request("ping", [], sentinel.id), Left( ErrorResult( code=sentinel.code, message=sentinel.message, data=sentinel.data ) ), ) ) == Left( ErrorResponse(sentinel.code, sentinel.message, sentinel.data, sentinel.id) )
def test_safe_call_api_error(): def error(): raise ApiError("Client Error", code=123, data={"data": 42}) response = safe_call( Request(method="error", id=1), Methods(error), debug=True, serialize=default_serialize, ) assert isinstance(response, ErrorResponse) error_dict = response.deserialized()["error"] assert error_dict["message"] == "Client Error" assert error_dict["code"] == 123 assert error_dict["data"] == {"data": 42}
def test_safe_call_api_error_minimal(): def error(): raise ApiError("Client Error") response = safe_call( Request(method="error", id=1), Methods(error), debug=True, serialize=default_serialize, ) assert isinstance(response, ErrorResponse) response_dict = response.deserialized() error_dict = response_dict["error"] assert error_dict["message"] == "Client Error" assert error_dict["code"] == 1 assert "data" not in error_dict
def test_safe_call_api_error_minimal(): def error(context: Context): return ApiErrorResponse("Client Error", code=123, id=context.request.id) response = safe_call( Request(method="error", params=[], id=1), Methods(error), extra=None, serialize=default_serialize, ) assert isinstance(response, ErrorResponse) response_dict = response.deserialized() error_dict = response_dict["error"] assert error_dict["message"] == "Client Error" assert error_dict["code"] == 123 assert "data" not in error_dict
def test_non_json_encodable_resonse(): def method(): return b"Hello, World" response = safe_call( Request(method="method", id=1), Methods(method), debug=False, serialize=default_serialize, ) # response must be serializable here str(response) assert isinstance(response, ErrorResponse) response_dict = response.deserialized() error_dict = response_dict["error"] assert error_dict["message"] == "Server error" assert error_dict["code"] == -32000 assert "data" not in error_dict
def test_keywords_with_context(self): methods = { 'square': lambda foo=None, context=None: { 'foo': foo, 'context': context } } req = Request( { 'jsonrpc': '2.0', 'method': 'square', 'params': { 'foo': FOO }, 'id': 1 }, context=BAR) self.assertEqual(FOO, req.call(methods)['result']['foo']) self.assertEqual(BAR, req.call(methods)['result']['context'])
def test_convert_camel_case(self): config.convert_camel_case = True req = Request({ 'jsonrpc': '2.0', 'method': 'fooMethod', 'params': { 'fooParam': 1, 'aDict': { 'barParam': 1 } } }) self.assertEqual('foo_method', req.method_name) self.assertEqual({ 'foo_param': 1, 'a_dict': { 'bar_param': 1 } }, req.kwargs)
def test_no_arguments(): req = Request({'jsonrpc': '2.0', 'method': 'foo'}) req._validate_arguments_against_signature(lambda: None)
def test(self): req = Request({'jsonrpc': '2.0', 'method': 'foo', 'id': 1}).call([foo]) self.assertIsInstance(req, RequestResponse) self.assertEqual('bar', req['result'])
def test_configuring_http_status(self): NotificationResponse.http_status = status.HTTP_OK req = Request({'jsonrpc': '2.0', 'method': 'foo'}).call([foo]) self.assertEqual(status.HTTP_OK, req.http_status) NotificationResponse.http_status = status.HTTP_NO_CONTENT
def test_config_notification_errors_on(self): # Should return "method not found" error request = Request({'jsonrpc': '2.0', 'method': 'baz'}) config.notification_errors = True req = request.call([foo]) self.assertIsInstance(req, ErrorResponse)
def test_uncaught_exception(self): def foo(): return 1/0 req = Request({'jsonrpc': '2.0', 'method': 'foo'}).call([foo]) self.assertIsInstance(req, NotificationResponse)
def test_explicitly_raised_exception(self): def foo(): raise InvalidParams() req = Request({'jsonrpc': '2.0', 'method': 'foo'}).call([foo]) self.assertIsInstance(req, NotificationResponse)
def test_is_notification_false(): assert is_notification(Request(method="foo", params=[], id=1)) is False
def handle(self): logger = self.server.logger poller = select.poll() poller.register(self.request.fileno(), select.POLLIN | select.POLLPRI | select.POLLERR) while True: if poller.poll(500): self.data = self.request.recv(8192).decode() if not self.data: break while self.data[-1] != '\n': self.data += self.request.recv(8192).decode() self.data = self.data.strip() else: if self.server.STOP_EVENT.is_set(): break else: continue lock_acquired = False try: if self.server._request_cb is not None: self.server._request_cb(self.data) if self.server._client_lock.acquire(True, 10): lock_acquired = True logger.debug("Dispatching %s" % (self.data)) response = dispatcher.dispatch(self.server._methods, self.data) logger.debug("Responding with: %s" % response.json_debug) else: # Send a time out response r = Request(self.data) logger.debug( "Timed out waiting for lock with request = %s" % (self.data)) request_id = r.request_id if hasattr( r, 'request_id') else None response = ErrorResponse( http_status=HTTP_STATUS_CODES[408], request_id=request_id, code=-32000, # Server error message="Timed out waiting for lock") except Exception as e: if logger is not None: logger.exception(e) finally: if lock_acquired: self.server._client_lock.release() try: json_str = json.dumps(response.json_debug) + "\n" msg = json_str.encode() logger.debug("Message length = %d" % len(msg)) self.request.sendall(msg) except BrokenPipeError: break except Exception as e: if logger is not None: logger.exception(e)
def test_positionals_not_passed(self): req = Request({'jsonrpc': '2.0', 'method': 'foo', 'params': {'foo': 'bar'}}) with self.assertRaises(InvalidParams): req._validate_arguments_against_signature(lambda x: None)
def test_no_arguments_too_many_positionals(self): req = Request({'jsonrpc': '2.0', 'method': 'foo', 'params': ['foo']}) with self.assertRaises(InvalidParams): req._validate_arguments_against_signature(lambda: None)
def test_positionals(): req = Request({'jsonrpc': '2.0', 'method': 'foo', 'params': [1]}) req._validate_arguments_against_signature(lambda x: None)
def test_false(self): req = Request({'jsonrpc': '2.0', 'method': 'foo', 'id': 99}) self.assertFalse(req.is_notification)
def test_keywords(): req = Request({'jsonrpc': '2.0', 'method': 'foo', 'params': {'foo': 'bar'}}) req._validate_arguments_against_signature(lambda **kwargs: None)
def test_success(self): req = Request({'jsonrpc': '2.0', 'method': 'foo'}).call([foo]) self.assertIsInstance(req, NotificationResponse)
def test_is_notification_true(): assert is_notification(Request(method="foo", params=[], id=NOID)) is True
def test_method_not_found(self): req = Request({'jsonrpc': '2.0', 'method': 'baz'}).call([foo]) self.assertIsInstance(req, NotificationResponse)
def test_request(): assert Request(method="foo", params=[], id=1).method == "foo"
def test_invalid_params(self): def foo(bar): return 'bar' req = Request({'jsonrpc': '2.0', 'method': 'foo'}).call([foo]) self.assertIsInstance(req, NotificationResponse)