async def test_async_receive_server_requests(server): def event_handler(*args, **kwargs): return args, kwargs server.on_server_event = event_handler server.namespace.on_server_event = event_handler response = await server.async_receive_request( jsonrpc_base.Request('on_server_event', msg_id=1)) args, kwargs = response.result assert len(args) == 0 assert len(kwargs) == 0 async def async_event_handler(*args, **kwargs): return args, kwargs server.on_async_server_event = async_event_handler response = await server.async_receive_request( jsonrpc_base.Request('on_async_server_event', msg_id=1)) args, kwargs = response.result assert len(args) == 0 assert len(kwargs) == 0 response = await server.async_receive_request( jsonrpc_base.Request('missing_event', params={'foo': 'bar'}, msg_id=1)) assert response.error['code'] == -32601 assert response.error['message'] == 'Method not found' response = await server.async_receive_request( jsonrpc_base.Request('on_server_event')) assert response is None
def test_dumps(self): # test no args self.assertSameJSON( '''{"jsonrpc": "2.0", "method": "my_method_name", "id": 1}''', jsonrpc_base.Request('my_method_name', params=None, msg_id=1).serialize()) # test keyword args self.assertSameJSON( '''{"params": {"foo": "bar"}, "jsonrpc": "2.0", "method": "my_method_name", "id": 1}''', jsonrpc_base.Request('my_method_name', params={ 'foo': 'bar' }, msg_id=1).serialize()) # test positional args self.assertSameJSON( '''{"params": ["foo", "bar"], "jsonrpc": "2.0", "method": "my_method_name", "id": 1}''', jsonrpc_base.Request('my_method_name', params=('foo', 'bar'), msg_id=1).serialize()) # test notification self.assertSameJSON( '''{"params": ["foo", "bar"], "jsonrpc": "2.0", "method": "my_method_name"}''', jsonrpc_base.Request('my_method_name', params=('foo', 'bar'), msg_id=None).serialize())
def test_server_responses(self): def handler(message): handler.response = message self.server._handler = handler def subtract(foo, bar): return foo - bar self.server.subtract = subtract response = self.server.receive_request( jsonrpc_base.Request('subtract', params={ 'foo': 5, 'bar': 3 }, msg_id=1)) self.server.send_message(response) self.assertSameJSON('''{"jsonrpc": "2.0", "result": 2, "id": 1}''', handler.response) response = self.server.receive_request( jsonrpc_base.Request('subtract', params=[11, 7], msg_id=1)) self.server.send_message(response) self.assertSameJSON('''{"jsonrpc": "2.0", "result": 4, "id": 1}''', handler.response) response = self.server.receive_request( jsonrpc_base.Request('missing_method', msg_id=1)) self.server.send_message(response) self.assertSameJSON( '''{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": 1}''', handler.response) def bad_handler(): raise TestTransportError("Transport Error") self.server._handler = bad_handler def good_method(): return True self.server.good_method = good_method response = self.server.receive_request( jsonrpc_base.Request('good_method', msg_id=1)) with self.assertRaisesRegex( TransportError, "Error responding to server method 'good_method': Transport Error" ): self.server.send_message(response)
def test_send_message(self): # catch non-json responses with self.assertRaises(TransportError) as transport_error: @asyncio.coroutine def handler(request): return aiohttp.web.Response(text='not json', content_type='application/json') self.handler = handler yield from self.server.send_message( jsonrpc_base.Request('my_method', params=None, msg_id=1)) self.assertEqual( transport_error.exception.args[0], "Error calling method 'my_method': Cannot deserialize response body" ) self.assertIsInstance(transport_error.exception.args[1], ValueError) # catch non-200 responses with self.assertRaisesRegex(TransportError, '404'): @asyncio.coroutine def handler(request): return aiohttp.web.Response(text='{}', content_type='application/json', status=404) self.handler = handler yield from self.server.send_message( jsonrpc_base.Request('my_method', params=None, msg_id=1)) # a notification @asyncio.coroutine def handler(request): return aiohttp.web.Response(text='we dont care about this', content_type='application/json') self.handler = handler yield from self.server.send_message( jsonrpc_base.Request('my_notification', params=None)) # catch aiohttp own exception with self.assertRaisesRegex(TransportError, 'aiohttp exception'): def callback(method, path, *args, **kwargs): raise aiohttp.ClientResponseError(message='aiohttp exception') self.client.request_callback = callback yield from self.server.send_message( jsonrpc_base.Request('my_method', params=None, msg_id=1))
def test_send_message(self): # catch non-json responses with self.assertRaises(TransportError) as transport_error: def handler(message): raise TestTransportError("Transport Error") self.server._handler = handler self.server.send_message( jsonrpc_base.Request('my_method', msg_id=1)) self.assertEqual(transport_error.exception.args[0], "Error calling method 'my_method': Transport Error") self.assertIsInstance(transport_error.exception.args[1], TestTransportError) # a notification def handler(message): return 'we dont care about this' self.server._handler = handler self.server.send_message( jsonrpc_base.Request('my_notification', msg_id=None))
def test_send_message(server): empty_server = Server() with pytest.raises(NotImplementedError): empty_server.send_message(jsonrpc_base.Request('my_method', msg_id=1)) # catch non-json responses with pytest.raises(TransportError) as transport_error: def handler(message): raise MockTransportError("Transport Error") server._handler = handler server.send_message(jsonrpc_base.Request('my_method', msg_id=1)) assert transport_error.value.args[0] == ( "Error calling method 'my_method': Transport Error") assert isinstance(transport_error.value.args[1], MockTransportError) # a notification def handler(message): return 'we dont care about this' server._handler = handler server.send_message(jsonrpc_base.Request('my_notification', msg_id=None))
def test_request(self): with self.assertRaisesRegex( ProtocolError, 'Request from server does not contain method'): jsonrpc_base.Request.parse({}) with self.assertRaisesRegex( ProtocolError, 'Parameters must either be a positional list or named dict.'): jsonrpc_base.Request.parse({ 'method': 'test_method', 'params': 'string_params' }) request = jsonrpc_base.Request('test_method', msg_id=1) self.assertEqual(request.response_id, 1)
def test_send_message_timeout(self): # catch timeout responses with self.assertRaises(TransportError) as transport_error: @asyncio.coroutine def handler(request): try: yield from asyncio.sleep(10, loop=self.loop) except asyncio.CancelledError: # Event loop will be terminated before sleep finishes pass return aiohttp.web.Response(text='{}', content_type='application/json') self.handler = handler yield from self.server.send_message(jsonrpc_base.Request('my_method', params=None, msg_id=1)) self.assertIsInstance(transport_error.exception.args[1], asyncio.TimeoutError)
def test_request(server): with pytest.raises(ProtocolError, match='Request from server does not contain method'): jsonrpc_base.Request.parse({}) with pytest.raises( ProtocolError, match='Parameters must either be a positional list or named dict.' ): jsonrpc_base.Request.parse({ 'method': 'test_method', 'params': 'string_params' }) request = jsonrpc_base.Request('test_method', msg_id=1) assert request.response_id == 1
def test_parse_result(server): request = jsonrpc_base.Request('my_message', msg_id=1) with pytest.raises(ProtocolError, match='Response is not a dictionary'): request.parse_response([]) with pytest.raises(ProtocolError, match='Response without a result field'): request.parse_response({}) with pytest.raises(ProtocolError) as protoerror: body = { "jsonrpc": "2.0", "error": { "code": -32601, "message": "Method not found" }, "id": "1" } request.parse_response(body) assert protoerror.value.args[0] == -32601 assert protoerror.value.args[1] == 'Method not found'
def test_parse_result(self): request = jsonrpc_base.Request('my_message', msg_id=1) with self.assertRaisesRegex(ProtocolError, 'Response is not a dictionary'): request.parse_response([]) with self.assertRaisesRegex(ProtocolError, 'Response without a result field'): request.parse_response({}) with self.assertRaises(ProtocolError) as protoerror: body = { "jsonrpc": "2.0", "error": { "code": -32601, "message": "Method not found" }, "id": "1" } request.parse_response(body) self.assertEqual(protoerror.exception.args[0], -32601) self.assertEqual(protoerror.exception.args[1], 'Method not found')
async def test_send_message_timeout(aiohttp_client): """Test the catching of the timeout responses.""" async def handler(request): try: await asyncio.sleep(10) except asyncio.CancelledError: # Event loop will be terminated before sleep finishes pass return aiohttp.web.Response(text='{}', content_type='application/json') def create_app(): app = aiohttp.web.Application() app.router.add_route('POST', '/', handler) return app client = await aiohttp_client(create_app()) server = Server('/', client, timeout=0.2) with pytest.raises(TransportError) as transport_error: await server.send_message(jsonrpc_base.Request( 'my_method', params=None, msg_id=1)) assert isinstance(transport_error.value.args[1], asyncio.TimeoutError)
def test_super_not_implemented(self): """Test the base class NotImplementedException.""" with self.assertRaises(NotImplementedError): super(TestServer, self.server).send_message(jsonrpc_base.Request('my_method'))
async def test_server_responses(server): def handler(message): handler.response = message server._handler = handler def subtract(foo, bar): return foo - bar server.subtract = subtract response = server.receive_request( jsonrpc_base.Request('subtract', params={ 'foo': 5, 'bar': 3 }, msg_id=1)) server.send_message(response) assertSameJSON('''{"jsonrpc": "2.0", "result": 2, "id": 1}''', handler.response) response = server.receive_request( jsonrpc_base.Request('subtract', params=[11, 7], msg_id=1)) server.send_message(response) assertSameJSON('''{"jsonrpc": "2.0", "result": 4, "id": 1}''', handler.response) response = server.receive_request( jsonrpc_base.Request('missing_method', msg_id=1)) server.send_message(response) assertSameJSON( '''{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method''' ''' not found"}, "id": 1}''', handler.response) def bad_handler(self): raise MockTransportError("Transport Error") server._handler = bad_handler def good_method(): return True server.good_method = good_method response = server.receive_request( jsonrpc_base.Request('good_method', msg_id=1)) with pytest.raises( TransportError, match="Error responding to server method 'good_method': " "Transport Error"): server.send_message(response) async def async_bad_method(): raise ValueError("Mock server error") server.async_bad_method = async_bad_method response = await server.async_receive_request( jsonrpc_base.Request('async_bad_method', msg_id=1)) with pytest.raises( TransportError, match="Error responding to server method 'async_bad_method': " "Transport Error"): server.send_message(response)
def test_receive_server_requests(self): def event_handler(*args, **kwargs): return args, kwargs self.server.on_server_event = event_handler self.server.namespace.on_server_event = event_handler response = self.server.receive_request( jsonrpc_base.Request('on_server_event', msg_id=1)) args, kwargs = response.result self.assertEqual(len(args), 0) self.assertEqual(len(kwargs), 0) # Test with a zero message ID response = self.server.receive_request( jsonrpc_base.Request('on_server_event', msg_id=0)) args, kwargs = response.result self.assertEqual(len(args), 0) self.assertEqual(len(kwargs), 0) response = self.server.receive_request( jsonrpc_base.Request('namespace.on_server_event', msg_id=1)) args, kwargs = response.result self.assertEqual(len(args), 0) self.assertEqual(len(kwargs), 0) response = self.server.receive_request( jsonrpc_base.Request('on_server_event', params=['foo', 'bar'], msg_id=1)) args, kwargs = response.result self.assertEqual(args, ('foo', 'bar')) self.assertEqual(len(kwargs), 0) response = self.server.receive_request( jsonrpc_base.Request('on_server_event', params={'foo': 'bar'}, msg_id=1)) args, kwargs = response.result self.assertEqual(len(args), 0) self.assertEqual(kwargs, {'foo': 'bar'}) with self.assertRaises(ProtocolError): response = self.server.receive_request( jsonrpc_base.Request('on_server_event', params="string_params", msg_id=1)) response = self.server.receive_request( jsonrpc_base.Request('missing_event', params={'foo': 'bar'}, msg_id=1)) self.assertEqual(response.error['code'], -32601) self.assertEqual(response.error['message'], 'Method not found') response = self.server.receive_request( jsonrpc_base.Request('on_server_event')) self.assertEqual(response, None) def bad_handler(): raise Exception("Bad Server Handler") self.server.on_bad_handler = bad_handler # receive_request will normally print traceback when an exception is caught. # This isn't necessary for the test with block_stderr(): response = self.server.receive_request( jsonrpc_base.Request('on_bad_handler', msg_id=1)) self.assertEqual(response.error['code'], -32000) self.assertEqual(response.error['message'], 'Server Error: Bad Server Handler')
def test_receive_server_requests(server): def event_handler(*args, **kwargs): return args, kwargs server.on_server_event = event_handler server.namespace.on_server_event = event_handler response = server.receive_request( jsonrpc_base.Request('on_server_event', msg_id=1)) args, kwargs = response.result assert len(args) == 0 assert len(kwargs) == 0 # Test with a zero message ID response = server.receive_request( jsonrpc_base.Request('on_server_event', msg_id=0)) args, kwargs = response.result assert len(args) == 0 assert len(kwargs) == 0 response = server.receive_request( jsonrpc_base.Request('namespace.on_server_event', msg_id=1)) args, kwargs = response.result assert len(args) == 0 assert len(kwargs) == 0 response = server.receive_request( jsonrpc_base.Request('on_server_event', params=['foo', 'bar'], msg_id=1)) args, kwargs = response.result assert args == ('foo', 'bar') assert len(kwargs) == 0 response = server.receive_request( jsonrpc_base.Request('on_server_event', params={'foo': 'bar'}, msg_id=1)) args, kwargs = response.result assert len(args) == 0 assert kwargs == {'foo': 'bar'} with pytest.raises(ProtocolError): response = server.receive_request( jsonrpc_base.Request('on_server_event', params="string_params", msg_id=1)) response = server.receive_request( jsonrpc_base.Request('missing_event', params={'foo': 'bar'}, msg_id=1)) assert response.error['code'] == -32601 assert response.error['message'] == 'Method not found' response = server.receive_request(jsonrpc_base.Request('on_server_event')) assert response is None def bad_handler(): raise Exception("Bad Server Handler") server.on_bad_handler = bad_handler # receive_request will normally print traceback when an exception is caught # This isn't necessary for the test response = server.receive_request( jsonrpc_base.Request('on_bad_handler', msg_id=1)) assert response.error['code'] == -32000 assert response.error['message'] == 'Server Error: Bad Server Handler' async def async_event_handler(*args, **kwargs): return args, kwargs server.on_async_server_event = async_event_handler response = server.receive_request( jsonrpc_base.Request('on_async_server_event', msg_id=1)) assert response.error['code'] == -32000 assert response.error['message'] == ( 'Server Error: Async handlers are not' ' supported in synchronous sever implementations')
async def test_send_message(aiohttp_client): """Test the sending of messages.""" # catch non-json responses async def handler1(request): return aiohttp.web.Response( text='not json', content_type='application/json') def create_app(): app = aiohttp.web.Application() app.router.add_route('POST', '/', handler1) return app client = await aiohttp_client(create_app()) server = Server('/', client) with pytest.raises(TransportError) as transport_error: await server.send_message( jsonrpc_base.Request('my_method', params=None, msg_id=1)) assert transport_error.value.args[0] == ( "Error calling method 'my_method': Cannot deserialize response body") assert isinstance(transport_error.value.args[1], ValueError) # catch non-200 responses async def handler2(request): return aiohttp.web.Response( text='{}', content_type='application/json', status=404) def create_app(): app = aiohttp.web.Application() app.router.add_route('POST', '/', handler2) return app client = await aiohttp_client(create_app()) server = Server('/', client) with pytest.raises(TransportError) as transport_error: await server.send_message(jsonrpc_base.Request( 'my_method', params=None, msg_id=1)) assert transport_error.value.args[0] == ( "Error calling method 'my_method': HTTP 404 Not Found") # catch aiohttp own exception async def callback(*args, **kwargs): raise aiohttp.ClientOSError('aiohttp exception') def create_app(): app = aiohttp.web.Application() return app client = await aiohttp_client(create_app()) client.post = callback server = Server('/', client) with pytest.raises(TransportError) as transport_error: await server.send_message(jsonrpc_base.Request( 'my_method', params=None, msg_id=1)) assert transport_error.value.args[0] == ( "Error calling method 'my_method': Transport Error")