|
|
|
@ -40,8 +40,24 @@ import unittest |
|
|
|
|
from grpc.framework.face import exceptions |
|
|
|
|
from grpc.framework.foundation import future |
|
|
|
|
|
|
|
|
|
# Identifiers of entities we expect to find in the generated module. |
|
|
|
|
SERVICER_IDENTIFIER = 'EarlyAdopterTestServiceServicer' |
|
|
|
|
SERVER_IDENTIFIER = 'EarlyAdopterTestServiceServer' |
|
|
|
|
STUB_IDENTIFIER = 'EarlyAdopterTestServiceStub' |
|
|
|
|
SERVER_FACTORY_IDENTIFIER = 'early_adopter_create_TestService_server' |
|
|
|
|
STUB_FACTORY_IDENTIFIER = 'early_adopter_create_TestService_stub' |
|
|
|
|
|
|
|
|
|
# Timeouts and delays. |
|
|
|
|
SHORT_TIMEOUT = 0.1 |
|
|
|
|
NORMAL_TIMEOUT = 1 |
|
|
|
|
LONG_TIMEOUT = 2 |
|
|
|
|
DOES_NOT_MATTER_DELAY = 0 |
|
|
|
|
NO_DELAY = 0 |
|
|
|
|
LONG_DELAY = 1 |
|
|
|
|
|
|
|
|
|
# Assigned in __main__. |
|
|
|
|
_build_mode = None |
|
|
|
|
_port = None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class _ServicerMethods(object): |
|
|
|
@ -71,14 +87,14 @@ class _ServicerMethods(object): |
|
|
|
|
while self._paused: |
|
|
|
|
time.sleep(0) |
|
|
|
|
|
|
|
|
|
def UnaryCall(self, request): |
|
|
|
|
def UnaryCall(self, request, context): |
|
|
|
|
response = self.test_pb2.SimpleResponse() |
|
|
|
|
response.payload.payload_type = self.test_pb2.COMPRESSABLE |
|
|
|
|
response.payload.payload_compressable = 'a' * request.response_size |
|
|
|
|
self._control() |
|
|
|
|
return response |
|
|
|
|
|
|
|
|
|
def StreamingOutputCall(self, request): |
|
|
|
|
def StreamingOutputCall(self, request, context): |
|
|
|
|
for parameter in request.response_parameters: |
|
|
|
|
response = self.test_pb2.StreamingOutputCallResponse() |
|
|
|
|
response.payload.payload_type = self.test_pb2.COMPRESSABLE |
|
|
|
@ -86,7 +102,7 @@ class _ServicerMethods(object): |
|
|
|
|
self._control() |
|
|
|
|
yield response |
|
|
|
|
|
|
|
|
|
def StreamingInputCall(self, request_iter): |
|
|
|
|
def StreamingInputCall(self, request_iter, context): |
|
|
|
|
response = self.test_pb2.StreamingInputCallResponse() |
|
|
|
|
aggregated_payload_size = 0 |
|
|
|
|
for request in request_iter: |
|
|
|
@ -95,7 +111,7 @@ class _ServicerMethods(object): |
|
|
|
|
self._control() |
|
|
|
|
return response |
|
|
|
|
|
|
|
|
|
def FullDuplexCall(self, request_iter): |
|
|
|
|
def FullDuplexCall(self, request_iter, context): |
|
|
|
|
for request in request_iter: |
|
|
|
|
for parameter in request.response_parameters: |
|
|
|
|
response = self.test_pb2.StreamingOutputCallResponse() |
|
|
|
@ -104,7 +120,7 @@ class _ServicerMethods(object): |
|
|
|
|
self._control() |
|
|
|
|
yield response |
|
|
|
|
|
|
|
|
|
def HalfDuplexCall(self, request_iter): |
|
|
|
|
def HalfDuplexCall(self, request_iter, context): |
|
|
|
|
responses = [] |
|
|
|
|
for request in request_iter: |
|
|
|
|
for parameter in request.response_parameters: |
|
|
|
@ -117,7 +133,7 @@ class _ServicerMethods(object): |
|
|
|
|
yield response |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def CreateService(test_pb2, delay=0, timeout=1): |
|
|
|
|
def _CreateService(test_pb2, delay): |
|
|
|
|
"""Provides a servicer backend and a stub. |
|
|
|
|
|
|
|
|
|
The servicer is just the implementation |
|
|
|
@ -136,28 +152,30 @@ def CreateService(test_pb2, delay=0, timeout=1): |
|
|
|
|
A two-tuple (servicer, stub), where the servicer is the back-end of the |
|
|
|
|
service bound to the stub. |
|
|
|
|
""" |
|
|
|
|
class Servicer(test_pb2.TestServiceServicer): |
|
|
|
|
servicer_methods = _ServicerMethods(test_pb2, delay) |
|
|
|
|
|
|
|
|
|
def UnaryCall(self, request): |
|
|
|
|
return servicer_methods.UnaryCall(request) |
|
|
|
|
class Servicer(getattr(test_pb2, SERVICER_IDENTIFIER)): |
|
|
|
|
|
|
|
|
|
def StreamingOutputCall(self, request): |
|
|
|
|
return servicer_methods.StreamingOutputCall(request) |
|
|
|
|
def UnaryCall(self, request, context): |
|
|
|
|
return servicer_methods.UnaryCall(request, context) |
|
|
|
|
|
|
|
|
|
def StreamingInputCall(self, request_iter): |
|
|
|
|
return servicer_methods.StreamingInputCall(request_iter) |
|
|
|
|
def StreamingOutputCall(self, request, context): |
|
|
|
|
return servicer_methods.StreamingOutputCall(request, context) |
|
|
|
|
|
|
|
|
|
def FullDuplexCall(self, request_iter): |
|
|
|
|
return servicer_methods.FullDuplexCall(request_iter) |
|
|
|
|
def StreamingInputCall(self, request_iter, context): |
|
|
|
|
return servicer_methods.StreamingInputCall(request_iter, context) |
|
|
|
|
|
|
|
|
|
def HalfDuplexCall(self, request_iter): |
|
|
|
|
return servicer_methods.HalfDuplexCall(request_iter) |
|
|
|
|
def FullDuplexCall(self, request_iter, context): |
|
|
|
|
return servicer_methods.FullDuplexCall(request_iter, context) |
|
|
|
|
|
|
|
|
|
def HalfDuplexCall(self, request_iter, context): |
|
|
|
|
return servicer_methods.HalfDuplexCall(request_iter, context) |
|
|
|
|
|
|
|
|
|
servicer_methods = _ServicerMethods(test_pb2, delay) |
|
|
|
|
servicer = Servicer() |
|
|
|
|
linked_pair = test_pb2.mock_TestService(servicer, timeout) |
|
|
|
|
stub = linked_pair.stub |
|
|
|
|
return servicer_methods, stub |
|
|
|
|
server = getattr(test_pb2, SERVER_FACTORY_IDENTIFIER)(servicer, _port, |
|
|
|
|
None, None) |
|
|
|
|
stub = getattr(test_pb2, STUB_FACTORY_IDENTIFIER)('localhost', _port) |
|
|
|
|
return servicer_methods, stub, server |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def StreamingInputRequest(test_pb2): |
|
|
|
@ -198,19 +216,20 @@ class PythonPluginTest(unittest.TestCase): |
|
|
|
|
def setUp(self): |
|
|
|
|
protoc_command = '../../bins/%s/protobuf/protoc' % _build_mode |
|
|
|
|
protoc_plugin_filename = '../../bins/%s/grpc_python_plugin' % _build_mode |
|
|
|
|
test_proto_filename = '../cpp/interop/test.proto' |
|
|
|
|
test_proto_filename = './test.proto' |
|
|
|
|
if not os.path.isfile(protoc_command): |
|
|
|
|
# Assume that if we haven't built protoc that it's on the system. |
|
|
|
|
protoc_command = 'protoc' |
|
|
|
|
|
|
|
|
|
# ensure that the output directory exists |
|
|
|
|
outdir = '../../gens/test/compiler/python/' |
|
|
|
|
# Ensure that the output directory exists. |
|
|
|
|
outdir = '../../gens/test/compiler/python' |
|
|
|
|
try: |
|
|
|
|
os.makedirs(outdir) |
|
|
|
|
except OSError as exception: |
|
|
|
|
if exception.errno != errno.EEXIST: |
|
|
|
|
raise |
|
|
|
|
|
|
|
|
|
# Invoke protoc with the plugin. |
|
|
|
|
cmd = [ |
|
|
|
|
protoc_command, |
|
|
|
|
'--plugin=protoc-gen-python-grpc=%s' % protoc_plugin_filename, |
|
|
|
@ -222,215 +241,231 @@ class PythonPluginTest(unittest.TestCase): |
|
|
|
|
subprocess.call(' '.join(cmd), shell=True) |
|
|
|
|
sys.path.append(outdir) |
|
|
|
|
|
|
|
|
|
self.delay = 1 # seconds |
|
|
|
|
self.timeout = 2 # seconds |
|
|
|
|
# TODO(atash): Figure out which of theses tests is hanging flakily with small |
|
|
|
|
# probability. |
|
|
|
|
|
|
|
|
|
def testImportAttributes(self): |
|
|
|
|
# check that we can access the members |
|
|
|
|
# check that we can access the generated module and its members. |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
self.assertIsNotNone(getattr(test_pb2, 'TestServiceServicer', None)) |
|
|
|
|
self.assertIsNotNone(getattr(test_pb2, 'TestServiceService', None)) |
|
|
|
|
self.assertIsNotNone(getattr(test_pb2, 'TestServiceStub', None)) |
|
|
|
|
self.assertIsNotNone(getattr(test_pb2, SERVICER_IDENTIFIER, None)) |
|
|
|
|
self.assertIsNotNone(getattr(test_pb2, SERVER_IDENTIFIER, None)) |
|
|
|
|
self.assertIsNotNone(getattr(test_pb2, STUB_IDENTIFIER, None)) |
|
|
|
|
self.assertIsNotNone(getattr(test_pb2, SERVER_FACTORY_IDENTIFIER, None)) |
|
|
|
|
self.assertIsNotNone(getattr(test_pb2, STUB_FACTORY_IDENTIFIER, None)) |
|
|
|
|
|
|
|
|
|
def testUpDown(self): |
|
|
|
|
import test_pb2 |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) |
|
|
|
|
request = test_pb2.SimpleRequest(response_size=13) |
|
|
|
|
with server, stub: |
|
|
|
|
pass |
|
|
|
|
|
|
|
|
|
def testUnaryCall(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, NO_DELAY) |
|
|
|
|
request = test_pb2.SimpleRequest(response_size=13) |
|
|
|
|
response = stub.UnaryCall(request) |
|
|
|
|
expected_response = servicer.UnaryCall(request) |
|
|
|
|
with server, stub: |
|
|
|
|
response = stub.UnaryCall(request, NORMAL_TIMEOUT) |
|
|
|
|
expected_response = servicer.UnaryCall(request, None) |
|
|
|
|
self.assertEqual(expected_response, response) |
|
|
|
|
|
|
|
|
|
def testUnaryCallAsync(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService( |
|
|
|
|
test_pb2, delay=self.delay, timeout=self.timeout) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, LONG_DELAY) |
|
|
|
|
request = test_pb2.SimpleRequest(response_size=13) |
|
|
|
|
# TODO(atash): consider using the 'profile' module? Does it even work here? |
|
|
|
|
start_time = time.clock() |
|
|
|
|
response_future = stub.UnaryCall.async(request) |
|
|
|
|
self.assertGreater(self.delay, time.clock() - start_time) |
|
|
|
|
response = response_future.result() |
|
|
|
|
expected_response = servicer.UnaryCall(request) |
|
|
|
|
with server, stub: |
|
|
|
|
start_time = time.clock() |
|
|
|
|
response_future = stub.UnaryCall.async(request, LONG_TIMEOUT) |
|
|
|
|
# Check that we didn't block on the asynchronous call. |
|
|
|
|
self.assertGreater(LONG_DELAY, time.clock() - start_time) |
|
|
|
|
response = response_future.result() |
|
|
|
|
expected_response = servicer.UnaryCall(request, None) |
|
|
|
|
self.assertEqual(expected_response, response) |
|
|
|
|
|
|
|
|
|
def testUnaryCallAsyncExpired(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
# set the timeout super low... |
|
|
|
|
servicer, stub = CreateService(test_pb2, delay=1, timeout=0.1) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, |
|
|
|
|
delay=DOES_NOT_MATTER_DELAY) |
|
|
|
|
request = test_pb2.SimpleRequest(response_size=13) |
|
|
|
|
with servicer.pause(): |
|
|
|
|
response_future = stub.UnaryCall.async(request) |
|
|
|
|
with self.assertRaises(exceptions.ExpirationError): |
|
|
|
|
response_future.result() |
|
|
|
|
with server, stub: |
|
|
|
|
with servicer.pause(): |
|
|
|
|
response_future = stub.UnaryCall.async(request, SHORT_TIMEOUT) |
|
|
|
|
with self.assertRaises(exceptions.ExpirationError): |
|
|
|
|
response_future.result() |
|
|
|
|
|
|
|
|
|
def testUnaryCallAsyncCancelled(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) |
|
|
|
|
request = test_pb2.SimpleRequest(response_size=13) |
|
|
|
|
with servicer.pause(): |
|
|
|
|
response_future = stub.UnaryCall.async(request) |
|
|
|
|
response_future.cancel() |
|
|
|
|
self.assertTrue(response_future.cancelled()) |
|
|
|
|
with server, stub: |
|
|
|
|
with servicer.pause(): |
|
|
|
|
response_future = stub.UnaryCall.async(request, 1) |
|
|
|
|
response_future.cancel() |
|
|
|
|
self.assertTrue(response_future.cancelled()) |
|
|
|
|
|
|
|
|
|
def testUnaryCallAsyncFailed(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) |
|
|
|
|
request = test_pb2.SimpleRequest(response_size=13) |
|
|
|
|
with servicer.fail(): |
|
|
|
|
response_future = stub.UnaryCall.async(request) |
|
|
|
|
self.assertIsNotNone(response_future.exception()) |
|
|
|
|
with server, stub: |
|
|
|
|
with servicer.fail(): |
|
|
|
|
response_future = stub.UnaryCall.async(request, NORMAL_TIMEOUT) |
|
|
|
|
self.assertIsNotNone(response_future.exception()) |
|
|
|
|
|
|
|
|
|
def testStreamingOutputCall(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, NO_DELAY) |
|
|
|
|
request = StreamingOutputRequest(test_pb2) |
|
|
|
|
responses = stub.StreamingOutputCall(request) |
|
|
|
|
expected_responses = servicer.StreamingOutputCall(request) |
|
|
|
|
for check in itertools.izip_longest(expected_responses, responses): |
|
|
|
|
expected_response, response = check |
|
|
|
|
self.assertEqual(expected_response, response) |
|
|
|
|
|
|
|
|
|
def testStreamingOutputCallAsync(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2, timeout=self.timeout) |
|
|
|
|
request = StreamingOutputRequest(test_pb2) |
|
|
|
|
responses = stub.StreamingOutputCall.async(request) |
|
|
|
|
expected_responses = servicer.StreamingOutputCall(request) |
|
|
|
|
for check in itertools.izip_longest(expected_responses, responses): |
|
|
|
|
expected_response, response = check |
|
|
|
|
self.assertEqual(expected_response, response) |
|
|
|
|
|
|
|
|
|
def testStreamingOutputCallAsyncExpired(self): |
|
|
|
|
with server, stub: |
|
|
|
|
responses = stub.StreamingOutputCall(request, NORMAL_TIMEOUT) |
|
|
|
|
expected_responses = servicer.StreamingOutputCall(request, None) |
|
|
|
|
for check in itertools.izip_longest(expected_responses, responses): |
|
|
|
|
expected_response, response = check |
|
|
|
|
self.assertEqual(expected_response, response) |
|
|
|
|
|
|
|
|
|
def testStreamingOutputCallExpired(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2, timeout=0.1) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) |
|
|
|
|
request = StreamingOutputRequest(test_pb2) |
|
|
|
|
with servicer.pause(): |
|
|
|
|
responses = stub.StreamingOutputCall.async(request) |
|
|
|
|
with self.assertRaises(exceptions.ExpirationError): |
|
|
|
|
list(responses) |
|
|
|
|
with server, stub: |
|
|
|
|
with servicer.pause(): |
|
|
|
|
responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT) |
|
|
|
|
with self.assertRaises(exceptions.ExpirationError): |
|
|
|
|
list(responses) |
|
|
|
|
|
|
|
|
|
def testStreamingOutputCallAsyncCancelled(self): |
|
|
|
|
def testStreamingOutputCallCancelled(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
_, stub = CreateService(test_pb2, timeout=0.1) |
|
|
|
|
unused_servicer, stub, server = _CreateService(test_pb2, |
|
|
|
|
DOES_NOT_MATTER_DELAY) |
|
|
|
|
request = StreamingOutputRequest(test_pb2) |
|
|
|
|
responses = stub.StreamingOutputCall.async(request) |
|
|
|
|
next(responses) |
|
|
|
|
responses.cancel() |
|
|
|
|
with self.assertRaises(future.CancelledError): |
|
|
|
|
with server, stub: |
|
|
|
|
responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT) |
|
|
|
|
next(responses) |
|
|
|
|
responses.cancel() |
|
|
|
|
with self.assertRaises(future.CancelledError): |
|
|
|
|
next(responses) |
|
|
|
|
|
|
|
|
|
def testStreamingOutputCallAsyncFailed(self): |
|
|
|
|
@unittest.skip('TODO(atash,nathaniel): figure out why this times out ' |
|
|
|
|
'instead of raising the proper error.') |
|
|
|
|
def testStreamingOutputCallFailed(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2, timeout=0.1) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) |
|
|
|
|
request = StreamingOutputRequest(test_pb2) |
|
|
|
|
with servicer.fail(): |
|
|
|
|
responses = stub.StreamingOutputCall.async(request) |
|
|
|
|
self.assertIsNotNone(responses) |
|
|
|
|
with self.assertRaises(exceptions.ServicerError): |
|
|
|
|
next(responses) |
|
|
|
|
with server, stub: |
|
|
|
|
with servicer.fail(): |
|
|
|
|
responses = stub.StreamingOutputCall(request, 1) |
|
|
|
|
self.assertIsNotNone(responses) |
|
|
|
|
with self.assertRaises(exceptions.ServicerError): |
|
|
|
|
next(responses) |
|
|
|
|
|
|
|
|
|
def testStreamingInputCall(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2) |
|
|
|
|
response = stub.StreamingInputCall(StreamingInputRequest(test_pb2)) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, NO_DELAY) |
|
|
|
|
with server, stub: |
|
|
|
|
response = stub.StreamingInputCall(StreamingInputRequest(test_pb2), |
|
|
|
|
NORMAL_TIMEOUT) |
|
|
|
|
expected_response = servicer.StreamingInputCall( |
|
|
|
|
StreamingInputRequest(test_pb2)) |
|
|
|
|
StreamingInputRequest(test_pb2), None) |
|
|
|
|
self.assertEqual(expected_response, response) |
|
|
|
|
|
|
|
|
|
def testStreamingInputCallAsync(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService( |
|
|
|
|
test_pb2, delay=self.delay, timeout=self.timeout) |
|
|
|
|
start_time = time.clock() |
|
|
|
|
response_future = stub.StreamingInputCall.async( |
|
|
|
|
StreamingInputRequest(test_pb2)) |
|
|
|
|
self.assertGreater(self.delay, time.clock() - start_time) |
|
|
|
|
response = response_future.result() |
|
|
|
|
servicer, stub, server = _CreateService( |
|
|
|
|
test_pb2, LONG_DELAY) |
|
|
|
|
with server, stub: |
|
|
|
|
start_time = time.clock() |
|
|
|
|
response_future = stub.StreamingInputCall.async( |
|
|
|
|
StreamingInputRequest(test_pb2), LONG_TIMEOUT) |
|
|
|
|
self.assertGreater(LONG_DELAY, time.clock() - start_time) |
|
|
|
|
response = response_future.result() |
|
|
|
|
expected_response = servicer.StreamingInputCall( |
|
|
|
|
StreamingInputRequest(test_pb2)) |
|
|
|
|
StreamingInputRequest(test_pb2), None) |
|
|
|
|
self.assertEqual(expected_response, response) |
|
|
|
|
|
|
|
|
|
def testStreamingInputCallAsyncExpired(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
# set the timeout super low... |
|
|
|
|
servicer, stub = CreateService(test_pb2, delay=1, timeout=0.1) |
|
|
|
|
with servicer.pause(): |
|
|
|
|
response_future = stub.StreamingInputCall.async( |
|
|
|
|
StreamingInputRequest(test_pb2)) |
|
|
|
|
with self.assertRaises(exceptions.ExpirationError): |
|
|
|
|
response_future.result() |
|
|
|
|
self.assertIsInstance( |
|
|
|
|
response_future.exception(), exceptions.ExpirationError) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) |
|
|
|
|
with server, stub: |
|
|
|
|
with servicer.pause(): |
|
|
|
|
response_future = stub.StreamingInputCall.async( |
|
|
|
|
StreamingInputRequest(test_pb2), SHORT_TIMEOUT) |
|
|
|
|
with self.assertRaises(exceptions.ExpirationError): |
|
|
|
|
response_future.result() |
|
|
|
|
self.assertIsInstance( |
|
|
|
|
response_future.exception(), exceptions.ExpirationError) |
|
|
|
|
|
|
|
|
|
def testStreamingInputCallAsyncCancelled(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2) |
|
|
|
|
with servicer.pause(): |
|
|
|
|
response_future = stub.StreamingInputCall.async( |
|
|
|
|
StreamingInputRequest(test_pb2)) |
|
|
|
|
response_future.cancel() |
|
|
|
|
self.assertTrue(response_future.cancelled()) |
|
|
|
|
with self.assertRaises(future.CancelledError): |
|
|
|
|
response_future.result() |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) |
|
|
|
|
with server, stub: |
|
|
|
|
with servicer.pause(): |
|
|
|
|
response_future = stub.StreamingInputCall.async( |
|
|
|
|
StreamingInputRequest(test_pb2), NORMAL_TIMEOUT) |
|
|
|
|
response_future.cancel() |
|
|
|
|
self.assertTrue(response_future.cancelled()) |
|
|
|
|
with self.assertRaises(future.CancelledError): |
|
|
|
|
response_future.result() |
|
|
|
|
|
|
|
|
|
def testStreamingInputCallAsyncFailed(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2) |
|
|
|
|
with servicer.fail(): |
|
|
|
|
response_future = stub.StreamingInputCall.async( |
|
|
|
|
StreamingInputRequest(test_pb2)) |
|
|
|
|
self.assertIsNotNone(response_future.exception()) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) |
|
|
|
|
with server, stub: |
|
|
|
|
with servicer.fail(): |
|
|
|
|
response_future = stub.StreamingInputCall.async( |
|
|
|
|
StreamingInputRequest(test_pb2), SHORT_TIMEOUT) |
|
|
|
|
self.assertIsNotNone(response_future.exception()) |
|
|
|
|
|
|
|
|
|
def testFullDuplexCall(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2) |
|
|
|
|
responses = stub.FullDuplexCall(FullDuplexRequest(test_pb2)) |
|
|
|
|
expected_responses = servicer.FullDuplexCall(FullDuplexRequest(test_pb2)) |
|
|
|
|
for check in itertools.izip_longest(expected_responses, responses): |
|
|
|
|
expected_response, response = check |
|
|
|
|
self.assertEqual(expected_response, response) |
|
|
|
|
|
|
|
|
|
def testFullDuplexCallAsync(self): |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, NO_DELAY) |
|
|
|
|
with server, stub: |
|
|
|
|
responses = stub.FullDuplexCall(FullDuplexRequest(test_pb2), |
|
|
|
|
NORMAL_TIMEOUT) |
|
|
|
|
expected_responses = servicer.FullDuplexCall(FullDuplexRequest(test_pb2), |
|
|
|
|
None) |
|
|
|
|
for check in itertools.izip_longest(expected_responses, responses): |
|
|
|
|
expected_response, response = check |
|
|
|
|
self.assertEqual(expected_response, response) |
|
|
|
|
|
|
|
|
|
def testFullDuplexCallExpired(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2, timeout=self.timeout) |
|
|
|
|
responses = stub.FullDuplexCall.async(FullDuplexRequest(test_pb2)) |
|
|
|
|
expected_responses = servicer.FullDuplexCall(FullDuplexRequest(test_pb2)) |
|
|
|
|
for check in itertools.izip_longest(expected_responses, responses): |
|
|
|
|
expected_response, response = check |
|
|
|
|
self.assertEqual(expected_response, response) |
|
|
|
|
|
|
|
|
|
def testFullDuplexCallAsyncExpired(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2, timeout=0.1) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) |
|
|
|
|
request = FullDuplexRequest(test_pb2) |
|
|
|
|
with servicer.pause(): |
|
|
|
|
responses = stub.FullDuplexCall.async(request) |
|
|
|
|
with self.assertRaises(exceptions.ExpirationError): |
|
|
|
|
list(responses) |
|
|
|
|
with server, stub: |
|
|
|
|
with servicer.pause(): |
|
|
|
|
responses = stub.FullDuplexCall(request, SHORT_TIMEOUT) |
|
|
|
|
with self.assertRaises(exceptions.ExpirationError): |
|
|
|
|
list(responses) |
|
|
|
|
|
|
|
|
|
def testFullDuplexCallAsyncCancelled(self): |
|
|
|
|
def testFullDuplexCallCancelled(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
_, stub = CreateService(test_pb2, timeout=0.1) |
|
|
|
|
request = FullDuplexRequest(test_pb2) |
|
|
|
|
responses = stub.FullDuplexCall.async(request) |
|
|
|
|
next(responses) |
|
|
|
|
responses.cancel() |
|
|
|
|
with self.assertRaises(future.CancelledError): |
|
|
|
|
unused_servicer, stub, server = _CreateService(test_pb2, NO_DELAY) |
|
|
|
|
with server, stub: |
|
|
|
|
request = FullDuplexRequest(test_pb2) |
|
|
|
|
responses = stub.FullDuplexCall(request, NORMAL_TIMEOUT) |
|
|
|
|
next(responses) |
|
|
|
|
responses.cancel() |
|
|
|
|
with self.assertRaises(future.CancelledError): |
|
|
|
|
next(responses) |
|
|
|
|
|
|
|
|
|
def testFullDuplexCallAsyncFailed(self): |
|
|
|
|
@unittest.skip('TODO(atash,nathaniel): figure out why this hangs forever ' |
|
|
|
|
'and fix.') |
|
|
|
|
def testFullDuplexCallFailed(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2, timeout=0.1) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) |
|
|
|
|
request = FullDuplexRequest(test_pb2) |
|
|
|
|
with servicer.fail(): |
|
|
|
|
responses = stub.FullDuplexCall.async(request) |
|
|
|
|
self.assertIsNotNone(responses) |
|
|
|
|
with self.assertRaises(exceptions.ServicerError): |
|
|
|
|
next(responses) |
|
|
|
|
with server, stub: |
|
|
|
|
with servicer.fail(): |
|
|
|
|
responses = stub.FullDuplexCall(request, NORMAL_TIMEOUT) |
|
|
|
|
self.assertIsNotNone(responses) |
|
|
|
|
with self.assertRaises(exceptions.ServicerError): |
|
|
|
|
next(responses) |
|
|
|
|
|
|
|
|
|
def testHalfDuplexCall(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
servicer, stub = CreateService(test_pb2) |
|
|
|
|
servicer, stub, server = _CreateService(test_pb2, NO_DELAY) |
|
|
|
|
def HalfDuplexRequest(): |
|
|
|
|
request = test_pb2.StreamingOutputCallRequest() |
|
|
|
|
request.response_parameters.add(size=1, interval_us=0) |
|
|
|
@ -439,15 +474,16 @@ class PythonPluginTest(unittest.TestCase): |
|
|
|
|
request.response_parameters.add(size=2, interval_us=0) |
|
|
|
|
request.response_parameters.add(size=3, interval_us=0) |
|
|
|
|
yield request |
|
|
|
|
responses = stub.HalfDuplexCall(HalfDuplexRequest()) |
|
|
|
|
expected_responses = servicer.HalfDuplexCall(HalfDuplexRequest()) |
|
|
|
|
for check in itertools.izip_longest(expected_responses, responses): |
|
|
|
|
expected_response, response = check |
|
|
|
|
self.assertEqual(expected_response, response) |
|
|
|
|
|
|
|
|
|
def testHalfDuplexCallAsyncWedged(self): |
|
|
|
|
with server, stub: |
|
|
|
|
responses = stub.HalfDuplexCall(HalfDuplexRequest(), NORMAL_TIMEOUT) |
|
|
|
|
expected_responses = servicer.HalfDuplexCall(HalfDuplexRequest(), None) |
|
|
|
|
for check in itertools.izip_longest(expected_responses, responses): |
|
|
|
|
expected_response, response = check |
|
|
|
|
self.assertEqual(expected_response, response) |
|
|
|
|
|
|
|
|
|
def testHalfDuplexCallWedged(self): |
|
|
|
|
import test_pb2 # pylint: disable=g-import-not-at-top |
|
|
|
|
_, stub = CreateService(test_pb2, timeout=1) |
|
|
|
|
_, stub, server = _CreateService(test_pb2, NO_DELAY) |
|
|
|
|
wait_flag = [False] |
|
|
|
|
@contextlib.contextmanager |
|
|
|
|
def wait(): # pylint: disable=invalid-name |
|
|
|
@ -461,20 +497,25 @@ class PythonPluginTest(unittest.TestCase): |
|
|
|
|
yield request |
|
|
|
|
while wait_flag[0]: |
|
|
|
|
time.sleep(0.1) |
|
|
|
|
with wait(): |
|
|
|
|
responses = stub.HalfDuplexCall.async(HalfDuplexRequest()) |
|
|
|
|
# half-duplex waits for the client to send all info |
|
|
|
|
with self.assertRaises(exceptions.ExpirationError): |
|
|
|
|
next(responses) |
|
|
|
|
with server, stub: |
|
|
|
|
with wait(): |
|
|
|
|
responses = stub.HalfDuplexCall(HalfDuplexRequest(), NORMAL_TIMEOUT) |
|
|
|
|
# half-duplex waits for the client to send all info |
|
|
|
|
with self.assertRaises(exceptions.ExpirationError): |
|
|
|
|
next(responses) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
|
os.chdir(os.path.dirname(sys.argv[0])) |
|
|
|
|
parser = argparse.ArgumentParser(description='Run Python compiler plugin test.') |
|
|
|
|
parser.add_argument('--build_mode', dest='build_mode', type=str, default='dbg', |
|
|
|
|
help='The build mode of the targets to test, e.g. ' |
|
|
|
|
'"dbg", "opt", "asan", etc.') |
|
|
|
|
parser = argparse.ArgumentParser( |
|
|
|
|
description='Run Python compiler plugin test.') |
|
|
|
|
parser.add_argument( |
|
|
|
|
'--build_mode', dest='build_mode', type=str, default='dbg', |
|
|
|
|
help='The build mode of the targets to test, e.g. "dbg", "opt", "asan", ' |
|
|
|
|
'etc.') |
|
|
|
|
parser.add_argument('--port', dest='port', type=int, default=0) |
|
|
|
|
args, remainder = parser.parse_known_args() |
|
|
|
|
_build_mode = args.build_mode |
|
|
|
|
_port = args.port |
|
|
|
|
sys.argv[1:] = remainder |
|
|
|
|
unittest.main() |
|
|
|
|