| 
					
				 | 
			
			
				@@ -29,11 +29,16 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 """Implementations of interoperability test methods.""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import threading 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from grpc.early_adopter import utilities 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from interop import empty_pb2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from interop import messages_pb2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+_TIMEOUT = 7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 def _empty_call(request, unused_context): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return empty_pb2.Empty() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -142,3 +147,134 @@ SERVER_METHODS = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     FULL_DUPLEX_CALL_METHOD_NAME: _SERVER_FULL_DUPLEX_CALL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     HALF_DUPLEX_CALL_METHOD_NAME: _SERVER_HALF_DUPLEX_CALL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def _empty_unary(stub): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  with stub: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if not isinstance(response, empty_pb2.Empty): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      raise TypeError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          'response is of type "%s", not empty_pb2.Empty!', type(response)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def _large_unary(stub): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  with stub: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    request = messages_pb2.SimpleRequest( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        response_type=messages_pb2.COMPRESSABLE, response_size=314159, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        payload=messages_pb2.Payload(body=b'\x00' * 271828)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    response_future = stub.UnaryCall.async(request, _TIMEOUT) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    response = response_future.result() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if response.payload.type is not messages_pb2.COMPRESSABLE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          'response payload type is "%s"!' % type(response.payload.type)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if len(response.payload.body) != 314159: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          'response body of incorrect size %d!' % len(response.payload.body)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def _client_streaming(stub): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  with stub: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    payload_body_sizes = (27182, 8, 1828, 45904) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    payloads = ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        messages_pb2.Payload(body=b'\x00' * size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for size in payload_body_sizes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    requests = ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        messages_pb2.StreamingInputCallRequest(payload=payload) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for payload in payloads) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    response = stub.StreamingInputCall(requests, _TIMEOUT) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if response.aggregated_payload_size != 74922: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          'incorrect size %d!' % response.aggregated_payload_size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def _server_streaming(stub): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  sizes = (31415, 9, 2653, 58979) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  with stub: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    request = messages_pb2.StreamingOutputCallRequest( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        response_type=messages_pb2.COMPRESSABLE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        response_parameters=( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            messages_pb2.ResponseParameters(size=sizes[0]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            messages_pb2.ResponseParameters(size=sizes[1]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            messages_pb2.ResponseParameters(size=sizes[2]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            messages_pb2.ResponseParameters(size=sizes[3]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        )) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    response_iterator = stub.StreamingOutputCall(request, _TIMEOUT) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for index, response in enumerate(response_iterator): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if response.payload.type != messages_pb2.COMPRESSABLE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            'response body of invalid type %s!' % response.payload.type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if len(response.payload.body) != sizes[index]: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            'response body of invalid size %d!' % len(response.payload.body)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class _Pipe(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def __init__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    self._condition = threading.Condition() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    self._values = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    self._open = True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def __iter__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return self 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def next(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    with self._condition: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while not self._values and self._open: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._condition.wait() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if self._values: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return self._values.pop(0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        raise StopIteration() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def add(self, value): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    with self._condition: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      self._values.append(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      self._condition.notify() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  def close(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    with self._condition: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      self._open = False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      self._condition.notify() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def _ping_pong(stub): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  request_response_sizes = (31415, 9, 2653, 58979) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  request_payload_sizes = (27182, 8, 1828, 45904) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  with stub: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pipe = _Pipe() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    print 'Starting ping-pong with response iterator %s' % response_iterator 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for response_size, payload_size in zip( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        request_response_sizes, request_payload_sizes): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      request = messages_pb2.StreamingOutputCallRequest( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          response_type=messages_pb2.COMPRESSABLE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          response_parameters=(messages_pb2.ResponseParameters( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              size=response_size),), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          payload=messages_pb2.Payload(body=b'\x00' * payload_size)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      pipe.add(request) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      response = next(response_iterator) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if response.payload.type != messages_pb2.COMPRESSABLE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            'response body of invalid type %s!' % response.payload.type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if len(response.payload.body) != response_size: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        raise ValueError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            'response body of invalid size %d!' % len(response.payload.body)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pipe.close() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def test_interoperability(test_case, stub): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if test_case == 'empty_unary': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _empty_unary(stub) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  elif test_case == 'large_unary': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _large_unary(stub) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  elif test_case == 'server_streaming': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _server_streaming(stub) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  elif test_case == 'client_streaming': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _client_streaming(stub) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  elif test_case == 'ping_pong': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    _ping_pong(stub) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    raise NotImplementedError('Test case "%s" not implemented!') 
			 |