def test_parseServiceRequest_junk_input(self): '''Test the correct error is raised after sending complete crap.''' # Bind an arbitrary bytestream to the socket bytestream = 'ABCD' socket_factory = FakeSocketFactory() sock = socket_factory.createSocket() # Test the server handler raises the BAD_REQUEST_DATA error code handler = server.SocketHandler(sock, self.client_addr, self.server_addr) self.assertRaises(error.BadRequestDataError, handler.parseServiceRequest, bytestream)
def serializeRpcRequestToSocket(self, partial = False): '''Convenience function for preparing socket connection tests.''' # Don't validate the RPC request if the partial flag is provided if partial: bytestream = self.rpc_request.SerializePartialToString() else: bytestream = self.rpc_request.SerializeToString() socket_factory = FakeSocketFactory() socket = socket_factory.createSocket() return (bytestream, socket)
def test_parseServiceRequest_junk_input(self): '''Test the correct error is raised after sending complete crap.''' # Bind an arbitrary bytestream to the socket bytestream = 'ABCD' socket_factory = FakeSocketFactory() sock = socket_factory.createSocket() # Test the server handler raises the BAD_REQUEST_DATA error code handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) self.assertRaises(error.BadRequestDataError, handler.parseServiceRequest, bytestream)
def serializeRpcRequestToSocket(self, partial=False): '''Convenience function for preparing socket connection tests.''' # Don't validate the RPC request if the partial flag is provided if partial: bytestream = self.rpc_request.SerializePartialToString() else: bytestream = self.rpc_request.SerializeToString() socket_factory = FakeSocketFactory() socket = socket_factory.createSocket() return (bytestream, socket)
class TestSocketRpcChannel(unittest.TestCase): '''Unit tests for the protobuf.channel.SocketRpcChannel class.''' def setUp(self): # Create a channel connected to a fake socket self.factory = FakeSocketFactory() self.channel = ch.SocketRpcChannel(socketFactory = self.factory) # Define a simple service request self.service_request = test_pb2.Request() self.service_request.str_data = 'The lord giveth' self.serialized_request = self.service_request.SerializeToString() # Define a service response self.service_response = test_pb2.Response() self.service_response.str_data = 'And the lord taketh away' self.serialized_response = self.service_response.SerializePartialToString() # Define an RPC request with the service request as payload self.rpc_request = rpc_pb2.Request() self.rpc_request.request_proto = self.serialized_request def tearDown(self): pass def test___init__1(self): self.assertEqual(self.channel.sockFactory, self.factory, 'Initialising channel with user-supplied factory') def test___init__defaults(self): self.assert_(self.channel.host, True) self.assert_(self.channel.port, True) def test_validateRequest(self): self.rpc_request.service_name = "Dummy Service" self.rpc_request.method_name = "Dummy Method" self.assertEqual(self.channel.validateRequest(self.rpc_request), None, 'validateRequest - valid request provided') def test_validateRequest_BAD_REQUEST_PROTO(self): # A request with mandatory fields missing self.rpc_request = rpc_pb2.Request() self.assertRaises(error.BadRequestProtoError, self.channel.validateRequest, self.rpc_request) def test_openSocket(self): '''Test normal return from openSocket.''' self.assert_(self.channel.openSocket, "openSocket returns something") def test_openSocket_IO_ERROR(self): '''Test exceptional return from openSocket (IO_ERROR).''' # Fake socket primed to throw an unknown host exception socket = FakeSocket() socket.throwIOErrorException() self.factory.setSocket(socket) self.assertRaises(error.IOError, self.channel.openSocket, 'host', -1) def test_openSocket_UNKNOWN_HOST(self): '''Test exceptional return from openSocket (UNKNOWN_HOST).''' self.assert_(self.channel.openSocket, "openSocket returns something") # Fake socket primed to throw an unknown host exception socket = FakeSocket() socket.throwUnknownHostException() self.factory.setSocket(socket) self.assertRaises(error.UnknownHostError, self.channel.openSocket, 'host', -1) def test_createRpcRequest(self): '''Test createRpcRequest - normal usage.''' # Instantiate the test service, and get a reference to the method method_name = 'TestMethod' service = TestServiceImpl() method = service.DESCRIPTOR.FindMethodByName(method_name) # Define a simple service request service_request = test_pb2.Request() service_request.str_data = 'The lord giveth' serialized_request = service_request.SerializeToString() # Define an RPC request with the service request as payload expected_rpc = rpc_pb2.Request() expected_rpc.request_proto = serialized_request expected_rpc.service_name = service.DESCRIPTOR.full_name expected_rpc.method_name = method_name self.assertEqual(self.channel.createRpcRequest(method, service_request), expected_rpc, 'createRpcRequest - normal usage') def test_sendRpcMessage(self): '''Test sendRpcMessage - normal usage.''' # Create a socket and service request sock = self.factory.createSocket() sent_request = self.rpc_request sent_request.service_name = "Dummy service" sent_request.method_name = "Dummy method" # Call the method self.channel.sendRpcMessage(sock, sent_request) # Extract the output that was written to the socket received_request = rpc_pb2.Request() received_request.MergeFromString(sock.output_stream.stream_data) self.assertEqual(received_request, sent_request, 'Request written to socket') def test_sendRpcMessage_IOError(self): '''Test sendRpcMessage - IOError.''' # Create a socket with an IOError condition set sock = self.factory.createSocket() sock.throwIOErrorException() # Create a service request sent_request = self.rpc_request sent_request.service_name = "Dummy service" sent_request.method_name = "Dummy method" self.assertRaises(error.IOError, self.channel.sendRpcMessage, sock, sent_request) def test_recvRpcMessage(self): '''Test recvRpcMessage - normal usage.''' # Create a socket and service request msg = 'Message from server' sock = self.factory.createSocket() sock.withInputBytes(msg) # Call the method self.assertEqual(self.channel.recvRpcMessage(sock), msg, 'recvRpcMessage - normal usage') def test_recvRpcMessage_ioerror(self): '''Test recvRpcMessage - IOError.''' # Create a socket and service request msg = 'Message from server' sock = self.factory.createSocket() sock.withInputBytes(msg) sock.throwIOErrorException() # Call the method self.assertRaises(error.IOError, self.channel.recvRpcMessage, sock) def test_parseResponse(self): '''Test parseResponse - normal usage.''' resp_class = rpc_pb2.Response expected_response = resp_class() bytestream = expected_response.SerializeToString() self.assertEqual(self.channel.parseResponse(bytestream, resp_class), expected_response, 'parseResponse - normal usage') def test_parseResponse_junk_input(self): '''Test the correct error is raised after sending complete crap.''' # Setup an arbitrary and broken bytestream bytestream = 'ABCD' resp_class = rpc_pb2.Response self.assertRaises(error.BadResponseProtoError, self.channel.parseResponse, bytestream, resp_class) def testGoodRpc(self): '''Test a good RPC call.''' # Fake socket with prepared response socket = FakeSocket() socket.withResponseProto(self.service_response) socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) controller = channel.newController() # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method callback = FakeCallback() service.TestMethod(controller,self.service_request,callback) self.assertTrue(callback.invoked,'Callback invoked') self.assertEquals(self.service_response.str_data, callback.response.str_data,'Response message') self.assertEquals(self.serialized_request, socket.getRequest().request_proto, 'Request protocol serialisation') self.assertEquals(service.DESCRIPTOR.full_name, socket.getRequest().service_name,'Service name') self.assertEquals(service.DESCRIPTOR.methods[0].name, socket.getRequest().method_name,'Method name') def testUnknownHostException(self): '''Test unknown host.''' # Fake socket primed to throw an unknown host exception socket = FakeSocket() socket.throwUnknownHostException() socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) controller = channel.newController() # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method callback = FakeCallback() service.TestMethod(controller,self.service_request,callback) self.assertFalse(callback.invoked,'Callback invoked') self.assertTrue(controller.failed()) self.assertEquals(rpc_pb2.UNKNOWN_HOST,controller.reason, 'Error reason') def testIOErrorWhileCreatingSocket(self): '''Test Error while creating socket.''' # Fake socket primed to throw an unknown host exception socket = FakeSocket() socket.throwIOErrorException() socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) controller = channel.newController() # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method callback = FakeCallback() service.TestMethod(controller,self.service_request,callback) self.assertFalse(callback.invoked,'Callback invoked') self.assertTrue(controller.failed()) self.assertEquals(rpc_pb2.IO_ERROR,controller.reason,'Error reason') def testIncompleteRequest(self): '''Test calling RPC with incomplete request.''' # Create data service_request = test_pb2.Request() # Fake socket with prepared response socket = FakeSocket() socket.withResponseProto(self.service_response) socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) controller = channel.newController() # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method callback = FakeCallback() service.TestMethod(controller,service_request,callback) self.assertFalse(callback.invoked,'Callback invoked') self.assertEquals(rpc_pb2.BAD_REQUEST_PROTO,controller.reason) self.assertTrue(controller.failed()) def testNoCallBack(self): '''Test RPC failing to invoke callback.''' # Fake socket with callback set to false socket = FakeSocket() socket.withNoResponse(False) socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) controller = channel.newController() # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method callback = FakeCallback() service.TestMethod(controller,self.service_request,callback) self.assertFalse(callback.invoked,'Callback invoked') self.assertEquals(self.serialized_request, socket.getRequest().request_proto, 'Request protocol serialisation') self.assertEquals(service.DESCRIPTOR.full_name, socket.getRequest().service_name,'Service name') self.assertEquals(service.DESCRIPTOR.methods[0].name, socket.getRequest().method_name,'Method name') def testBadResponse(self): '''Test bad response from server.''' # Fake socket with prepared response socket = FakeSocket() socket.withInputBytes("bad response") socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) controller = channel.newController() # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method callback = FakeCallback() service.TestMethod(controller,self.service_request,callback) # Verify request was sent and bad response received self.assertFalse(callback.invoked,'Callback invoked') self.assertEquals(self.serialized_request, socket.getRequest().request_proto, 'Request protocol serialisation') self.assertTrue(controller.failed(),'Controller failed') self.assertEquals(rpc_pb2.BAD_RESPONSE_PROTO, controller.reason, 'Controller reason')
class TestSocketRpcChannel(unittest.TestCase): '''Unit tests for the protobuf.channel.SocketRpcChannel class.''' def setUp(self): # Create a channel connected to a fake socket self.factory = FakeSocketFactory() self.channel = ch.SocketRpcChannel(socketFactory=self.factory) # Define a simple service request self.service_request = test_pb2.Request() self.service_request.str_data = 'The lord giveth' self.serialized_request = self.service_request.SerializeToString() # Define a service response self.service_response = test_pb2.Response() self.service_response.str_data = 'And the lord taketh away' self.serialized_response = \ self.service_response.SerializePartialToString() # Define an RPC request with the service request as payload self.rpc_request = rpc_pb2.Request() self.rpc_request.request_proto = self.serialized_request def tearDown(self): pass def test___init__1(self): self.assertEqual(self.channel.sockFactory, self.factory, 'Initialising channel with user-supplied factory') def test___init__defaults(self): self.assert_(self.channel.host, True) self.assert_(self.channel.port, True) def test_validateRequest(self): self.rpc_request.service_name = "Dummy Service" self.rpc_request.method_name = "Dummy Method" self.assertEqual(self.channel.validateRequest(self.rpc_request), None, 'validateRequest - valid request provided') def test_validateRequest_BAD_REQUEST_PROTO(self): # A request with mandatory fields missing self.rpc_request = rpc_pb2.Request() self.assertRaises(error.BadRequestProtoError, self.channel.validateRequest, self.rpc_request) def test_openSocket(self): '''Test normal return from openSocket.''' self.assert_(self.channel.openSocket, "openSocket returns something") def test_openSocket_IO_ERROR(self): '''Test exceptional return from openSocket (IO_ERROR).''' # Fake socket primed to throw an unknown host exception socket = FakeSocket() socket.throwIOErrorException() self.factory.setSocket(socket) self.assertRaises(error.IOError, self.channel.openSocket, 'host', -1) def test_openSocket_UNKNOWN_HOST(self): '''Test exceptional return from openSocket (UNKNOWN_HOST).''' self.assert_(self.channel.openSocket, "openSocket returns something") # Fake socket primed to throw an unknown host exception socket = FakeSocket() socket.throwUnknownHostException() self.factory.setSocket(socket) self.assertRaises(error.UnknownHostError, self.channel.openSocket, 'host', -1) def test_createRpcRequest(self): '''Test createRpcRequest - normal usage.''' # Instantiate the test service, and get a reference to the method method_name = 'TestMethod' service = TestServiceImpl() method = service.DESCRIPTOR.FindMethodByName(method_name) # Define a simple service request service_request = test_pb2.Request() service_request.str_data = 'The lord giveth' serialized_request = service_request.SerializeToString() # Define an RPC request with the service request as payload expected_rpc = rpc_pb2.Request() expected_rpc.request_proto = serialized_request expected_rpc.service_name = service.DESCRIPTOR.full_name expected_rpc.method_name = method_name self.assertEqual( self.channel.createRpcRequest(method, service_request), expected_rpc, 'createRpcRequest - normal usage') def test_sendRpcMessage(self): '''Test sendRpcMessage - normal usage.''' # Create a socket and service request sock = self.factory.createSocket() sent_request = self.rpc_request sent_request.service_name = "Dummy service" sent_request.method_name = "Dummy method" # Call the method self.channel.sendRpcMessage(sock, sent_request) # Extract the output that was written to the socket received_request = rpc_pb2.Request() received_request.MergeFromString(sock.output_stream.stream_data) self.assertEqual(received_request, sent_request, 'Request written to socket') def test_sendRpcMessage_IOError(self): '''Test sendRpcMessage - IOError.''' # Create a socket with an IOError condition set sock = self.factory.createSocket() sock.throwIOErrorException() # Create a service request sent_request = self.rpc_request sent_request.service_name = "Dummy service" sent_request.method_name = "Dummy method" self.assertRaises(error.IOError, self.channel.sendRpcMessage, sock, sent_request) def test_recvRpcMessage(self): '''Test recvRpcMessage - normal usage.''' # Create a socket and service request msg = 'Message from server' sock = self.factory.createSocket() sock.withInputBytes(msg) # Call the method self.assertEqual(self.channel.recvRpcMessage(sock), msg, 'recvRpcMessage - normal usage') def test_recvRpcMessage_ioerror(self): '''Test recvRpcMessage - IOError.''' # Create a socket and service request msg = 'Message from server' sock = self.factory.createSocket() sock.withInputBytes(msg) sock.throwIOErrorException() # Call the method self.assertRaises(error.IOError, self.channel.recvRpcMessage, sock) def test_parseResponse(self): '''Test parseResponse - normal usage.''' resp_class = rpc_pb2.Response expected_response = resp_class() bytestream = expected_response.SerializeToString() self.assertEqual(self.channel.parseResponse(bytestream, resp_class), expected_response, 'parseResponse - normal usage') def test_parseResponse_junk_input(self): '''Test the correct error is raised after sending complete crap.''' # Setup an arbitrary and broken bytestream bytestream = 'ABCD' resp_class = rpc_pb2.Response self.assertRaises(error.BadResponseProtoError, self.channel.parseResponse, bytestream, resp_class) def testGoodRpc(self): '''Test a good RPC call.''' # Fake socket with prepared response socket = FakeSocket() socket.withResponseProto(self.service_response) socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) # Create the service service = test_pb2.TestService_Stub(channel) def VerifyGoodRpc(response): self.assertEquals(self.service_response.str_data, response.str_data, 'Response message') self.assertEquals(self.serialized_request, socket.getRequest().request_proto, 'Request protocol serialisation') self.assertEquals(service.DESCRIPTOR.full_name, socket.getRequest().service_name, 'Service name') self.assertEquals(service.DESCRIPTOR.methods[0].name, socket.getRequest().method_name, 'Method name') # Call RPC method controller = channel.newController() callback = FakeCallback() service.TestMethod(controller, self.service_request, callback) self.assertTrue(callback.invoked, 'Callback invoked') VerifyGoodRpc(callback.response) # Call Blocking RPC controller = channel.newController() response = service.TestMethod(controller, self.service_request, None) VerifyGoodRpc(response) def testUnknownHostException(self): '''Test unknown host.''' # Fake socket primed to throw an unknown host exception socket = FakeSocket() socket.throwUnknownHostException() socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method controller = channel.newController() callback = FakeCallback() service.TestMethod(controller, self.service_request, callback) self.assertTrue(callback.invoked, 'Callback invoked') self.assertTrue(callback.response is None, 'Response') self.assertTrue(controller.failed()) self.assertEquals(rpc_pb2.UNKNOWN_HOST, controller.reason, 'Error reason') # Call Blocking RPC controller = channel.newController() try: service.TestMethod(controller, self.service_request, None) self.fail('Should have thrown error') except RpcError: self.assertTrue(controller.failed()) self.assertEquals(rpc_pb2.UNKNOWN_HOST, controller.reason, 'Error reason') def testIOErrorWhileCreatingSocket(self): '''Test Error while creating socket.''' # Fake socket primed to throw an unknown host exception socket = FakeSocket() socket.throwIOErrorException() socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method controller = channel.newController() callback = FakeCallback() service.TestMethod(controller, self.service_request, callback) self.assertTrue(callback.invoked, 'Callback invoked') self.assertTrue(callback.response is None, 'Response') self.assertTrue(controller.failed()) self.assertEquals(rpc_pb2.IO_ERROR, controller.reason, 'Error reason') # Call Blocking RPC controller = channel.newController() try: service.TestMethod(controller, self.service_request, None) self.fail('Should have thrown error') except RpcError: self.assertTrue(controller.failed()) self.assertEquals(rpc_pb2.IO_ERROR, controller.reason, 'Error reason') def testIncompleteRequest(self): '''Test calling RPC with incomplete request.''' # Create data service_request = test_pb2.Request() # Fake socket with prepared response socket = FakeSocket() socket.withResponseProto(self.service_response) socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method controller = channel.newController() callback = FakeCallback() service.TestMethod(controller, service_request, callback) self.assertTrue(callback.invoked, 'Callback invoked') self.assertTrue(callback.response is None, 'Response') self.assertEquals(rpc_pb2.BAD_REQUEST_PROTO, controller.reason) self.assertTrue(controller.failed()) # Call Blocking RPC controller = channel.newController() try: service.TestMethod(controller, service_request, None) self.fail('Should have thrown error') except RpcError: self.assertTrue(controller.failed()) self.assertEquals(rpc_pb2.BAD_REQUEST_PROTO, controller.reason, 'Error reason') def testNoCallBack(self): '''Test RPC failing to invoke callback.''' # Fake socket with callback set to false socket = FakeSocket() socket.withNoResponse(False) socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method controller = channel.newController() callback = FakeCallback() service.TestMethod(controller, self.service_request, callback) self.assertFalse(callback.invoked, 'Callback invoked') self.assertEquals(self.serialized_request, socket.getRequest().request_proto, 'Request protocol serialisation') self.assertEquals(service.DESCRIPTOR.full_name, socket.getRequest().service_name, 'Service name') self.assertEquals(service.DESCRIPTOR.methods[0].name, socket.getRequest().method_name, 'Method name') # Call Blocking RPC controller = channel.newController() response = service.TestMethod(controller, self.service_request, None) self.assertFalse(controller.failed()) self.assertTrue(response is None, 'Response'); def testBadResponse(self): '''Test bad response from server.''' # Fake socket with prepared response socket = FakeSocket() socket.withInputBytes("bad response") socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method controller = channel.newController() callback = FakeCallback() service.TestMethod(controller, self.service_request, callback) # Verify request was sent and bad response received self.assertTrue(callback.invoked, 'Callback invoked') self.assertEquals(self.serialized_request, socket.getRequest().request_proto, 'Request protocol serialisation') self.assertTrue(controller.failed(), 'Controller failed') self.assertTrue(callback.response is None, 'Response') self.assertEquals(rpc_pb2.BAD_RESPONSE_PROTO, controller.reason, 'Controller reason') # Call Blocking RPC controller = channel.newController() try: service.TestMethod(controller, self.service_request, None) self.fail('Should have thrown error') except RpcError: self.assertTrue(controller.failed()) self.assertEquals(rpc_pb2.BAD_RESPONSE_PROTO, controller.reason, 'Error reason')