aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/python/grpcio_tests/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/python/grpcio_tests/tests')
-rw-r--r--src/python/grpcio_tests/tests/_runner.py20
-rw-r--r--src/python/grpcio_tests/tests/health_check/_health_servicer_test.py58
-rw-r--r--src/python/grpcio_tests/tests/interop/_insecure_interop_test.py2
-rw-r--r--src/python/grpcio_tests/tests/interop/_secure_interop_test.py2
-rw-r--r--src/python/grpcio_tests/tests/interop/methods.py46
-rw-r--r--src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py4
-rw-r--r--src/python/grpcio_tests/tests/qps/benchmark_client.py37
-rw-r--r--src/python/grpcio_tests/tests/qps/benchmark_server.py4
-rw-r--r--src/python/grpcio_tests/tests/qps/qps_worker.py7
-rw-r--r--src/python/grpcio_tests/tests/qps/worker_server.py36
-rw-r--r--src/python/grpcio_tests/tests/tests.json1
-rw-r--r--src/python/grpcio_tests/tests/unit/_adapter/.gitignore5
-rw-r--r--src/python/grpcio_tests/tests/unit/_adapter/__init__.py30
-rw-r--r--src/python/grpcio_tests/tests/unit/_adapter/_proto_scenarios.py262
-rw-r--r--src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py4
-rw-r--r--src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_compression_test.py3
-rw-r--r--src/python/grpcio_tests/tests/unit/_credentials_test.py72
-rw-r--r--src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py8
-rw-r--r--src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py22
-rw-r--r--src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py11
-rw-r--r--src/python/grpcio_tests/tests/unit/_empty_message_test.py3
-rw-r--r--src/python/grpcio_tests/tests/unit/_exit_scenarios.py8
-rw-r--r--src/python/grpcio_tests/tests/unit/_junkdrawer/math_pb2.py266
-rw-r--r--src/python/grpcio_tests/tests/unit/_links/__init__.py30
-rw-r--r--src/python/grpcio_tests/tests/unit/_links/_proto_scenarios.py262
-rw-r--r--src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_metadata_test.py4
-rw-r--r--src/python/grpcio_tests/tests/unit/_rpc_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/core/__init__.py30
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/interfaces/base/__init__.py30
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/interfaces/base/_control.py570
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/interfaces/base/_sequence.py171
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/interfaces/base/_state.py55
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/interfaces/base/test_cases.py279
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/interfaces/base/test_interfaces.py186
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py31
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/interfaces/face/_receiver.py95
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/interfaces/links/__init__.py30
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/interfaces/links/test_cases.py327
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/interfaces/links/test_utilities.py167
-rw-r--r--src/python/grpcio_tests/tests/unit/test_common.py22
42 files changed, 311 insertions, 2895 deletions
diff --git a/src/python/grpcio_tests/tests/_runner.py b/src/python/grpcio_tests/tests/_runner.py
index f0718573e2..926dcbe23a 100644
--- a/src/python/grpcio_tests/tests/_runner.py
+++ b/src/python/grpcio_tests/tests/_runner.py
@@ -30,7 +30,6 @@
from __future__ import absolute_import
import collections
-import fcntl
import multiprocessing
import os
import select
@@ -178,15 +177,20 @@ class Runner(object):
stderr_pipe.write_bypass(
'\ninterrupted stderr:\n{}\n'.format(stderr_pipe.output().decode()))
os._exit(1)
- signal.signal(signal.SIGINT, sigint_handler)
- signal.signal(signal.SIGSEGV, fault_handler)
- signal.signal(signal.SIGBUS, fault_handler)
- signal.signal(signal.SIGABRT, fault_handler)
- signal.signal(signal.SIGFPE, fault_handler)
- signal.signal(signal.SIGILL, fault_handler)
+ def try_set_handler(name, handler):
+ try:
+ signal.signal(getattr(signal, name), handler)
+ except AttributeError:
+ pass
+ try_set_handler('SIGINT', sigint_handler)
+ try_set_handler('SIGSEGV', fault_handler)
+ try_set_handler('SIGBUS', fault_handler)
+ try_set_handler('SIGABRT', fault_handler)
+ try_set_handler('SIGFPE', fault_handler)
+ try_set_handler('SIGILL', fault_handler)
# Sometimes output will lag after a test has successfully finished; we
# ignore such writes to our pipes.
- signal.signal(signal.SIGPIPE, signal.SIG_IGN)
+ try_set_handler('SIGPIPE', signal.SIG_IGN)
# Run the tests
result.startTestRun()
diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
index 1b63388663..80300d13df 100644
--- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
+++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py
@@ -27,48 +27,68 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""Tests of grpc_health.health.v1.health."""
+"""Tests of grpc.health.v1.health."""
import unittest
-from grpc_health.health.v1 import health
-from grpc_health.health.v1 import health_pb2
+import grpc
+from grpc.framework.foundation import logging_pool
+from grpc.health.v1 import health
+from grpc.health.v1 import health_pb2
+
+from tests.unit.framework.common import test_constants
class HealthServicerTest(unittest.TestCase):
def setUp(self):
- self.servicer = health.HealthServicer()
- self.servicer.set('', health_pb2.HealthCheckResponse.SERVING)
- self.servicer.set('grpc.test.TestServiceServing',
- health_pb2.HealthCheckResponse.SERVING)
- self.servicer.set('grpc.test.TestServiceUnknown',
- health_pb2.HealthCheckResponse.UNKNOWN)
- self.servicer.set('grpc.test.TestServiceNotServing',
- health_pb2.HealthCheckResponse.NOT_SERVING)
+ servicer = health.HealthServicer()
+ servicer.set('', health_pb2.HealthCheckResponse.SERVING)
+ servicer.set('grpc.test.TestServiceServing',
+ health_pb2.HealthCheckResponse.SERVING)
+ servicer.set('grpc.test.TestServiceUnknown',
+ health_pb2.HealthCheckResponse.UNKNOWN)
+ servicer.set('grpc.test.TestServiceNotServing',
+ health_pb2.HealthCheckResponse.NOT_SERVING)
+ server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+ self._server = grpc.server(server_pool)
+ port = self._server.add_insecure_port('[::]:0')
+ health_pb2.add_HealthServicer_to_server(servicer, self._server)
+ self._server.start()
+
+ channel = grpc.insecure_channel('localhost:%d' % port)
+ self._stub = health_pb2.HealthStub(channel)
def test_empty_service(self):
request = health_pb2.HealthCheckRequest()
- resp = self.servicer.Check(request, None)
- self.assertEqual(resp.status, health_pb2.HealthCheckResponse.SERVING)
+ resp = self._stub.Check(request)
+ self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status)
def test_serving_service(self):
request = health_pb2.HealthCheckRequest(
service='grpc.test.TestServiceServing')
- resp = self.servicer.Check(request, None)
- self.assertEqual(resp.status, health_pb2.HealthCheckResponse.SERVING)
+ resp = self._stub.Check(request)
+ self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status)
def test_unknown_serivce(self):
request = health_pb2.HealthCheckRequest(
service='grpc.test.TestServiceUnknown')
- resp = self.servicer.Check(request, None)
- self.assertEqual(resp.status, health_pb2.HealthCheckResponse.UNKNOWN)
+ resp = self._stub.Check(request)
+ self.assertEqual(health_pb2.HealthCheckResponse.UNKNOWN, resp.status)
def test_not_serving_service(self):
request = health_pb2.HealthCheckRequest(
service='grpc.test.TestServiceNotServing')
- resp = self.servicer.Check(request, None)
- self.assertEqual(resp.status, health_pb2.HealthCheckResponse.NOT_SERVING)
+ resp = self._stub.Check(request)
+ self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, resp.status)
+
+ def test_not_found_service(self):
+ request = health_pb2.HealthCheckRequest(
+ service='not-found')
+ with self.assertRaises(grpc.RpcError) as context:
+ resp = self._stub.Check(request)
+
+ self.assertEqual(grpc.StatusCode.NOT_FOUND, context.exception.code())
if __name__ == '__main__':
diff --git a/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py b/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py
index 91519b6fba..c753d6faf0 100644
--- a/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py
+++ b/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py
@@ -48,7 +48,7 @@ class InsecureInteropTest(
port = self.server.add_insecure_port('[::]:0')
self.server.start()
self.stub = test_pb2.beta_create_TestService_stub(
- implementations.insecure_channel('[::]', port))
+ implementations.insecure_channel('localhost', port))
def tearDown(self):
self.server.stop(0)
diff --git a/src/python/grpcio_tests/tests/interop/_secure_interop_test.py b/src/python/grpcio_tests/tests/interop/_secure_interop_test.py
index c61547b977..cb09f54a34 100644
--- a/src/python/grpcio_tests/tests/interop/_secure_interop_test.py
+++ b/src/python/grpcio_tests/tests/interop/_secure_interop_test.py
@@ -55,7 +55,7 @@ class SecureInteropTest(
self.server.start()
self.stub = test_pb2.beta_create_TestService_stub(
test_utilities.not_really_secure_channel(
- '[::]', port, implementations.ssl_channel_credentials(
+ 'localhost', port, implementations.ssl_channel_credentials(
resources.test_root_certificates()),
_SERVER_HOST_OVERRIDE))
diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py
index 86aa0495a2..97e6c9e27e 100644
--- a/src/python/grpcio_tests/tests/interop/methods.py
+++ b/src/python/grpcio_tests/tests/interop/methods.py
@@ -39,6 +39,7 @@ import time
from oauth2client import client as oauth2client_client
+import grpc
from grpc.beta import implementations
from grpc.beta import interfaces
from grpc.framework.common import cardinality
@@ -57,12 +58,18 @@ class TestService(test_pb2.BetaTestServiceServicer):
return empty_pb2.Empty()
def UnaryCall(self, request, context):
+ if request.HasField('response_status'):
+ context.code(request.response_status.code)
+ context.details(request.response_status.message)
return messages_pb2.SimpleResponse(
payload=messages_pb2.Payload(
type=messages_pb2.COMPRESSABLE,
body=b'\x00' * request.response_size))
def StreamingOutputCall(self, request, context):
+ if request.HasField('response_status'):
+ context.code(request.response_status.code)
+ context.details(request.response_status.message)
for response_parameters in request.response_parameters:
yield messages_pb2.StreamingOutputCallResponse(
payload=messages_pb2.Payload(
@@ -79,6 +86,9 @@ class TestService(test_pb2.BetaTestServiceServicer):
def FullDuplexCall(self, request_iterator, context):
for request in request_iterator:
+ if request.HasField('response_status'):
+ context.code(request.response_status.code)
+ context.details(request.response_status.message)
for response_parameters in request.response_parameters:
yield messages_pb2.StreamingOutputCallResponse(
payload=messages_pb2.Payload(
@@ -289,6 +299,39 @@ def _empty_stream(stub):
pass
+def _status_code_and_message(stub):
+ with stub:
+ message = 'test status message'
+ code = 2
+ status = grpc.StatusCode.UNKNOWN # code = 2
+ request = messages_pb2.SimpleRequest(
+ response_type=messages_pb2.COMPRESSABLE,
+ response_size=1,
+ payload=messages_pb2.Payload(body=b'\x00'),
+ response_status=messages_pb2.EchoStatus(code=code, message=message)
+ )
+ response_future = stub.UnaryCall.future(request, _TIMEOUT)
+ if response_future.code() != status:
+ raise ValueError(
+ 'expected code %s, got %s' % (status, response_future.code()))
+ if response_future.details() != message:
+ raise ValueError(
+ 'expected message %s, got %s' % (message, response_future.details()))
+
+ request = messages_pb2.StreamingOutputCallRequest(
+ response_type=messages_pb2.COMPRESSABLE,
+ response_parameters=(
+ messages_pb2.ResponseParameters(size=1),),
+ response_status=messages_pb2.EchoStatus(code=code, message=message))
+ response_iterator = stub.StreamingOutputCall(request, _TIMEOUT)
+ if response_future.code() != status:
+ raise ValueError(
+ 'expected code %s, got %s' % (status, response_iterator.code()))
+ if response_future.details() != message:
+ raise ValueError(
+ 'expected message %s, got %s' % (message, response_iterator.details()))
+
+
def _compute_engine_creds(stub, args):
response = _large_unary_common_behavior(stub, True, True)
if args.default_service_account != response.username:
@@ -347,6 +390,7 @@ class TestCase(enum.Enum):
CANCEL_AFTER_BEGIN = 'cancel_after_begin'
CANCEL_AFTER_FIRST_RESPONSE = 'cancel_after_first_response'
EMPTY_STREAM = 'empty_stream'
+ STATUS_CODE_AND_MESSAGE = 'status_code_and_message'
COMPUTE_ENGINE_CREDS = 'compute_engine_creds'
OAUTH2_AUTH_TOKEN = 'oauth2_auth_token'
JWT_TOKEN_CREDS = 'jwt_token_creds'
@@ -372,6 +416,8 @@ class TestCase(enum.Enum):
_timeout_on_sleeping_server(stub)
elif self is TestCase.EMPTY_STREAM:
_empty_stream(stub)
+ elif self is TestCase.STATUS_CODE_AND_MESSAGE:
+ _status_code_and_message(stub)
elif self is TestCase.COMPUTE_ENGINE_CREDS:
_compute_engine_creds(stub, args)
elif self is TestCase.OAUTH2_AUTH_TOKEN:
diff --git a/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py b/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py
index bf09380c85..7ca2bcff38 100644
--- a/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py
+++ b/src/python/grpcio_tests/tests/protoc_plugin/_python_plugin_test.py
@@ -171,7 +171,7 @@ def _CreateService():
return servicer_methods.HalfDuplexCall(request_iter, context)
server = grpc.server(
- (), futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
+ futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
getattr(service_pb2, ADD_SERVICER_TO_SERVER_IDENTIFIER)(Servicer(), server)
port = server.add_insecure_port('[::]:0')
server.start()
@@ -192,7 +192,7 @@ def _CreateIncompleteService():
pass
server = grpc.server(
- (), futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
+ futures.ThreadPoolExecutor(max_workers=test_constants.POOL_SIZE))
getattr(service_pb2, ADD_SERVICER_TO_SERVER_IDENTIFIER)(Servicer(), server)
port = server.add_insecure_port('[::]:0')
server.start()
diff --git a/src/python/grpcio_tests/tests/qps/benchmark_client.py b/src/python/grpcio_tests/tests/qps/benchmark_client.py
index 080281415d..83b46c914e 100644
--- a/src/python/grpcio_tests/tests/qps/benchmark_client.py
+++ b/src/python/grpcio_tests/tests/qps/benchmark_client.py
@@ -37,16 +37,23 @@ from concurrent import futures
from six.moves import queue
import grpc
-from grpc.beta import implementations
-from grpc.framework.interfaces.face import face
from src.proto.grpc.testing import messages_pb2
from src.proto.grpc.testing import services_pb2
from tests.unit import resources
-from tests.unit.beta import test_utilities
+from tests.unit import test_common
_TIMEOUT = 60 * 60 * 24
+class GenericStub(object):
+
+ def __init__(self, channel):
+ self.UnaryCall = channel.unary_unary(
+ '/grpc.testing.BenchmarkService/UnaryCall')
+ self.StreamingCall = channel.stream_stream(
+ '/grpc.testing.BenchmarkService/StreamingCall')
+
+
class BenchmarkClient:
"""Benchmark client interface that exposes a non-blocking send_request()."""
@@ -54,15 +61,12 @@ class BenchmarkClient:
def __init__(self, server, config, hist):
# Create the stub
- host, port = server.split(':')
- port = int(port)
if config.HasField('security_params'):
- creds = implementations.ssl_channel_credentials(
- resources.test_root_certificates())
- channel = test_utilities.not_really_secure_channel(
- host, port, creds, config.security_params.server_host_override)
+ creds = grpc.ssl_channel_credentials(resources.test_root_certificates())
+ channel = test_common.test_secure_channel(
+ server, creds, config.security_params.server_host_override)
else:
- channel = implementations.insecure_channel(host, port)
+ channel = grpc.insecure_channel(server)
connected_event = threading.Event()
def wait_for_ready(connectivity):
@@ -73,7 +77,7 @@ class BenchmarkClient:
if config.payload_config.WhichOneof('payload') == 'simple_params':
self._generic = False
- self._stub = services_pb2.beta_create_BenchmarkService_stub(channel)
+ self._stub = services_pb2.BenchmarkServiceStub(channel)
payload = messages_pb2.Payload(
body='\0' * config.payload_config.simple_params.req_size)
self._request = messages_pb2.SimpleRequest(
@@ -81,7 +85,7 @@ class BenchmarkClient:
response_size=config.payload_config.simple_params.resp_size)
else:
self._generic = True
- self._stub = implementations.generic_stub(channel)
+ self._stub = GenericStub(channel)
self._request = '\0' * config.payload_config.bytebuf_params.req_size
self._hist = hist
@@ -166,13 +170,8 @@ class _SyncStream(object):
def start(self):
self._is_streaming = True
- if self._generic:
- stream_callable = self._stub.stream_stream(
- 'grpc.testing.BenchmarkService', 'StreamingCall')
- else:
- stream_callable = self._stub.StreamingCall
-
- response_stream = stream_callable(self._request_generator(), _TIMEOUT)
+ response_stream = self._stub.StreamingCall(
+ self._request_generator(), _TIMEOUT)
for _ in response_stream:
self._handle_response(
self, time.time() - self._send_time_queue.get_nowait())
diff --git a/src/python/grpcio_tests/tests/qps/benchmark_server.py b/src/python/grpcio_tests/tests/qps/benchmark_server.py
index 8cbf480d58..2b76b810cd 100644
--- a/src/python/grpcio_tests/tests/qps/benchmark_server.py
+++ b/src/python/grpcio_tests/tests/qps/benchmark_server.py
@@ -31,7 +31,7 @@ from src.proto.grpc.testing import messages_pb2
from src.proto.grpc.testing import services_pb2
-class BenchmarkServer(services_pb2.BetaBenchmarkServiceServicer):
+class BenchmarkServer(services_pb2.BenchmarkServiceServicer):
"""Synchronous Server implementation for the Benchmark service."""
def UnaryCall(self, request, context):
@@ -44,7 +44,7 @@ class BenchmarkServer(services_pb2.BetaBenchmarkServiceServicer):
yield messages_pb2.SimpleResponse(payload=payload)
-class GenericBenchmarkServer(services_pb2.BetaBenchmarkServiceServicer):
+class GenericBenchmarkServer(services_pb2.BenchmarkServiceServicer):
"""Generic Server implementation for the Benchmark service."""
def __init__(self, resp_size):
diff --git a/src/python/grpcio_tests/tests/qps/qps_worker.py b/src/python/grpcio_tests/tests/qps/qps_worker.py
index 16926379a5..2371ff0956 100644
--- a/src/python/grpcio_tests/tests/qps/qps_worker.py
+++ b/src/python/grpcio_tests/tests/qps/qps_worker.py
@@ -32,18 +32,21 @@
import argparse
import time
+from concurrent import futures
+import grpc
from src.proto.grpc.testing import services_pb2
from tests.qps import worker_server
def run_worker_server(port):
+ server = grpc.server(futures.ThreadPoolExecutor(max_workers=5))
servicer = worker_server.WorkerServer()
- server = services_pb2.beta_create_WorkerService_server(servicer)
+ services_pb2.add_WorkerServiceServicer_to_server(servicer, server)
server.add_insecure_port('[::]:{}'.format(port))
server.start()
servicer.wait_for_quit()
- server.stop(2)
+ server.stop(0)
if __name__ == '__main__':
diff --git a/src/python/grpcio_tests/tests/qps/worker_server.py b/src/python/grpcio_tests/tests/qps/worker_server.py
index d41f8377c2..46d542940f 100644
--- a/src/python/grpcio_tests/tests/qps/worker_server.py
+++ b/src/python/grpcio_tests/tests/qps/worker_server.py
@@ -32,8 +32,8 @@ import random
import threading
import time
-from grpc.beta import implementations
-from grpc.framework.interfaces.face import utilities
+from concurrent import futures
+import grpc
from src.proto.grpc.testing import control_pb2
from src.proto.grpc.testing import services_pb2
from src.proto.grpc.testing import stats_pb2
@@ -45,7 +45,7 @@ from tests.qps import histogram
from tests.unit import resources
-class WorkerServer(services_pb2.BetaWorkerServiceServicer):
+class WorkerServer(services_pb2.WorkerServiceServicer):
"""Python Worker Server implementation."""
def __init__(self):
@@ -65,7 +65,7 @@ class WorkerServer(services_pb2.BetaWorkerServiceServicer):
if request.mark.reset:
start_time = end_time
yield status
- server.stop(0)
+ server.stop(None)
def _get_server_status(self, start_time, end_time, port, cores):
end_time = time.time()
@@ -76,25 +76,35 @@ class WorkerServer(services_pb2.BetaWorkerServiceServicer):
return control_pb2.ServerStatus(stats=stats, port=port, cores=cores)
def _create_server(self, config):
- if config.server_type == control_pb2.SYNC_SERVER:
+ if config.async_server_threads == 0:
+ # This is the default concurrent.futures thread pool size, but
+ # None doesn't seem to work
+ server_threads = multiprocessing.cpu_count() * 5
+ else:
+ server_threads = config.async_server_threads
+ server = grpc.server(futures.ThreadPoolExecutor(
+ max_workers=server_threads))
+ if config.server_type == control_pb2.ASYNC_SERVER:
servicer = benchmark_server.BenchmarkServer()
- server = services_pb2.beta_create_BenchmarkService_server(servicer)
+ services_pb2.add_BenchmarkServiceServicer_to_server(servicer, server)
elif config.server_type == control_pb2.ASYNC_GENERIC_SERVER:
resp_size = config.payload_config.bytebuf_params.resp_size
servicer = benchmark_server.GenericBenchmarkServer(resp_size)
method_implementations = {
- ('grpc.testing.BenchmarkService', 'StreamingCall'):
- utilities.stream_stream_inline(servicer.StreamingCall),
- ('grpc.testing.BenchmarkService', 'UnaryCall'):
- utilities.unary_unary_inline(servicer.UnaryCall),
+ 'StreamingCall':
+ grpc.stream_stream_rpc_method_handler(servicer.StreamingCall),
+ 'UnaryCall':
+ grpc.unary_unary_rpc_method_handler(servicer.UnaryCall),
}
- server = implementations.server(method_implementations)
+ handler = grpc.method_handlers_generic_handler(
+ 'grpc.testing.BenchmarkService', method_implementations)
+ server.add_generic_rpc_handlers((handler,))
else:
raise Exception('Unsupported server type {}'.format(config.server_type))
if config.HasField('security_params'): # Use SSL
- server_creds = implementations.ssl_server_credentials([(
- resources.private_key(), resources.certificate_chain())])
+ server_creds = grpc.ssl_server_credentials(
+ ((resources.private_key(), resources.certificate_chain()),))
port = server.add_secure_port('[::]:{}'.format(config.port), server_creds)
else:
port = server.add_insecure_port('[::]:{}'.format(config.port))
diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index 45eb75b242..dcaef0db1f 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -12,6 +12,7 @@
"_channel_test.ChannelTest",
"_compression_test.CompressionTest",
"_connectivity_channel_test.ConnectivityStatesTest",
+ "_credentials_test.CredentialsTest",
"_empty_message_test.EmptyMessageTest",
"_exit_test.ExitTest",
"_face_interface_test.DynamicInvokerBlockingInvocationInlineServiceTest",
diff --git a/src/python/grpcio_tests/tests/unit/_adapter/.gitignore b/src/python/grpcio_tests/tests/unit/_adapter/.gitignore
deleted file mode 100644
index a6f96cd6db..0000000000
--- a/src/python/grpcio_tests/tests/unit/_adapter/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-*.a
-*.so
-*.dll
-*.pyc
-*.pyd
diff --git a/src/python/grpcio_tests/tests/unit/_adapter/__init__.py b/src/python/grpcio_tests/tests/unit/_adapter/__init__.py
deleted file mode 100644
index 7086519106..0000000000
--- a/src/python/grpcio_tests/tests/unit/_adapter/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/_adapter/_proto_scenarios.py b/src/python/grpcio_tests/tests/unit/_adapter/_proto_scenarios.py
deleted file mode 100644
index 7a90eacf77..0000000000
--- a/src/python/grpcio_tests/tests/unit/_adapter/_proto_scenarios.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Test scenarios using protocol buffers."""
-
-import abc
-import threading
-
-import six
-
-from tests.unit._junkdrawer import math_pb2
-
-
-class ProtoScenario(six.with_metaclass(abc.ABCMeta)):
- """An RPC test scenario using protocol buffers."""
-
- @abc.abstractmethod
- def method(self):
- """Access the test method name.
-
- Returns:
- The test method name.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def serialize_request(self, request):
- """Serialize a request protocol buffer.
-
- Args:
- request: A request protocol buffer.
-
- Returns:
- The bytestring serialization of the given request protocol buffer.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def deserialize_request(self, request_bytestring):
- """Deserialize a request protocol buffer.
-
- Args:
- request_bytestring: The bytestring serialization of a request protocol
- buffer.
-
- Returns:
- The request protocol buffer deserialized from the given byte string.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def serialize_response(self, response):
- """Serialize a response protocol buffer.
-
- Args:
- response: A response protocol buffer.
-
- Returns:
- The bytestring serialization of the given response protocol buffer.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def deserialize_response(self, response_bytestring):
- """Deserialize a response protocol buffer.
-
- Args:
- response_bytestring: The bytestring serialization of a response protocol
- buffer.
-
- Returns:
- The response protocol buffer deserialized from the given byte string.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def requests(self):
- """Access the sequence of requests for this scenario.
-
- Returns:
- A sequence of request protocol buffers.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def response_for_request(self, request):
- """Access the response for a particular request.
-
- Args:
- request: A request protocol buffer.
-
- Returns:
- The response protocol buffer appropriate for the given request.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def verify_requests(self, experimental_requests):
- """Verify the requests transmitted through the system under test.
-
- Args:
- experimental_requests: The request protocol buffers transmitted through
- the system under test.
-
- Returns:
- True if the requests satisfy this test scenario; False otherwise.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def verify_responses(self, experimental_responses):
- """Verify the responses transmitted through the system under test.
-
- Args:
- experimental_responses: The response protocol buffers transmitted through
- the system under test.
-
- Returns:
- True if the responses satisfy this test scenario; False otherwise.
- """
- raise NotImplementedError()
-
-
-class EmptyScenario(ProtoScenario):
- """A scenario that transmits no protocol buffers in either direction."""
-
- def method(self):
- return 'DivMany'
-
- def serialize_request(self, request):
- raise ValueError('This should not be necessary to call!')
-
- def deserialize_request(self, request_bytestring):
- raise ValueError('This should not be necessary to call!')
-
- def serialize_response(self, response):
- raise ValueError('This should not be necessary to call!')
-
- def deserialize_response(self, response_bytestring):
- raise ValueError('This should not be necessary to call!')
-
- def requests(self):
- return ()
-
- def response_for_request(self, request):
- raise ValueError('This should not be necessary to call!')
-
- def verify_requests(self, experimental_requests):
- return not experimental_requests
-
- def verify_responses(self, experimental_responses):
- return not experimental_responses
-
-
-class BidirectionallyUnaryScenario(ProtoScenario):
- """A scenario that transmits no protocol buffers in either direction."""
-
- _DIVIDEND = 59
- _DIVISOR = 7
- _QUOTIENT = 8
- _REMAINDER = 3
-
- _REQUEST = math_pb2.DivArgs(dividend=_DIVIDEND, divisor=_DIVISOR)
- _RESPONSE = math_pb2.DivReply(quotient=_QUOTIENT, remainder=_REMAINDER)
-
- def method(self):
- return 'Div'
-
- def serialize_request(self, request):
- return request.SerializeToString()
-
- def deserialize_request(self, request_bytestring):
- return math_pb2.DivArgs.FromString(request_bytestring)
-
- def serialize_response(self, response):
- return response.SerializeToString()
-
- def deserialize_response(self, response_bytestring):
- return math_pb2.DivReply.FromString(response_bytestring)
-
- def requests(self):
- return [self._REQUEST]
-
- def response_for_request(self, request):
- return self._RESPONSE
-
- def verify_requests(self, experimental_requests):
- return tuple(experimental_requests) == (self._REQUEST,)
-
- def verify_responses(self, experimental_responses):
- return tuple(experimental_responses) == (self._RESPONSE,)
-
-
-class BidirectionallyStreamingScenario(ProtoScenario):
- """A scenario that transmits no protocol buffers in either direction."""
-
- _STREAM_LENGTH = 200
- _REQUESTS = tuple(
- math_pb2.DivArgs(dividend=59 + index, divisor=7 + index)
- for index in range(_STREAM_LENGTH))
-
- def __init__(self):
- self._lock = threading.Lock()
- self._responses = []
-
- def method(self):
- return 'DivMany'
-
- def serialize_request(self, request):
- return request.SerializeToString()
-
- def deserialize_request(self, request_bytestring):
- return math_pb2.DivArgs.FromString(request_bytestring)
-
- def serialize_response(self, response):
- return response.SerializeToString()
-
- def deserialize_response(self, response_bytestring):
- return math_pb2.DivReply.FromString(response_bytestring)
-
- def requests(self):
- return self._REQUESTS
-
- def response_for_request(self, request):
- quotient, remainder = divmod(request.dividend, request.divisor)
- response = math_pb2.DivReply(quotient=quotient, remainder=remainder)
- with self._lock:
- self._responses.append(response)
- return response
-
- def verify_requests(self, experimental_requests):
- return tuple(experimental_requests) == self._REQUESTS
-
- def verify_responses(self, experimental_responses):
- with self._lock:
- return tuple(experimental_responses) == tuple(self._responses)
diff --git a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py
index ae8de523ec..3c00f686ce 100644
--- a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py
+++ b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py
@@ -104,7 +104,7 @@ class ChannelConnectivityTest(unittest.TestCase):
grpc.ChannelConnectivity.READY, fifth_connectivities)
def test_immediately_connectable_channel_connectivity(self):
- server = _server.Server((), futures.ThreadPoolExecutor(max_workers=0))
+ server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ())
port = server.add_insecure_port('[::]:0')
server.start()
first_callback = _Callback()
@@ -143,7 +143,7 @@ class ChannelConnectivityTest(unittest.TestCase):
grpc.ChannelConnectivity.SHUTDOWN, fourth_connectivities)
def test_reachable_then_unreachable_channel_connectivity(self):
- server = _server.Server((), futures.ThreadPoolExecutor(max_workers=0))
+ server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ())
port = server.add_insecure_port('[::]:0')
server.start()
callback = _Callback()
diff --git a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
index b84bc0197a..e8982ed2de 100644
--- a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
+++ b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
@@ -78,7 +78,7 @@ class ChannelReadyFutureTest(unittest.TestCase):
self.assertFalse(ready_future.running())
def test_immediately_connectable_channel_connectivity(self):
- server = _server.Server((), futures.ThreadPoolExecutor(max_workers=0))
+ server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ())
port = server.add_insecure_port('[::]:0')
server.start()
channel = grpc.insecure_channel('localhost:{}'.format(port))
diff --git a/src/python/grpcio_tests/tests/unit/_compression_test.py b/src/python/grpcio_tests/tests/unit/_compression_test.py
index 9e8b8578c1..83b9109466 100644
--- a/src/python/grpcio_tests/tests/unit/_compression_test.py
+++ b/src/python/grpcio_tests/tests/unit/_compression_test.py
@@ -88,7 +88,8 @@ class CompressionTest(unittest.TestCase):
def setUp(self):
self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
- self._server = grpc.server((_GenericHandler(),), self._server_pool)
+ self._server = grpc.server(
+ self._server_pool, handlers=(_GenericHandler(),))
self._port = self._server.add_insecure_port('[::]:0')
self._server.start()
diff --git a/src/python/grpcio_tests/tests/unit/_credentials_test.py b/src/python/grpcio_tests/tests/unit/_credentials_test.py
new file mode 100644
index 0000000000..87af85a0b9
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/_credentials_test.py
@@ -0,0 +1,72 @@
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests of credentials."""
+
+import unittest
+
+import grpc
+
+
+class CredentialsTest(unittest.TestCase):
+
+ def test_call_credentials_composition(self):
+ first = grpc.access_token_call_credentials('abc')
+ second = grpc.access_token_call_credentials('def')
+ third = grpc.access_token_call_credentials('ghi')
+
+ first_and_second = grpc.composite_call_credentials(first, second)
+ first_second_and_third = grpc.composite_call_credentials(
+ first, second, third)
+
+ self.assertIsInstance(first_and_second, grpc.CallCredentials)
+ self.assertIsInstance(first_second_and_third, grpc.CallCredentials)
+
+ def test_channel_credentials_composition(self):
+ first_call_credentials = grpc.access_token_call_credentials('abc')
+ second_call_credentials = grpc.access_token_call_credentials('def')
+ third_call_credentials = grpc.access_token_call_credentials('ghi')
+ channel_credentials = grpc.ssl_channel_credentials()
+
+ channel_and_first = grpc.composite_channel_credentials(
+ channel_credentials, first_call_credentials)
+ channel_first_and_second = grpc.composite_channel_credentials(
+ channel_credentials, first_call_credentials, second_call_credentials)
+ channel_first_second_and_third = grpc.composite_channel_credentials(
+ channel_credentials, first_call_credentials, second_call_credentials,
+ third_call_credentials)
+
+ self.assertIsInstance(channel_and_first, grpc.ChannelCredentials)
+ self.assertIsInstance(channel_first_and_second, grpc.ChannelCredentials)
+ self.assertIsInstance(
+ channel_first_second_and_third, grpc.ChannelCredentials)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py b/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py
index cac0c8b3b9..cf212c5653 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/_cancel_many_calls_test.py
@@ -81,11 +81,11 @@ class _Handler(object):
self._state.condition.wait()
with self._lock:
- self._call.start_batch(
+ self._call.start_server_batch(
cygrpc.Operations(
(cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),)),
_RECEIVE_CLOSE_ON_SERVER_TAG)
- self._call.start_batch(
+ self._call.start_server_batch(
cygrpc.Operations((cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
_RECEIVE_MESSAGE_TAG)
first_event = self._completion_queue.poll()
@@ -101,7 +101,7 @@ class _Handler(object):
_EMPTY_METADATA, cygrpc.StatusCode.ok, b'test details!',
_EMPTY_FLAGS),
)
- self._call.start_batch(
+ self._call.start_server_batch(
cygrpc.Operations(operations), _SERVER_COMPLETE_CALL_TAG)
self._completion_queue.poll()
self._completion_queue.poll()
@@ -193,7 +193,7 @@ class CancelManyCallsTest(unittest.TestCase):
cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
)
tag = 'client_complete_call_{0:04d}_tag'.format(index)
- client_call.start_batch(cygrpc.Operations(operations), tag)
+ client_call.start_client_batch(cygrpc.Operations(operations), tag)
client_due.add(tag)
client_calls.append(client_call)
diff --git a/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py b/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py
index 27fcee0d6f..152d8edde3 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/_read_some_but_not_all_responses_test.py
@@ -168,12 +168,12 @@ class ReadSomeButNotAllResponsesTest(unittest.TestCase):
client_complete_rpc_tag = 'client_complete_rpc_tag'
with client_condition:
client_receive_initial_metadata_start_batch_result = (
- client_call.start_batch(cygrpc.Operations([
+ client_call.start_client_batch(cygrpc.Operations([
cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
]), client_receive_initial_metadata_tag))
client_due.add(client_receive_initial_metadata_tag)
client_complete_rpc_start_batch_result = (
- client_call.start_batch(cygrpc.Operations([
+ client_call.start_client_batch(cygrpc.Operations([
cygrpc.operation_send_initial_metadata(
_EMPTY_METADATA, _EMPTY_FLAGS),
cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
@@ -185,30 +185,30 @@ class ReadSomeButNotAllResponsesTest(unittest.TestCase):
with server_call_condition:
server_send_initial_metadata_start_batch_result = (
- server_rpc_event.operation_call.start_batch(cygrpc.Operations([
+ server_rpc_event.operation_call.start_server_batch([
cygrpc.operation_send_initial_metadata(
_EMPTY_METADATA, _EMPTY_FLAGS),
- ]), server_send_initial_metadata_tag))
+ ], server_send_initial_metadata_tag))
server_send_first_message_start_batch_result = (
- server_rpc_event.operation_call.start_batch(cygrpc.Operations([
+ server_rpc_event.operation_call.start_server_batch([
cygrpc.operation_send_message(b'\x07', _EMPTY_FLAGS),
- ]), server_send_first_message_tag))
+ ], server_send_first_message_tag))
server_send_initial_metadata_event = server_call_driver.event_with_tag(
server_send_initial_metadata_tag)
server_send_first_message_event = server_call_driver.event_with_tag(
server_send_first_message_tag)
with server_call_condition:
server_send_second_message_start_batch_result = (
- server_rpc_event.operation_call.start_batch(cygrpc.Operations([
+ server_rpc_event.operation_call.start_server_batch([
cygrpc.operation_send_message(b'\x07', _EMPTY_FLAGS),
- ]), server_send_second_message_tag))
+ ], server_send_second_message_tag))
server_complete_rpc_start_batch_result = (
- server_rpc_event.operation_call.start_batch(cygrpc.Operations([
+ server_rpc_event.operation_call.start_server_batch([
cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
cygrpc.operation_send_status_from_server(
cygrpc.Metadata(()), cygrpc.StatusCode.ok, b'test details',
_EMPTY_FLAGS),
- ]), server_complete_rpc_tag))
+ ], server_complete_rpc_tag))
server_send_second_message_event = server_call_driver.event_with_tag(
server_send_second_message_tag)
server_complete_rpc_event = server_call_driver.event_with_tag(
@@ -218,7 +218,7 @@ class ReadSomeButNotAllResponsesTest(unittest.TestCase):
with client_condition:
client_receive_first_message_tag = 'client_receive_first_message_tag'
client_receive_first_message_start_batch_result = (
- client_call.start_batch(cygrpc.Operations([
+ client_call.start_client_batch(cygrpc.Operations([
cygrpc.operation_receive_message(_EMPTY_FLAGS),
]), client_receive_first_message_tag))
client_due.add(client_receive_first_message_tag)
diff --git a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
index b740695e35..f9a8e2401b 100644
--- a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
+++ b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py
@@ -186,7 +186,8 @@ class ServerClientMixin(object):
def performer():
tag = object()
try:
- call_result = call.start_batch(cygrpc.Operations(operations), tag)
+ call_result = call.start_client_batch(
+ cygrpc.Operations(operations), tag)
self.assertEqual(cygrpc.CallError.ok, call_result)
event = queue.poll(deadline)
self.assertEqual(cygrpc.CompletionType.operation_complete, event.type)
@@ -231,7 +232,7 @@ class ServerClientMixin(object):
cygrpc.Metadatum(CLIENT_METADATA_ASCII_KEY,
CLIENT_METADATA_ASCII_VALUE),
cygrpc.Metadatum(CLIENT_METADATA_BIN_KEY, CLIENT_METADATA_BIN_VALUE)])
- client_start_batch_result = client_call.start_batch(cygrpc.Operations([
+ client_start_batch_result = client_call.start_client_batch([
cygrpc.operation_send_initial_metadata(client_initial_metadata,
_EMPTY_FLAGS),
cygrpc.operation_send_message(REQUEST, _EMPTY_FLAGS),
@@ -239,7 +240,7 @@ class ServerClientMixin(object):
cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
cygrpc.operation_receive_message(_EMPTY_FLAGS),
cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS)
- ]), client_call_tag)
+ ], client_call_tag)
self.assertEqual(cygrpc.CallError.ok, client_start_batch_result)
client_event_future = test_utilities.CompletionQueuePollFuture(
self.client_completion_queue, cygrpc_deadline)
@@ -268,7 +269,7 @@ class ServerClientMixin(object):
server_trailing_metadata = cygrpc.Metadata([
cygrpc.Metadatum(SERVER_TRAILING_METADATA_KEY,
SERVER_TRAILING_METADATA_VALUE)])
- server_start_batch_result = server_call.start_batch([
+ server_start_batch_result = server_call.start_server_batch([
cygrpc.operation_send_initial_metadata(server_initial_metadata,
_EMPTY_FLAGS),
cygrpc.operation_receive_message(_EMPTY_FLAGS),
@@ -280,8 +281,8 @@ class ServerClientMixin(object):
], server_call_tag)
self.assertEqual(cygrpc.CallError.ok, server_start_batch_result)
- client_event = client_event_future.result()
server_event = self.server_completion_queue.poll(cygrpc_deadline)
+ client_event = client_event_future.result()
self.assertEqual(6, len(client_event.batch_operations))
found_client_op_types = set()
diff --git a/src/python/grpcio_tests/tests/unit/_empty_message_test.py b/src/python/grpcio_tests/tests/unit/_empty_message_test.py
index 8c7d697728..131f6e9452 100644
--- a/src/python/grpcio_tests/tests/unit/_empty_message_test.py
+++ b/src/python/grpcio_tests/tests/unit/_empty_message_test.py
@@ -103,7 +103,8 @@ class EmptyMessageTest(unittest.TestCase):
def setUp(self):
self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
- self._server = grpc.server((_GenericHandler(),), self._server_pool)
+ self._server = grpc.server(
+ self._server_pool, handlers=(_GenericHandler(),))
port = self._server.add_insecure_port('[::]:0')
self._server.start()
self._channel = grpc.insecure_channel('localhost:%d' % port)
diff --git a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
index 24a2faef85..b33802bf57 100644
--- a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
+++ b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
@@ -184,11 +184,11 @@ if __name__ == '__main__':
args = parser.parse_args()
if args.scenario == UNSTARTED_SERVER:
- server = grpc.server((), DaemonPool())
+ server = grpc.server(DaemonPool())
if args.wait_for_interrupt:
time.sleep(WAIT_TIME)
elif args.scenario == RUNNING_SERVER:
- server = grpc.server((), DaemonPool())
+ server = grpc.server(DaemonPool())
port = server.add_insecure_port('[::]:0')
server.start()
if args.wait_for_interrupt:
@@ -203,7 +203,7 @@ if __name__ == '__main__':
if args.wait_for_interrupt:
time.sleep(WAIT_TIME)
elif args.scenario == POLL_CONNECTIVITY:
- server = grpc.server((), DaemonPool())
+ server = grpc.server(DaemonPool())
port = server.add_insecure_port('[::]:0')
server.start()
channel = grpc.insecure_channel('localhost:%d' % port)
@@ -217,7 +217,7 @@ if __name__ == '__main__':
else:
handler = GenericHandler()
- server = grpc.server((), DaemonPool())
+ server = grpc.server(DaemonPool())
port = server.add_insecure_port('[::]:0')
server.add_generic_rpc_handlers((handler,))
server.start()
diff --git a/src/python/grpcio_tests/tests/unit/_junkdrawer/math_pb2.py b/src/python/grpcio_tests/tests/unit/_junkdrawer/math_pb2.py
deleted file mode 100644
index 20165955b4..0000000000
--- a/src/python/grpcio_tests/tests/unit/_junkdrawer/math_pb2.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# TODO(nathaniel): Remove this from source control after having made
-# generation from the math.proto source part of GRPC's build-and-test
-# process.
-
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: math.proto
-
-import sys
-_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
-from google.protobuf import descriptor as _descriptor
-from google.protobuf import message as _message
-from google.protobuf import reflection as _reflection
-from google.protobuf import symbol_database as _symbol_database
-from google.protobuf import descriptor_pb2
-# @@protoc_insertion_point(imports)
-
-_sym_db = _symbol_database.Default()
-
-
-
-
-DESCRIPTOR = _descriptor.FileDescriptor(
- name='math.proto',
- package='math',
- serialized_pb=_b('\n\nmath.proto\x12\x04math\",\n\x07\x44ivArgs\x12\x10\n\x08\x64ividend\x18\x01 \x02(\x03\x12\x0f\n\x07\x64ivisor\x18\x02 \x02(\x03\"/\n\x08\x44ivReply\x12\x10\n\x08quotient\x18\x01 \x02(\x03\x12\x11\n\tremainder\x18\x02 \x02(\x03\"\x18\n\x07\x46ibArgs\x12\r\n\x05limit\x18\x01 \x01(\x03\"\x12\n\x03Num\x12\x0b\n\x03num\x18\x01 \x02(\x03\"\x19\n\x08\x46ibReply\x12\r\n\x05\x63ount\x18\x01 \x02(\x03\x32\xa4\x01\n\x04Math\x12&\n\x03\x44iv\x12\r.math.DivArgs\x1a\x0e.math.DivReply\"\x00\x12.\n\x07\x44ivMany\x12\r.math.DivArgs\x1a\x0e.math.DivReply\"\x00(\x01\x30\x01\x12#\n\x03\x46ib\x12\r.math.FibArgs\x1a\t.math.Num\"\x00\x30\x01\x12\x1f\n\x03Sum\x12\t.math.Num\x1a\t.math.Num\"\x00(\x01')
-)
-_sym_db.RegisterFileDescriptor(DESCRIPTOR)
-
-
-
-
-_DIVARGS = _descriptor.Descriptor(
- name='DivArgs',
- full_name='math.DivArgs',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='dividend', full_name='math.DivArgs.dividend', index=0,
- number=1, type=3, cpp_type=2, label=2,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='divisor', full_name='math.DivArgs.divisor', index=1,
- number=2, type=3, cpp_type=2, label=2,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=20,
- serialized_end=64,
-)
-
-
-_DIVREPLY = _descriptor.Descriptor(
- name='DivReply',
- full_name='math.DivReply',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='quotient', full_name='math.DivReply.quotient', index=0,
- number=1, type=3, cpp_type=2, label=2,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- _descriptor.FieldDescriptor(
- name='remainder', full_name='math.DivReply.remainder', index=1,
- number=2, type=3, cpp_type=2, label=2,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=66,
- serialized_end=113,
-)
-
-
-_FIBARGS = _descriptor.Descriptor(
- name='FibArgs',
- full_name='math.FibArgs',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='limit', full_name='math.FibArgs.limit', index=0,
- number=1, type=3, cpp_type=2, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=115,
- serialized_end=139,
-)
-
-
-_NUM = _descriptor.Descriptor(
- name='Num',
- full_name='math.Num',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='num', full_name='math.Num.num', index=0,
- number=1, type=3, cpp_type=2, label=2,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=141,
- serialized_end=159,
-)
-
-
-_FIBREPLY = _descriptor.Descriptor(
- name='FibReply',
- full_name='math.FibReply',
- filename=None,
- file=DESCRIPTOR,
- containing_type=None,
- fields=[
- _descriptor.FieldDescriptor(
- name='count', full_name='math.FibReply.count', index=0,
- number=1, type=3, cpp_type=2, label=2,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None),
- ],
- extensions=[
- ],
- nested_types=[],
- enum_types=[
- ],
- options=None,
- is_extendable=False,
- extension_ranges=[],
- oneofs=[
- ],
- serialized_start=161,
- serialized_end=186,
-)
-
-DESCRIPTOR.message_types_by_name['DivArgs'] = _DIVARGS
-DESCRIPTOR.message_types_by_name['DivReply'] = _DIVREPLY
-DESCRIPTOR.message_types_by_name['FibArgs'] = _FIBARGS
-DESCRIPTOR.message_types_by_name['Num'] = _NUM
-DESCRIPTOR.message_types_by_name['FibReply'] = _FIBREPLY
-
-DivArgs = _reflection.GeneratedProtocolMessageType('DivArgs', (_message.Message,), dict(
- DESCRIPTOR = _DIVARGS,
- __module__ = 'math_pb2'
- # @@protoc_insertion_point(class_scope:math.DivArgs)
- ))
-_sym_db.RegisterMessage(DivArgs)
-
-DivReply = _reflection.GeneratedProtocolMessageType('DivReply', (_message.Message,), dict(
- DESCRIPTOR = _DIVREPLY,
- __module__ = 'math_pb2'
- # @@protoc_insertion_point(class_scope:math.DivReply)
- ))
-_sym_db.RegisterMessage(DivReply)
-
-FibArgs = _reflection.GeneratedProtocolMessageType('FibArgs', (_message.Message,), dict(
- DESCRIPTOR = _FIBARGS,
- __module__ = 'math_pb2'
- # @@protoc_insertion_point(class_scope:math.FibArgs)
- ))
-_sym_db.RegisterMessage(FibArgs)
-
-Num = _reflection.GeneratedProtocolMessageType('Num', (_message.Message,), dict(
- DESCRIPTOR = _NUM,
- __module__ = 'math_pb2'
- # @@protoc_insertion_point(class_scope:math.Num)
- ))
-_sym_db.RegisterMessage(Num)
-
-FibReply = _reflection.GeneratedProtocolMessageType('FibReply', (_message.Message,), dict(
- DESCRIPTOR = _FIBREPLY,
- __module__ = 'math_pb2'
- # @@protoc_insertion_point(class_scope:math.FibReply)
- ))
-_sym_db.RegisterMessage(FibReply)
-
-
-# @@protoc_insertion_point(module_scope)
diff --git a/src/python/grpcio_tests/tests/unit/_links/__init__.py b/src/python/grpcio_tests/tests/unit/_links/__init__.py
deleted file mode 100644
index 7086519106..0000000000
--- a/src/python/grpcio_tests/tests/unit/_links/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/_links/_proto_scenarios.py b/src/python/grpcio_tests/tests/unit/_links/_proto_scenarios.py
deleted file mode 100644
index 50661085f9..0000000000
--- a/src/python/grpcio_tests/tests/unit/_links/_proto_scenarios.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Test scenarios using protocol buffers."""
-
-import abc
-import threading
-
-import six
-
-from tests.unit._junkdrawer import math_pb2
-from tests.unit.framework.common import test_constants
-
-
-class ProtoScenario(six.with_metaclass(abc.ABCMeta)):
- """An RPC test scenario using protocol buffers."""
-
- @abc.abstractmethod
- def group_and_method(self):
- """Access the test group and method.
-
- Returns:
- The test group and method as a pair.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def serialize_request(self, request):
- """Serialize a request protocol buffer.
-
- Args:
- request: A request protocol buffer.
-
- Returns:
- The bytestring serialization of the given request protocol buffer.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def deserialize_request(self, request_bytestring):
- """Deserialize a request protocol buffer.
-
- Args:
- request_bytestring: The bytestring serialization of a request protocol
- buffer.
-
- Returns:
- The request protocol buffer deserialized from the given byte string.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def serialize_response(self, response):
- """Serialize a response protocol buffer.
-
- Args:
- response: A response protocol buffer.
-
- Returns:
- The bytestring serialization of the given response protocol buffer.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def deserialize_response(self, response_bytestring):
- """Deserialize a response protocol buffer.
-
- Args:
- response_bytestring: The bytestring serialization of a response protocol
- buffer.
-
- Returns:
- The response protocol buffer deserialized from the given byte string.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def requests(self):
- """Access the sequence of requests for this scenario.
-
- Returns:
- A sequence of request protocol buffers.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def response_for_request(self, request):
- """Access the response for a particular request.
-
- Args:
- request: A request protocol buffer.
-
- Returns:
- The response protocol buffer appropriate for the given request.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def verify_requests(self, experimental_requests):
- """Verify the requests transmitted through the system under test.
-
- Args:
- experimental_requests: The request protocol buffers transmitted through
- the system under test.
-
- Returns:
- True if the requests satisfy this test scenario; False otherwise.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def verify_responses(self, experimental_responses):
- """Verify the responses transmitted through the system under test.
-
- Args:
- experimental_responses: The response protocol buffers transmitted through
- the system under test.
-
- Returns:
- True if the responses satisfy this test scenario; False otherwise.
- """
- raise NotImplementedError()
-
-
-class EmptyScenario(ProtoScenario):
- """A scenario that transmits no protocol buffers in either direction."""
-
- def group_and_method(self):
- return 'math.Math', 'DivMany'
-
- def serialize_request(self, request):
- raise ValueError('This should not be necessary to call!')
-
- def deserialize_request(self, request_bytestring):
- raise ValueError('This should not be necessary to call!')
-
- def serialize_response(self, response):
- raise ValueError('This should not be necessary to call!')
-
- def deserialize_response(self, response_bytestring):
- raise ValueError('This should not be necessary to call!')
-
- def requests(self):
- return ()
-
- def response_for_request(self, request):
- raise ValueError('This should not be necessary to call!')
-
- def verify_requests(self, experimental_requests):
- return not experimental_requests
-
- def verify_responses(self, experimental_responses):
- return not experimental_responses
-
-
-class BidirectionallyUnaryScenario(ProtoScenario):
- """A scenario that transmits no protocol buffers in either direction."""
-
- _DIVIDEND = 59
- _DIVISOR = 7
- _QUOTIENT = 8
- _REMAINDER = 3
-
- _REQUEST = math_pb2.DivArgs(dividend=_DIVIDEND, divisor=_DIVISOR)
- _RESPONSE = math_pb2.DivReply(quotient=_QUOTIENT, remainder=_REMAINDER)
-
- def group_and_method(self):
- return 'math.Math', 'Div'
-
- def serialize_request(self, request):
- return request.SerializeToString()
-
- def deserialize_request(self, request_bytestring):
- return math_pb2.DivArgs.FromString(request_bytestring)
-
- def serialize_response(self, response):
- return response.SerializeToString()
-
- def deserialize_response(self, response_bytestring):
- return math_pb2.DivReply.FromString(response_bytestring)
-
- def requests(self):
- return [self._REQUEST]
-
- def response_for_request(self, request):
- return self._RESPONSE
-
- def verify_requests(self, experimental_requests):
- return tuple(experimental_requests) == (self._REQUEST,)
-
- def verify_responses(self, experimental_responses):
- return tuple(experimental_responses) == (self._RESPONSE,)
-
-
-class BidirectionallyStreamingScenario(ProtoScenario):
- """A scenario that transmits no protocol buffers in either direction."""
-
- _REQUESTS = tuple(
- math_pb2.DivArgs(dividend=59 + index, divisor=7 + index)
- for index in range(test_constants.STREAM_LENGTH))
-
- def __init__(self):
- self._lock = threading.Lock()
- self._responses = []
-
- def group_and_method(self):
- return 'math.Math', 'DivMany'
-
- def serialize_request(self, request):
- return request.SerializeToString()
-
- def deserialize_request(self, request_bytestring):
- return math_pb2.DivArgs.FromString(request_bytestring)
-
- def serialize_response(self, response):
- return response.SerializeToString()
-
- def deserialize_response(self, response_bytestring):
- return math_pb2.DivReply.FromString(response_bytestring)
-
- def requests(self):
- return self._REQUESTS
-
- def response_for_request(self, request):
- quotient, remainder = divmod(request.dividend, request.divisor)
- response = math_pb2.DivReply(quotient=quotient, remainder=remainder)
- with self._lock:
- self._responses.append(response)
- return response
-
- def verify_requests(self, experimental_requests):
- return tuple(experimental_requests) == self._REQUESTS
-
- def verify_responses(self, experimental_responses):
- with self._lock:
- return tuple(experimental_responses) == tuple(self._responses)
diff --git a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py
index 0fd02d2a22..fb3e547781 100644
--- a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py
+++ b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py
@@ -189,7 +189,7 @@ class MetadataCodeDetailsTest(unittest.TestCase):
self._servicer = _Servicer()
self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
self._server = grpc.server(
- (_generic_handler(self._servicer),), self._server_pool)
+ self._server_pool, handlers=(_generic_handler(self._servicer),))
port = self._server.add_insecure_port('[::]:0')
self._server.start()
diff --git a/src/python/grpcio_tests/tests/unit/_metadata_test.py b/src/python/grpcio_tests/tests/unit/_metadata_test.py
index c637a28039..da73476929 100644
--- a/src/python/grpcio_tests/tests/unit/_metadata_test.py
+++ b/src/python/grpcio_tests/tests/unit/_metadata_test.py
@@ -161,8 +161,8 @@ class MetadataTest(unittest.TestCase):
def setUp(self):
self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
- self._server = grpc.server((_GenericHandler(weakref.proxy(self)),),
- self._server_pool)
+ self._server = grpc.server(
+ self._server_pool, handlers=(_GenericHandler(weakref.proxy(self)),))
port = self._server.add_insecure_port('[::]:0')
self._server.start()
self._channel = grpc.insecure_channel('localhost:%d' % port,
diff --git a/src/python/grpcio_tests/tests/unit/_rpc_test.py b/src/python/grpcio_tests/tests/unit/_rpc_test.py
index c70d65a6df..59bf240d28 100644
--- a/src/python/grpcio_tests/tests/unit/_rpc_test.py
+++ b/src/python/grpcio_tests/tests/unit/_rpc_test.py
@@ -184,7 +184,7 @@ class RPCTest(unittest.TestCase):
self._handler = _Handler(self._control)
self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
- self._server = grpc.server((), self._server_pool)
+ self._server = grpc.server(self._server_pool)
port = self._server.add_insecure_port('[::]:0')
self._server.add_generic_rpc_handlers((_GenericHandler(self._handler),))
self._server.start()
diff --git a/src/python/grpcio_tests/tests/unit/framework/core/__init__.py b/src/python/grpcio_tests/tests/unit/framework/core/__init__.py
deleted file mode 100644
index 7086519106..0000000000
--- a/src/python/grpcio_tests/tests/unit/framework/core/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/base/__init__.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/base/__init__.py
deleted file mode 100644
index 7086519106..0000000000
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/base/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/base/_control.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/base/_control.py
deleted file mode 100644
index 0eb38abf22..0000000000
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/base/_control.py
+++ /dev/null
@@ -1,570 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Part of the tests of the base interface of RPC Framework."""
-
-from __future__ import division
-
-import abc
-import collections
-import enum
-import random # pylint: disable=unused-import
-import threading
-import time
-
-import six
-
-from grpc.framework.interfaces.base import base
-from tests.unit.framework.common import test_constants
-from tests.unit.framework.interfaces.base import _sequence
-from tests.unit.framework.interfaces.base import _state
-from tests.unit.framework.interfaces.base import test_interfaces # pylint: disable=unused-import
-
-_GROUP = 'base test cases test group'
-_METHOD = 'base test cases test method'
-
-_PAYLOAD_RANDOM_SECTION_MAXIMUM_SIZE = test_constants.PAYLOAD_SIZE // 20
-_MINIMUM_PAYLOAD_SIZE = test_constants.PAYLOAD_SIZE // 600
-
-
-def _create_payload(randomness):
- length = randomness.randint(
- _MINIMUM_PAYLOAD_SIZE, test_constants.PAYLOAD_SIZE)
- random_section_length = randomness.randint(
- 0, min(_PAYLOAD_RANDOM_SECTION_MAXIMUM_SIZE, length))
- random_section = bytes(
- bytearray(
- randomness.getrandbits(8) for _ in range(random_section_length)))
- sevens_section = b'\x07' * (length - random_section_length)
- return b''.join(randomness.sample((random_section, sevens_section), 2))
-
-
-def _anything_in_flight(state):
- return (
- state.invocation_initial_metadata_in_flight is not None or
- state.invocation_payloads_in_flight or
- state.invocation_completion_in_flight is not None or
- state.service_initial_metadata_in_flight is not None or
- state.service_payloads_in_flight or
- state.service_completion_in_flight is not None or
- 0 < state.invocation_allowance_in_flight or
- 0 < state.service_allowance_in_flight
- )
-
-
-def _verify_service_advance_and_update_state(
- initial_metadata, payload, completion, allowance, state, implementation):
- if initial_metadata is not None:
- if state.invocation_initial_metadata_received:
- return 'Later invocation initial metadata received: %s' % (
- initial_metadata,)
- if state.invocation_payloads_received:
- return 'Invocation initial metadata received after payloads: %s' % (
- state.invocation_payloads_received)
- if state.invocation_completion_received:
- return 'Invocation initial metadata received after invocation completion!'
- if not implementation.metadata_transmitted(
- state.invocation_initial_metadata_in_flight, initial_metadata):
- return 'Invocation initial metadata maltransmitted: %s, %s' % (
- state.invocation_initial_metadata_in_flight, initial_metadata)
- else:
- state.invocation_initial_metadata_in_flight = None
- state.invocation_initial_metadata_received = True
-
- if payload is not None:
- if state.invocation_completion_received:
- return 'Invocation payload received after invocation completion!'
- elif not state.invocation_payloads_in_flight:
- return 'Invocation payload "%s" received but not in flight!' % (payload,)
- elif state.invocation_payloads_in_flight[0] != payload:
- return 'Invocation payload mismatch: %s, %s' % (
- state.invocation_payloads_in_flight[0], payload)
- elif state.service_side_invocation_allowance < 1:
- return 'Disallowed invocation payload!'
- else:
- state.invocation_payloads_in_flight.pop(0)
- state.invocation_payloads_received += 1
- state.service_side_invocation_allowance -= 1
-
- if completion is not None:
- if state.invocation_completion_received:
- return 'Later invocation completion received: %s' % (completion,)
- elif not implementation.completion_transmitted(
- state.invocation_completion_in_flight, completion):
- return 'Invocation completion maltransmitted: %s, %s' % (
- state.invocation_completion_in_flight, completion)
- else:
- state.invocation_completion_in_flight = None
- state.invocation_completion_received = True
-
- if allowance is not None:
- if allowance <= 0:
- return 'Illegal allowance value: %s' % (allowance,)
- else:
- state.service_allowance_in_flight -= allowance
- state.service_side_service_allowance += allowance
-
-
-def _verify_invocation_advance_and_update_state(
- initial_metadata, payload, completion, allowance, state, implementation):
- if initial_metadata is not None:
- if state.service_initial_metadata_received:
- return 'Later service initial metadata received: %s' % (initial_metadata,)
- if state.service_payloads_received:
- return 'Service initial metadata received after service payloads: %s' % (
- state.service_payloads_received)
- if state.service_completion_received:
- return 'Service initial metadata received after service completion!'
- if not implementation.metadata_transmitted(
- state.service_initial_metadata_in_flight, initial_metadata):
- return 'Service initial metadata maltransmitted: %s, %s' % (
- state.service_initial_metadata_in_flight, initial_metadata)
- else:
- state.service_initial_metadata_in_flight = None
- state.service_initial_metadata_received = True
-
- if payload is not None:
- if state.service_completion_received:
- return 'Service payload received after service completion!'
- elif not state.service_payloads_in_flight:
- return 'Service payload "%s" received but not in flight!' % (payload,)
- elif state.service_payloads_in_flight[0] != payload:
- return 'Service payload mismatch: %s, %s' % (
- state.invocation_payloads_in_flight[0], payload)
- elif state.invocation_side_service_allowance < 1:
- return 'Disallowed service payload!'
- else:
- state.service_payloads_in_flight.pop(0)
- state.service_payloads_received += 1
- state.invocation_side_service_allowance -= 1
-
- if completion is not None:
- if state.service_completion_received:
- return 'Later service completion received: %s' % (completion,)
- elif not implementation.completion_transmitted(
- state.service_completion_in_flight, completion):
- return 'Service completion maltransmitted: %s, %s' % (
- state.service_completion_in_flight, completion)
- else:
- state.service_completion_in_flight = None
- state.service_completion_received = True
-
- if allowance is not None:
- if allowance <= 0:
- return 'Illegal allowance value: %s' % (allowance,)
- else:
- state.invocation_allowance_in_flight -= allowance
- state.invocation_side_service_allowance += allowance
-
-
-class Invocation(
- collections.namedtuple(
- 'Invocation',
- ('group', 'method', 'subscription_kind', 'timeout', 'initial_metadata',
- 'payload', 'completion',))):
- """A description of operation invocation.
-
- Attributes:
- group: The group identifier for the operation.
- method: The method identifier for the operation.
- subscription_kind: A base.Subscription.Kind value describing the kind of
- subscription to use for the operation.
- timeout: A duration in seconds to pass as the timeout value for the
- operation.
- initial_metadata: An object to pass as the initial metadata for the
- operation or None.
- payload: An object to pass as a payload value for the operation or None.
- completion: An object to pass as a completion value for the operation or
- None.
- """
-
-
-class OnAdvance(
- collections.namedtuple(
- 'OnAdvance',
- ('kind', 'initial_metadata', 'payload', 'completion', 'allowance'))):
- """Describes action to be taken in a test in response to an advance call.
-
- Attributes:
- kind: A Kind value describing the overall kind of response.
- initial_metadata: An initial metadata value to pass to a call of the advance
- method of the operator under test. Only valid if kind is Kind.ADVANCE and
- may be None.
- payload: A payload value to pass to a call of the advance method of the
- operator under test. Only valid if kind is Kind.ADVANCE and may be None.
- completion: A base.Completion value to pass to a call of the advance method
- of the operator under test. Only valid if kind is Kind.ADVANCE and may be
- None.
- allowance: An allowance value to pass to a call of the advance method of the
- operator under test. Only valid if kind is Kind.ADVANCE and may be None.
- """
-
- @enum.unique
- class Kind(enum.Enum):
- ADVANCE = 'advance'
- DEFECT = 'defect'
- IDLE = 'idle'
-
-
-_DEFECT_ON_ADVANCE = OnAdvance(OnAdvance.Kind.DEFECT, None, None, None, None)
-_IDLE_ON_ADVANCE = OnAdvance(OnAdvance.Kind.IDLE, None, None, None, None)
-
-
-class Instruction(
- collections.namedtuple(
- 'Instruction',
- ('kind', 'advance_args', 'advance_kwargs', 'conclude_success',
- 'conclude_message', 'conclude_invocation_outcome_kind',
- 'conclude_service_outcome_kind',))):
- """"""
-
- @enum.unique
- class Kind(enum.Enum):
- ADVANCE = 'ADVANCE'
- CANCEL = 'CANCEL'
- CONCLUDE = 'CONCLUDE'
-
-
-class Controller(six.with_metaclass(abc.ABCMeta)):
-
- @abc.abstractmethod
- def failed(self, message):
- """"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def serialize_request(self, request):
- """"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def deserialize_request(self, serialized_request):
- """"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def serialize_response(self, response):
- """"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def deserialize_response(self, serialized_response):
- """"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def invocation(self):
- """"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def poll(self):
- """"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def on_service_advance(
- self, initial_metadata, payload, completion, allowance):
- """"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def on_invocation_advance(
- self, initial_metadata, payload, completion, allowance):
- """"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def service_on_termination(self, outcome):
- """"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def invocation_on_termination(self, outcome):
- """"""
- raise NotImplementedError()
-
-
-class ControllerCreator(six.with_metaclass(abc.ABCMeta)):
-
- @abc.abstractmethod
- def name(self):
- """"""
- raise NotImplementedError()
-
- @abc.abstractmethod
- def controller(self, implementation, randomness):
- """"""
- raise NotImplementedError()
-
-
-class _Remainder(
- collections.namedtuple(
- '_Remainder',
- ('invocation_payloads', 'service_payloads', 'invocation_completion',
- 'service_completion',))):
- """Describes work remaining to be done in a portion of a test.
-
- Attributes:
- invocation_payloads: The number of payloads to be sent from the invocation
- side of the operation to the service side of the operation.
- service_payloads: The number of payloads to be sent from the service side of
- the operation to the invocation side of the operation.
- invocation_completion: Whether or not completion from the invocation side of
- the operation should be indicated and has yet to be indicated.
- service_completion: Whether or not completion from the service side of the
- operation should be indicated and has yet to be indicated.
- """
-
-
-class _SequenceController(Controller):
-
- def __init__(self, sequence, implementation, randomness):
- """Constructor.
-
- Args:
- sequence: A _sequence.Sequence describing the steps to be taken in the
- test at a relatively high level.
- implementation: A test_interfaces.Implementation encapsulating the
- base interface implementation that is the system under test.
- randomness: A random.Random instance for use in the test.
- """
- self._condition = threading.Condition()
- self._sequence = sequence
- self._implementation = implementation
- self._randomness = randomness
-
- self._until = None
- self._remaining_elements = None
- self._poll_next = None
- self._message = None
-
- self._state = _state.OperationState()
- self._todo = None
-
- # called with self._condition
- def _failed(self, message):
- self._message = message
- self._condition.notify_all()
-
- def _passed(self, invocation_outcome, service_outcome):
- self._poll_next = Instruction(
- Instruction.Kind.CONCLUDE, None, None, True, None, invocation_outcome,
- service_outcome)
- self._condition.notify_all()
-
- def failed(self, message):
- with self._condition:
- self._failed(message)
-
- def serialize_request(self, request):
- return request + request
-
- def deserialize_request(self, serialized_request):
- return serialized_request[:len(serialized_request) // 2]
-
- def serialize_response(self, response):
- return response * 3
-
- def deserialize_response(self, serialized_response):
- return serialized_response[2 * len(serialized_response) // 3:]
-
- def invocation(self):
- with self._condition:
- self._until = time.time() + self._sequence.maximum_duration
- self._remaining_elements = list(self._sequence.elements)
- if self._sequence.invocation.initial_metadata:
- initial_metadata = self._implementation.invocation_initial_metadata()
- self._state.invocation_initial_metadata_in_flight = initial_metadata
- else:
- initial_metadata = None
- if self._sequence.invocation.payload:
- payload = _create_payload(self._randomness)
- self._state.invocation_payloads_in_flight.append(payload)
- else:
- payload = None
- if self._sequence.invocation.complete:
- completion = self._implementation.invocation_completion()
- self._state.invocation_completion_in_flight = completion
- else:
- completion = None
- return Invocation(
- _GROUP, _METHOD, base.Subscription.Kind.FULL,
- self._sequence.invocation.timeout, initial_metadata, payload,
- completion)
-
- def poll(self):
- with self._condition:
- while True:
- if self._message is not None:
- return Instruction(
- Instruction.Kind.CONCLUDE, None, None, False, self._message, None,
- None)
- elif self._poll_next:
- poll_next = self._poll_next
- self._poll_next = None
- return poll_next
- elif self._until < time.time():
- return Instruction(
- Instruction.Kind.CONCLUDE, None, None, False,
- 'overran allotted time!', None, None)
- else:
- self._condition.wait(timeout=self._until-time.time())
-
- def on_service_advance(
- self, initial_metadata, payload, completion, allowance):
- with self._condition:
- message = _verify_service_advance_and_update_state(
- initial_metadata, payload, completion, allowance, self._state,
- self._implementation)
- if message is not None:
- self._failed(message)
- if self._todo is not None:
- raise ValueError('TODO!!!')
- elif _anything_in_flight(self._state):
- return _IDLE_ON_ADVANCE
- elif self._remaining_elements:
- element = self._remaining_elements.pop(0)
- if element.kind is _sequence.Element.Kind.SERVICE_TRANSMISSION:
- if element.transmission.initial_metadata:
- initial_metadata = self._implementation.service_initial_metadata()
- self._state.service_initial_metadata_in_flight = initial_metadata
- else:
- initial_metadata = None
- if element.transmission.payload:
- payload = _create_payload(self._randomness)
- self._state.service_payloads_in_flight.append(payload)
- self._state.service_side_service_allowance -= 1
- else:
- payload = None
- if element.transmission.complete:
- completion = self._implementation.service_completion()
- self._state.service_completion_in_flight = completion
- else:
- completion = None
- if (not self._state.invocation_completion_received and
- 0 <= self._state.service_side_invocation_allowance):
- allowance = 1
- self._state.service_side_invocation_allowance += 1
- self._state.invocation_allowance_in_flight += 1
- else:
- allowance = None
- return OnAdvance(
- OnAdvance.Kind.ADVANCE, initial_metadata, payload, completion,
- allowance)
- else:
- raise ValueError('TODO!!!')
- else:
- return _IDLE_ON_ADVANCE
-
- def on_invocation_advance(
- self, initial_metadata, payload, completion, allowance):
- with self._condition:
- message = _verify_invocation_advance_and_update_state(
- initial_metadata, payload, completion, allowance, self._state,
- self._implementation)
- if message is not None:
- self._failed(message)
- if self._todo is not None:
- raise ValueError('TODO!!!')
- elif _anything_in_flight(self._state):
- return _IDLE_ON_ADVANCE
- elif self._remaining_elements:
- element = self._remaining_elements.pop(0)
- if element.kind is _sequence.Element.Kind.INVOCATION_TRANSMISSION:
- if element.transmission.initial_metadata:
- initial_metadata = self._implementation.invocation_initial_metadata()
- self._state.invocation_initial_metadata_in_fight = initial_metadata
- else:
- initial_metadata = None
- if element.transmission.payload:
- payload = _create_payload(self._randomness)
- self._state.invocation_payloads_in_flight.append(payload)
- self._state.invocation_side_invocation_allowance -= 1
- else:
- payload = None
- if element.transmission.complete:
- completion = self._implementation.invocation_completion()
- self._state.invocation_completion_in_flight = completion
- else:
- completion = None
- if (not self._state.service_completion_received and
- 0 <= self._state.invocation_side_service_allowance):
- allowance = 1
- self._state.invocation_side_service_allowance += 1
- self._state.service_allowance_in_flight += 1
- else:
- allowance = None
- return OnAdvance(
- OnAdvance.Kind.ADVANCE, initial_metadata, payload, completion,
- allowance)
- else:
- raise ValueError('TODO!!!')
- else:
- return _IDLE_ON_ADVANCE
-
- def service_on_termination(self, outcome):
- with self._condition:
- self._state.service_side_outcome = outcome
- if self._todo is not None or self._remaining_elements:
- self._failed('Premature service-side outcome %s!' % (outcome,))
- elif outcome.kind is not self._sequence.outcome_kinds.service:
- self._failed(
- 'Incorrect service-side outcome kind: %s should have been %s' % (
- outcome.kind, self._sequence.outcome_kinds.service))
- elif self._state.invocation_side_outcome is not None:
- self._passed(self._state.invocation_side_outcome.kind, outcome.kind)
-
- def invocation_on_termination(self, outcome):
- with self._condition:
- self._state.invocation_side_outcome = outcome
- if self._todo is not None or self._remaining_elements:
- self._failed('Premature invocation-side outcome %s!' % (outcome,))
- elif outcome.kind is not self._sequence.outcome_kinds.invocation:
- self._failed(
- 'Incorrect invocation-side outcome kind: %s should have been %s' % (
- outcome.kind, self._sequence.outcome_kinds.invocation))
- elif self._state.service_side_outcome is not None:
- self._passed(outcome.kind, self._state.service_side_outcome.kind)
-
-
-class _SequenceControllerCreator(ControllerCreator):
-
- def __init__(self, sequence):
- self._sequence = sequence
-
- def name(self):
- return self._sequence.name
-
- def controller(self, implementation, randomness):
- return _SequenceController(self._sequence, implementation, randomness)
-
-
-CONTROLLER_CREATORS = tuple(
- _SequenceControllerCreator(sequence) for sequence in _sequence.SEQUENCES)
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/base/_sequence.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/base/_sequence.py
deleted file mode 100644
index 571d0e1e63..0000000000
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/base/_sequence.py
+++ /dev/null
@@ -1,171 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Part of the tests of the base interface of RPC Framework."""
-
-import collections
-import enum
-
-from grpc.framework.interfaces.base import base
-from tests.unit.framework.common import test_constants
-
-
-class Invocation(
- collections.namedtuple(
- 'Invocation', ('timeout', 'initial_metadata', 'payload', 'complete',))):
- """A recipe for operation invocation.
-
- Attributes:
- timeout: A duration in seconds to pass to the system under test as the
- operation's timeout value.
- initial_metadata: A boolean indicating whether or not to pass initial
- metadata when invoking the operation.
- payload: A boolean indicating whether or not to pass a payload when
- invoking the operation.
- complete: A boolean indicating whether or not to indicate completion of
- transmissions from the invoking side of the operation when invoking the
- operation.
- """
-
-
-class Transmission(
- collections.namedtuple(
- 'Transmission', ('initial_metadata', 'payload', 'complete',))):
- """A recipe for a single transmission in an operation.
-
- Attributes:
- initial_metadata: A boolean indicating whether or not to pass initial
- metadata as part of the transmission.
- payload: A boolean indicating whether or not to pass a payload as part of
- the transmission.
- complete: A boolean indicating whether or not to indicate completion of
- transmission from the transmitting side of the operation as part of the
- transmission.
- """
-
-
-class Intertransmission(
- collections.namedtuple('Intertransmission', ('invocation', 'service',))):
- """A recipe for multiple transmissions in an operation.
-
- Attributes:
- invocation: An integer describing the number of payloads to send from the
- invocation side of the operation to the service side.
- service: An integer describing the number of payloads to send from the
- service side of the operation to the invocation side.
- """
-
-
-class Element(collections.namedtuple('Element', ('kind', 'transmission',))):
- """A sum type for steps to perform when testing an operation.
-
- Attributes:
- kind: A Kind value describing the kind of step to perform in the test.
- transmission: Only valid for kinds Kind.INVOCATION_TRANSMISSION and
- Kind.SERVICE_TRANSMISSION, a Transmission value describing the details of
- the transmission to be made.
- """
-
- @enum.unique
- class Kind(enum.Enum):
- INVOCATION_TRANSMISSION = 'invocation transmission'
- SERVICE_TRANSMISSION = 'service transmission'
- INTERTRANSMISSION = 'intertransmission'
- INVOCATION_CANCEL = 'invocation cancel'
- SERVICE_CANCEL = 'service cancel'
- INVOCATION_FAILURE = 'invocation failure'
- SERVICE_FAILURE = 'service failure'
-
-
-class OutcomeKinds(
- collections.namedtuple('Outcome', ('invocation', 'service',))):
- """A description of the expected outcome of an operation test.
-
- Attributes:
- invocation: The base.Outcome.Kind value expected on the invocation side of
- the operation.
- service: The base.Outcome.Kind value expected on the service side of the
- operation.
- """
-
-
-class Sequence(
- collections.namedtuple(
- 'Sequence',
- ('name', 'maximum_duration', 'invocation', 'elements',
- 'outcome_kinds',))):
- """Describes at a high level steps to perform in a test.
-
- Attributes:
- name: The string name of the sequence.
- maximum_duration: A length of time in seconds to allow for the test before
- declaring it to have failed.
- invocation: An Invocation value describing how to invoke the operation
- under test.
- elements: A sequence of Element values describing at coarse granularity
- actions to take during the operation under test.
- outcome_kinds: An OutcomeKinds value describing the expected outcome kinds
- of the test.
- """
-
-_EASY = Sequence(
- 'Easy',
- test_constants.TIME_ALLOWANCE,
- Invocation(test_constants.LONG_TIMEOUT, True, True, True),
- (
- Element(
- Element.Kind.SERVICE_TRANSMISSION, Transmission(True, True, True)),
- ),
- OutcomeKinds(base.Outcome.Kind.COMPLETED, base.Outcome.Kind.COMPLETED))
-
-_PEASY = Sequence(
- 'Peasy',
- test_constants.TIME_ALLOWANCE,
- Invocation(test_constants.LONG_TIMEOUT, True, True, False),
- (
- Element(
- Element.Kind.SERVICE_TRANSMISSION, Transmission(True, True, False)),
- Element(
- Element.Kind.INVOCATION_TRANSMISSION,
- Transmission(False, True, True)),
- Element(
- Element.Kind.SERVICE_TRANSMISSION, Transmission(False, True, True)),
- ),
- OutcomeKinds(base.Outcome.Kind.COMPLETED, base.Outcome.Kind.COMPLETED))
-
-
-# TODO(issue 2959): Finish this test suite. This tuple of sequences should
-# contain at least the values in the Cartesian product of (half-duplex,
-# full-duplex) * (zero payloads, one payload, test_constants.STREAM_LENGTH
-# payloads) * (completion, cancellation, expiration, programming defect in
-# servicer code).
-SEQUENCES = (
- _EASY,
- _PEASY,
-)
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/base/_state.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/base/_state.py
deleted file mode 100644
index 21cf33aeb6..0000000000
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/base/_state.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Part of the tests of the base interface of RPC Framework."""
-
-
-class OperationState(object):
-
- def __init__(self):
- self.invocation_initial_metadata_in_flight = None
- self.invocation_initial_metadata_received = False
- self.invocation_payloads_in_flight = []
- self.invocation_payloads_received = 0
- self.invocation_completion_in_flight = None
- self.invocation_completion_received = False
- self.service_initial_metadata_in_flight = None
- self.service_initial_metadata_received = False
- self.service_payloads_in_flight = []
- self.service_payloads_received = 0
- self.service_completion_in_flight = None
- self.service_completion_received = False
- self.invocation_side_invocation_allowance = 1
- self.invocation_side_service_allowance = 1
- self.service_side_invocation_allowance = 1
- self.service_side_service_allowance = 1
- self.invocation_allowance_in_flight = 0
- self.service_allowance_in_flight = 0
- self.invocation_side_outcome = None
- self.service_side_outcome = None
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/base/test_cases.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/base/test_cases.py
deleted file mode 100644
index 5d16bf98be..0000000000
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/base/test_cases.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Tests of the base interface of RPC Framework."""
-
-from __future__ import division
-
-import logging
-import random
-import threading
-import time
-import unittest
-
-from grpc.framework.foundation import logging_pool
-from grpc.framework.interfaces.base import base
-from grpc.framework.interfaces.base import utilities
-from tests.unit.framework.common import test_constants
-from tests.unit.framework.interfaces.base import _control
-from tests.unit.framework.interfaces.base import test_interfaces
-
-_SYNCHRONICITY_VARIATION = (('Sync', False), ('Async', True))
-
-_EMPTY_OUTCOME_KIND_DICT = {
- outcome_kind: 0 for outcome_kind in base.Outcome.Kind}
-
-
-class _Serialization(test_interfaces.Serialization):
-
- def serialize_request(self, request):
- return request + request
-
- def deserialize_request(self, serialized_request):
- return serialized_request[:len(serialized_request) // 2]
-
- def serialize_response(self, response):
- return response * 3
-
- def deserialize_response(self, serialized_response):
- return serialized_response[2 * len(serialized_response) // 3:]
-
-
-def _advance(quadruples, operator, controller):
- try:
- for quadruple in quadruples:
- operator.advance(
- initial_metadata=quadruple[0], payload=quadruple[1],
- completion=quadruple[2], allowance=quadruple[3])
- except Exception as e: # pylint: disable=broad-except
- controller.failed('Exception on advance: %e' % e)
-
-
-class _Operator(base.Operator):
-
- def __init__(self, controller, on_advance, pool, operator_under_test):
- self._condition = threading.Condition()
- self._controller = controller
- self._on_advance = on_advance
- self._pool = pool
- self._operator_under_test = operator_under_test
- self._pending_advances = []
-
- def set_operator_under_test(self, operator_under_test):
- with self._condition:
- self._operator_under_test = operator_under_test
- pent_advances = self._pending_advances
- self._pending_advances = []
- pool = self._pool
- controller = self._controller
-
- if pool is None:
- _advance(pent_advances, operator_under_test, controller)
- else:
- pool.submit(_advance, pent_advances, operator_under_test, controller)
-
- def advance(
- self, initial_metadata=None, payload=None, completion=None,
- allowance=None):
- on_advance = self._on_advance(
- initial_metadata, payload, completion, allowance)
- if on_advance.kind is _control.OnAdvance.Kind.ADVANCE:
- with self._condition:
- pool = self._pool
- operator_under_test = self._operator_under_test
- controller = self._controller
-
- quadruple = (
- on_advance.initial_metadata, on_advance.payload,
- on_advance.completion, on_advance.allowance)
- if pool is None:
- _advance((quadruple,), operator_under_test, controller)
- else:
- pool.submit(_advance, (quadruple,), operator_under_test, controller)
- elif on_advance.kind is _control.OnAdvance.Kind.DEFECT:
- raise ValueError(
- 'Deliberately raised exception from Operator.advance (in a test)!')
-
-
-class _ProtocolReceiver(base.ProtocolReceiver):
-
- def __init__(self):
- self._condition = threading.Condition()
- self._contexts = []
-
- def context(self, protocol_context):
- with self._condition:
- self._contexts.append(protocol_context)
-
-
-class _Servicer(base.Servicer):
- """A base.Servicer with instrumented for testing."""
-
- def __init__(self, group, method, controllers, pool):
- self._condition = threading.Condition()
- self._group = group
- self._method = method
- self._pool = pool
- self._controllers = list(controllers)
-
- def service(self, group, method, context, output_operator):
- with self._condition:
- controller = self._controllers.pop(0)
- if group != self._group or method != self._method:
- controller.fail(
- '%s != %s or %s != %s' % (group, self._group, method, self._method))
- raise base.NoSuchMethodError(None, None)
- else:
- operator = _Operator(
- controller, controller.on_service_advance, self._pool,
- output_operator)
- outcome = context.add_termination_callback(
- controller.service_on_termination)
- if outcome is not None:
- controller.service_on_termination(outcome)
- return utilities.full_subscription(operator, _ProtocolReceiver())
-
-
-class _OperationTest(unittest.TestCase):
-
- def setUp(self):
- if self._synchronicity_variation:
- self._pool = logging_pool.pool(test_constants.POOL_SIZE)
- else:
- self._pool = None
- self._controller = self._controller_creator.controller(
- self._implementation, self._randomness)
-
- def tearDown(self):
- if self._synchronicity_variation:
- self._pool.shutdown(wait=True)
- else:
- self._pool = None
-
- def test_operation(self):
- invocation = self._controller.invocation()
- if invocation.subscription_kind is base.Subscription.Kind.FULL:
- test_operator = _Operator(
- self._controller, self._controller.on_invocation_advance,
- self._pool, None)
- subscription = utilities.full_subscription(
- test_operator, _ProtocolReceiver())
- else:
- # TODO(nathaniel): support and test other subscription kinds.
- self.fail('Non-full subscriptions not yet supported!')
-
- servicer = _Servicer(
- invocation.group, invocation.method, (self._controller,), self._pool)
-
- invocation_end, service_end, memo = self._implementation.instantiate(
- {(invocation.group, invocation.method): _Serialization()}, servicer)
-
- try:
- invocation_end.start()
- service_end.start()
- operation_context, operator_under_test = invocation_end.operate(
- invocation.group, invocation.method, subscription, invocation.timeout,
- initial_metadata=invocation.initial_metadata, payload=invocation.payload,
- completion=invocation.completion)
- test_operator.set_operator_under_test(operator_under_test)
- outcome = operation_context.add_termination_callback(
- self._controller.invocation_on_termination)
- if outcome is not None:
- self._controller.invocation_on_termination(outcome)
- except Exception as e: # pylint: disable=broad-except
- self._controller.failed('Exception on invocation: %s' % e)
- self.fail(e)
-
- while True:
- instruction = self._controller.poll()
- if instruction.kind is _control.Instruction.Kind.ADVANCE:
- try:
- test_operator.advance(
- *instruction.advance_args, **instruction.advance_kwargs)
- except Exception as e: # pylint: disable=broad-except
- self._controller.failed('Exception on instructed advance: %s' % e)
- elif instruction.kind is _control.Instruction.Kind.CANCEL:
- try:
- operation_context.cancel()
- except Exception as e: # pylint: disable=broad-except
- self._controller.failed('Exception on cancel: %s' % e)
- elif instruction.kind is _control.Instruction.Kind.CONCLUDE:
- break
-
- invocation_stop_event = invocation_end.stop(0)
- service_stop_event = service_end.stop(0)
- invocation_stop_event.wait()
- service_stop_event.wait()
- invocation_stats = invocation_end.operation_stats()
- service_stats = service_end.operation_stats()
-
- self._implementation.destantiate(memo)
-
- self.assertTrue(
- instruction.conclude_success, msg=instruction.conclude_message)
-
- expected_invocation_stats = dict(_EMPTY_OUTCOME_KIND_DICT)
- expected_invocation_stats[
- instruction.conclude_invocation_outcome_kind] += 1
- self.assertDictEqual(expected_invocation_stats, invocation_stats)
- expected_service_stats = dict(_EMPTY_OUTCOME_KIND_DICT)
- expected_service_stats[instruction.conclude_service_outcome_kind] += 1
- self.assertDictEqual(expected_service_stats, service_stats)
-
-
-def test_cases(implementation):
- """Creates unittest.TestCase classes for a given Base implementation.
-
- Args:
- implementation: A test_interfaces.Implementation specifying creation and
- destruction of the Base implementation under test.
-
- Returns:
- A sequence of subclasses of unittest.TestCase defining tests of the
- specified Base layer implementation.
- """
- random_seed = hash(time.time())
- logging.warning('Random seed for this execution: %s', random_seed)
- randomness = random.Random(x=random_seed)
-
- test_case_classes = []
- for synchronicity_variation in _SYNCHRONICITY_VARIATION:
- for controller_creator in _control.CONTROLLER_CREATORS:
- name = ''.join(
- (synchronicity_variation[0], controller_creator.name(), 'Test',))
- test_case_classes.append(
- type(name, (_OperationTest,),
- {'_implementation': implementation,
- '_randomness': randomness,
- '_synchronicity_variation': synchronicity_variation[1],
- '_controller_creator': controller_creator,
- '__module__': implementation.__module__,
- }))
-
- return test_case_classes
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/base/test_interfaces.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/base/test_interfaces.py
deleted file mode 100644
index 5eba475ba8..0000000000
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/base/test_interfaces.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Interfaces used in tests of implementations of the Base layer."""
-
-import abc
-
-import six
-
-from grpc.framework.interfaces.base import base # pylint: disable=unused-import
-
-
-class Serialization(six.with_metaclass(abc.ABCMeta)):
- """Specifies serialization and deserialization of test payloads."""
-
- def serialize_request(self, request):
- """Serializes a request value used in a test.
-
- Args:
- request: A request value created by a test.
-
- Returns:
- A bytestring that is the serialization of the given request.
- """
- raise NotImplementedError()
-
- def deserialize_request(self, serialized_request):
- """Deserializes a request value used in a test.
-
- Args:
- serialized_request: A bytestring that is the serialization of some request
- used in a test.
-
- Returns:
- The request value encoded by the given bytestring.
- """
- raise NotImplementedError()
-
- def serialize_response(self, response):
- """Serializes a response value used in a test.
-
- Args:
- response: A response value created by a test.
-
- Returns:
- A bytestring that is the serialization of the given response.
- """
- raise NotImplementedError()
-
- def deserialize_response(self, serialized_response):
- """Deserializes a response value used in a test.
-
- Args:
- serialized_response: A bytestring that is the serialization of some
- response used in a test.
-
- Returns:
- The response value encoded by the given bytestring.
- """
- raise NotImplementedError()
-
-
-class Implementation(six.with_metaclass(abc.ABCMeta)):
- """Specifies an implementation of the Base layer."""
-
- @abc.abstractmethod
- def instantiate(self, serializations, servicer):
- """Instantiates the Base layer implementation to be used in a test.
-
- Args:
- serializations: A dict from group-method pair to Serialization object
- specifying how to serialize and deserialize payload values used in the
- test.
- servicer: A base.Servicer object to be called to service RPCs made during
- the test.
-
- Returns:
- A sequence of length three the first element of which is a
- base.End to be used to invoke RPCs, the second element of which is a
- base.End to be used to service invoked RPCs, and the third element of
- which is an arbitrary memo object to be kept and passed to destantiate
- at the conclusion of the test.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def destantiate(self, memo):
- """Destroys the Base layer implementation under test.
-
- Args:
- memo: The object from the third position of the return value of a call to
- instantiate.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def invocation_initial_metadata(self):
- """Provides an operation's invocation-side initial metadata.
-
- Returns:
- A value to use for an operation's invocation-side initial metadata, or
- None.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def service_initial_metadata(self):
- """Provides an operation's service-side initial metadata.
-
- Returns:
- A value to use for an operation's service-side initial metadata, or
- None.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def invocation_completion(self):
- """Provides an operation's invocation-side completion.
-
- Returns:
- A base.Completion to use for an operation's invocation-side completion.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def service_completion(self):
- """Provides an operation's service-side completion.
-
- Returns:
- A base.Completion to use for an operation's service-side completion.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def metadata_transmitted(self, original_metadata, transmitted_metadata):
- """Identifies whether or not metadata was properly transmitted.
-
- Args:
- original_metadata: A metadata value passed to the system under test.
- transmitted_metadata: The same metadata value after having been
- transmitted through the system under test.
-
- Returns:
- Whether or not the metadata was properly transmitted.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def completion_transmitted(self, original_completion, transmitted_completion):
- """Identifies whether or not a base.Completion was properly transmitted.
-
- Args:
- original_completion: A base.Completion passed to the system under test.
- transmitted_completion: The same completion value after having been
- transmitted through the system under test.
-
- Returns:
- Whether or not the completion was properly transmitted.
- """
- raise NotImplementedError()
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py
index 791620307b..df620b19ba 100644
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py
+++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py
@@ -41,6 +41,7 @@ from concurrent import futures
import six
# test_interfaces is referenced from specification in this module.
+from grpc.framework.foundation import future
from grpc.framework.foundation import logging_pool
from grpc.framework.interfaces.face import face
from tests.unit.framework.common import test_constants
@@ -159,6 +160,8 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest.
test_messages.verify(request, response, self)
self.assertIs(callback.future(), response_future)
+ self.assertIsNone(response_future.exception())
+ self.assertIsNone(response_future.traceback())
def testSuccessfulUnaryRequestStreamResponse(self):
for (group, method), test_messages_sequence in (
@@ -191,6 +194,8 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest.
test_messages.verify(requests, response, self)
self.assertIs(future_passed_to_callback, response_future)
+ self.assertIsNone(response_future.exception())
+ self.assertIsNone(response_future.traceback())
def testSuccessfulStreamRequestStreamResponse(self):
for (group, method), test_messages_sequence in (
@@ -301,6 +306,12 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest.
self.assertIs(callback.future(), response_future)
self.assertFalse(cancel_method_return_value)
self.assertTrue(response_future.cancelled())
+ with self.assertRaises(future.CancelledError):
+ response_future.result()
+ with self.assertRaises(future.CancelledError):
+ response_future.exception()
+ with self.assertRaises(future.CancelledError):
+ response_future.traceback()
def testCancelledUnaryRequestStreamResponse(self):
for (group, method), test_messages_sequence in (
@@ -332,6 +343,12 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest.
self.assertIs(callback.future(), response_future)
self.assertFalse(cancel_method_return_value)
self.assertTrue(response_future.cancelled())
+ with self.assertRaises(future.CancelledError):
+ response_future.result()
+ with self.assertRaises(future.CancelledError):
+ response_future.exception()
+ with self.assertRaises(future.CancelledError):
+ response_future.traceback()
def testCancelledStreamRequestStreamResponse(self):
for (group, method), test_messages_sequence in (
@@ -363,6 +380,9 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest.
response_future.exception(), face.ExpirationError)
with self.assertRaises(face.ExpirationError):
response_future.result()
+ self.assertIsInstance(
+ response_future.exception(), face.AbortionError)
+ self.assertIsNotNone(response_future.traceback())
def testExpiredUnaryRequestStreamResponse(self):
for (group, method), test_messages_sequence in (
@@ -392,6 +412,9 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest.
response_future.exception(), face.ExpirationError)
with self.assertRaises(face.ExpirationError):
response_future.result()
+ self.assertIsInstance(
+ response_future.exception(), face.AbortionError)
+ self.assertIsNotNone(response_future.traceback())
def testExpiredStreamRequestStreamResponse(self):
for (group, method), test_messages_sequence in (
@@ -411,11 +434,13 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest.
for test_messages in test_messages_sequence:
request = test_messages.request()
callback = _Callback()
+ abortion_callback = _Callback()
with self._control.fail():
response_future = self._invoker.future(group, method)(
request, _3069_test_constant.REALLY_SHORT_TIMEOUT)
response_future.add_done_callback(callback)
+ response_future.add_abortion_callback(abortion_callback)
self.assertIs(callback.future(), response_future)
# Because the servicer fails outside of the thread from which the
@@ -426,6 +451,8 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest.
response_future.exception(), face.ExpirationError)
with self.assertRaises(face.ExpirationError):
response_future.result()
+ self.assertIsNotNone(response_future.traceback())
+ self.assertIsNotNone(abortion_callback.future())
def testFailedUnaryRequestStreamResponse(self):
for (group, method), test_messages_sequence in (
@@ -448,11 +475,13 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest.
for test_messages in test_messages_sequence:
requests = test_messages.requests()
callback = _Callback()
+ abortion_callback = _Callback()
with self._control.fail():
response_future = self._invoker.future(group, method)(
iter(requests), _3069_test_constant.REALLY_SHORT_TIMEOUT)
response_future.add_done_callback(callback)
+ response_future.add_abortion_callback(abortion_callback)
self.assertIs(callback.future(), response_future)
# Because the servicer fails outside of the thread from which the
@@ -463,6 +492,8 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest.
response_future.exception(), face.ExpirationError)
with self.assertRaises(face.ExpirationError):
response_future.result()
+ self.assertIsNotNone(response_future.traceback())
+ self.assertIsNotNone(abortion_callback.future())
def testFailedStreamRequestStreamResponse(self):
for (group, method), test_messages_sequence in (
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_receiver.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_receiver.py
deleted file mode 100644
index 48f31fc677..0000000000
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_receiver.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""A utility useful in tests of asynchronous, event-driven interfaces."""
-
-import threading
-
-from grpc.framework.interfaces.face import face
-
-
-class Receiver(face.ResponseReceiver):
- """A utility object useful in tests of asynchronous code."""
-
- def __init__(self):
- self._condition = threading.Condition()
- self._initial_metadata = None
- self._responses = []
- self._terminal_metadata = None
- self._code = None
- self._details = None
- self._completed = False
- self._abortion = None
-
- def abort(self, abortion):
- with self._condition:
- self._abortion = abortion
- self._condition.notify_all()
-
- def initial_metadata(self, initial_metadata):
- with self._condition:
- self._initial_metadata = initial_metadata
-
- def response(self, response):
- with self._condition:
- self._responses.append(response)
-
- def complete(self, terminal_metadata, code, details):
- with self._condition:
- self._terminal_metadata = terminal_metadata
- self._code = code
- self._details = details
- self._completed = True
- self._condition.notify_all()
-
- def block_until_terminated(self):
- with self._condition:
- while self._abortion is None and not self._completed:
- self._condition.wait()
-
- def unary_response(self):
- with self._condition:
- if self._abortion is not None:
- raise AssertionError('Aborted: "{}"!'.format(self._abortion))
- elif len(self._responses) != 1:
- raise AssertionError(
- '%d responses received, not exactly one!', len(self._responses))
- else:
- return self._responses[0]
-
- def stream_responses(self):
- with self._condition:
- if self._abortion is None:
- return list(self._responses)
- else:
- raise AssertionError('Aborted: "{}"!'.format(self._abortion))
-
- def abortion(self):
- with self._condition:
- return self._abortion
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/links/__init__.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/links/__init__.py
deleted file mode 100644
index 7086519106..0000000000
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/links/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/links/test_cases.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/links/test_cases.py
deleted file mode 100644
index 608e64119e..0000000000
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/links/test_cases.py
+++ /dev/null
@@ -1,327 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Tests of the links interface of RPC Framework."""
-
-# unittest is referenced from specification in this module.
-import abc
-import unittest # pylint: disable=unused-import
-
-import six
-
-from grpc.framework.interfaces.links import links
-from tests.unit.framework.common import test_constants
-from tests.unit.framework.interfaces.links import test_utilities
-
-
-def at_least_n_payloads_received_predicate(n):
- def predicate(ticket_sequence):
- payload_count = 0
- for ticket in ticket_sequence:
- if ticket.payload is not None:
- payload_count += 1
- if n <= payload_count:
- return True
- else:
- return False
- return predicate
-
-
-def terminated(ticket_sequence):
- return ticket_sequence and ticket_sequence[-1].termination is not None
-
-_TRANSMISSION_GROUP = 'test.Group'
-_TRANSMISSION_METHOD = 'TestMethod'
-
-
-class TransmissionTest(six.with_metaclass(abc.ABCMeta)):
- """Tests ticket transmission between two connected links.
-
- This class must be mixed into a unittest.TestCase that implements the abstract
- methods it provides.
- """
-
- # This is a unittest.TestCase mix-in.
- # pylint: disable=invalid-name
-
- @abc.abstractmethod
- def create_transmitting_links(self):
- """Creates two connected links for use in this test.
-
- Returns:
- Two links.Links, the first of which will be used on the invocation side
- of RPCs and the second of which will be used on the service side of
- RPCs.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def destroy_transmitting_links(self, invocation_side_link, service_side_link):
- """Destroys the two connected links created for this test.
-
-
- Args:
- invocation_side_link: The link used on the invocation side of RPCs in
- this test.
- service_side_link: The link used on the service side of RPCs in this
- test.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def create_invocation_initial_metadata(self):
- """Creates a value for use as invocation-side initial metadata.
-
- Returns:
- A metadata value appropriate for use as invocation-side initial metadata
- or None if invocation-side initial metadata transmission is not
- supported by the links under test.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def create_invocation_terminal_metadata(self):
- """Creates a value for use as invocation-side terminal metadata.
-
- Returns:
- A metadata value appropriate for use as invocation-side terminal
- metadata or None if invocation-side terminal metadata transmission is
- not supported by the links under test.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def create_service_initial_metadata(self):
- """Creates a value for use as service-side initial metadata.
-
- Returns:
- A metadata value appropriate for use as service-side initial metadata or
- None if service-side initial metadata transmission is not supported by
- the links under test.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def create_service_terminal_metadata(self):
- """Creates a value for use as service-side terminal metadata.
-
- Returns:
- A metadata value appropriate for use as service-side terminal metadata or
- None if service-side terminal metadata transmission is not supported by
- the links under test.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def create_invocation_completion(self):
- """Creates values for use as invocation-side code and message.
-
- Returns:
- An invocation-side code value and an invocation-side message value.
- Either or both may be None if invocation-side code and/or
- invocation-side message transmission is not supported by the links
- under test.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def create_service_completion(self):
- """Creates values for use as service-side code and message.
-
- Returns:
- A service-side code value and a service-side message value. Either or
- both may be None if service-side code and/or service-side message
- transmission is not supported by the links under test.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def assertMetadataTransmitted(self, original_metadata, transmitted_metadata):
- """Asserts that transmitted_metadata contains original_metadata.
-
- Args:
- original_metadata: A metadata object used in this test.
- transmitted_metadata: A metadata object obtained after transmission
- through the system under test.
-
- Raises:
- AssertionError: if the transmitted_metadata object does not contain
- original_metadata.
- """
- raise NotImplementedError()
-
- def group_and_method(self):
- """Returns the group and method used in this test case.
-
- Returns:
- A pair of the group and method used in this test case.
- """
- return _TRANSMISSION_GROUP, _TRANSMISSION_METHOD
-
- def serialize_request(self, request):
- """Serializes a request value used in this test case.
-
- Args:
- request: A request value created by this test case.
-
- Returns:
- A bytestring that is the serialization of the given request.
- """
- return request
-
- def deserialize_request(self, serialized_request):
- """Deserializes a request value used in this test case.
-
- Args:
- serialized_request: A bytestring that is the serialization of some request
- used in this test case.
-
- Returns:
- The request value encoded by the given bytestring.
- """
- return serialized_request
-
- def serialize_response(self, response):
- """Serializes a response value used in this test case.
-
- Args:
- response: A response value created by this test case.
-
- Returns:
- A bytestring that is the serialization of the given response.
- """
- return response
-
- def deserialize_response(self, serialized_response):
- """Deserializes a response value used in this test case.
-
- Args:
- serialized_response: A bytestring that is the serialization of some
- response used in this test case.
-
- Returns:
- The response value encoded by the given bytestring.
- """
- return serialized_response
-
- def _assert_is_valid_metadata_payload_sequence(
- self, ticket_sequence, payloads, initial_metadata, terminal_metadata):
- initial_metadata_seen = False
- seen_payloads = []
- terminal_metadata_seen = False
-
- for ticket in ticket_sequence:
- if ticket.initial_metadata is not None:
- self.assertFalse(initial_metadata_seen)
- self.assertFalse(seen_payloads)
- self.assertFalse(terminal_metadata_seen)
- self.assertMetadataTransmitted(initial_metadata, ticket.initial_metadata)
- initial_metadata_seen = True
-
- if ticket.payload is not None:
- self.assertFalse(terminal_metadata_seen)
- seen_payloads.append(ticket.payload)
-
- if ticket.terminal_metadata is not None:
- self.assertFalse(terminal_metadata_seen)
- self.assertMetadataTransmitted(terminal_metadata, ticket.terminal_metadata)
- terminal_metadata_seen = True
- self.assertSequenceEqual(payloads, seen_payloads)
-
- def _assert_is_valid_invocation_sequence(
- self, ticket_sequence, group, method, payloads, initial_metadata,
- terminal_metadata, termination):
- self.assertLess(0, len(ticket_sequence))
- self.assertEqual(group, ticket_sequence[0].group)
- self.assertEqual(method, ticket_sequence[0].method)
- self._assert_is_valid_metadata_payload_sequence(
- ticket_sequence, payloads, initial_metadata, terminal_metadata)
- self.assertIs(termination, ticket_sequence[-1].termination)
-
- def _assert_is_valid_service_sequence(
- self, ticket_sequence, payloads, initial_metadata, terminal_metadata,
- code, message, termination):
- self.assertLess(0, len(ticket_sequence))
- self._assert_is_valid_metadata_payload_sequence(
- ticket_sequence, payloads, initial_metadata, terminal_metadata)
- self.assertEqual(code, ticket_sequence[-1].code)
- self.assertEqual(message, ticket_sequence[-1].message)
- self.assertIs(termination, ticket_sequence[-1].termination)
-
- def setUp(self):
- self._invocation_link, self._service_link = self.create_transmitting_links()
- self._invocation_mate = test_utilities.RecordingLink()
- self._service_mate = test_utilities.RecordingLink()
- self._invocation_link.join_link(self._invocation_mate)
- self._service_link.join_link(self._service_mate)
-
- def tearDown(self):
- self.destroy_transmitting_links(self._invocation_link, self._service_link)
-
- def testSimplestRoundTrip(self):
- """Tests transmission of one ticket in each direction."""
- invocation_operation_id = object()
- invocation_payload = b'\x07' * 1023
- timeout = test_constants.LONG_TIMEOUT
- invocation_initial_metadata = self.create_invocation_initial_metadata()
- invocation_terminal_metadata = self.create_invocation_terminal_metadata()
- invocation_code, invocation_message = self.create_invocation_completion()
- service_payload = b'\x08' * 1025
- service_initial_metadata = self.create_service_initial_metadata()
- service_terminal_metadata = self.create_service_terminal_metadata()
- service_code, service_message = self.create_service_completion()
-
- original_invocation_ticket = links.Ticket(
- invocation_operation_id, 0, _TRANSMISSION_GROUP, _TRANSMISSION_METHOD,
- links.Ticket.Subscription.FULL, timeout, 0, invocation_initial_metadata,
- invocation_payload, invocation_terminal_metadata, invocation_code,
- invocation_message, links.Ticket.Termination.COMPLETION, None)
- self._invocation_link.accept_ticket(original_invocation_ticket)
-
- self._service_mate.block_until_tickets_satisfy(
- at_least_n_payloads_received_predicate(1))
- service_operation_id = self._service_mate.tickets()[0].operation_id
-
- self._service_mate.block_until_tickets_satisfy(terminated)
- self._assert_is_valid_invocation_sequence(
- self._service_mate.tickets(), _TRANSMISSION_GROUP, _TRANSMISSION_METHOD,
- (invocation_payload,), invocation_initial_metadata,
- invocation_terminal_metadata, links.Ticket.Termination.COMPLETION)
-
- original_service_ticket = links.Ticket(
- service_operation_id, 0, None, None, links.Ticket.Subscription.FULL,
- timeout, 0, service_initial_metadata, service_payload,
- service_terminal_metadata, service_code, service_message,
- links.Ticket.Termination.COMPLETION, None)
- self._service_link.accept_ticket(original_service_ticket)
- self._invocation_mate.block_until_tickets_satisfy(terminated)
- self._assert_is_valid_service_sequence(
- self._invocation_mate.tickets(), (service_payload,),
- service_initial_metadata, service_terminal_metadata, service_code,
- service_message, links.Ticket.Termination.COMPLETION)
diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/links/test_utilities.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/links/test_utilities.py
deleted file mode 100644
index 39c7f2fc63..0000000000
--- a/src/python/grpcio_tests/tests/unit/framework/interfaces/links/test_utilities.py
+++ /dev/null
@@ -1,167 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""State and behavior appropriate for use in tests."""
-
-import logging
-import threading
-import time
-
-from grpc.framework.interfaces.links import links
-from grpc.framework.interfaces.links import utilities
-
-# A more-or-less arbitrary limit on the length of raw data values to be logged.
-_UNCOMFORTABLY_LONG = 48
-
-
-def _safe_for_log_ticket(ticket):
- """Creates a safe-for-printing-to-the-log ticket for a given ticket.
-
- Args:
- ticket: Any links.Ticket.
-
- Returns:
- A links.Ticket that is as much as can be equal to the given ticket but
- possibly features values like the string "<payload of length 972321>" in
- place of the actual values of the given ticket.
- """
- if isinstance(ticket.payload, (basestring,)):
- payload_length = len(ticket.payload)
- else:
- payload_length = -1
- if payload_length < _UNCOMFORTABLY_LONG:
- return ticket
- else:
- return links.Ticket(
- ticket.operation_id, ticket.sequence_number,
- ticket.group, ticket.method, ticket.subscription, ticket.timeout,
- ticket.allowance, ticket.initial_metadata,
- '<payload of length {}>'.format(payload_length),
- ticket.terminal_metadata, ticket.code, ticket.message,
- ticket.termination, None)
-
-
-class RecordingLink(links.Link):
- """A Link that records every ticket passed to it."""
-
- def __init__(self):
- self._condition = threading.Condition()
- self._tickets = []
-
- def accept_ticket(self, ticket):
- with self._condition:
- self._tickets.append(ticket)
- self._condition.notify_all()
-
- def join_link(self, link):
- pass
-
- def block_until_tickets_satisfy(self, predicate):
- """Blocks until the received tickets satisfy the given predicate.
-
- Args:
- predicate: A callable that takes a sequence of tickets and returns a
- boolean value.
- """
- with self._condition:
- while not predicate(self._tickets):
- self._condition.wait()
-
- def tickets(self):
- """Returns a copy of the list of all tickets received by this Link."""
- with self._condition:
- return tuple(self._tickets)
-
-
-class _Pipe(object):
- """A conduit that logs all tickets passed through it."""
-
- def __init__(self, name):
- self._lock = threading.Lock()
- self._name = name
- self._left_mate = utilities.NULL_LINK
- self._right_mate = utilities.NULL_LINK
-
- def accept_left_to_right_ticket(self, ticket):
- with self._lock:
- logging.warning(
- '%s: moving left to right through %s: %s', time.time(), self._name,
- _safe_for_log_ticket(ticket))
- try:
- self._right_mate.accept_ticket(ticket)
- except Exception as e: # pylint: disable=broad-except
- logging.exception(e)
-
- def accept_right_to_left_ticket(self, ticket):
- with self._lock:
- logging.warning(
- '%s: moving right to left through %s: %s', time.time(), self._name,
- _safe_for_log_ticket(ticket))
- try:
- self._left_mate.accept_ticket(ticket)
- except Exception as e: # pylint: disable=broad-except
- logging.exception(e)
-
- def join_left_mate(self, left_mate):
- with self._lock:
- self._left_mate = utilities.NULL_LINK if left_mate is None else left_mate
-
- def join_right_mate(self, right_mate):
- with self._lock:
- self._right_mate = (
- utilities.NULL_LINK if right_mate is None else right_mate)
-
-
-class _Facade(links.Link):
-
- def __init__(self, accept, join):
- self._accept = accept
- self._join = join
-
- def accept_ticket(self, ticket):
- self._accept(ticket)
-
- def join_link(self, link):
- self._join(link)
-
-
-def logging_links(name):
- """Creates a conduit that logs all tickets passed through it.
-
- Args:
- name: A name to use for the conduit to identify itself in logging output.
-
- Returns:
- Two links.Links, the first of which is the "left" side of the conduit
- and the second of which is the "right" side of the conduit.
- """
- pipe = _Pipe(name)
- left_facade = _Facade(pipe.accept_left_to_right_ticket, pipe.join_left_mate)
- right_facade = _Facade(pipe.accept_right_to_left_ticket, pipe.join_right_mate)
- return left_facade, right_facade
diff --git a/src/python/grpcio_tests/tests/unit/test_common.py b/src/python/grpcio_tests/tests/unit/test_common.py
index c8886bf4ca..cd71bd80d7 100644
--- a/src/python/grpcio_tests/tests/unit/test_common.py
+++ b/src/python/grpcio_tests/tests/unit/test_common.py
@@ -31,6 +31,7 @@
import collections
+import grpc
import six
INVOCATION_INITIAL_METADATA = (('0', 'abc'), ('1', 'def'), ('2', 'ghi'),)
@@ -78,3 +79,24 @@ def metadata_transmitted(original_metadata, transmitted_metadata):
return False
else:
return True
+
+
+def test_secure_channel(
+ target, channel_credentials, server_host_override):
+ """Creates an insecure Channel to a remote host.
+
+ Args:
+ host: The name of the remote host to which to connect.
+ port: The port of the remote host to which to connect.
+ channel_credentials: The implementations.ChannelCredentials with which to
+ connect.
+ server_host_override: The target name used for SSL host name checking.
+
+ Returns:
+ An implementations.Channel to the remote host through which RPCs may be
+ conducted.
+ """
+ channel = grpc.secure_channel(
+ target, channel_credentials,
+ (('grpc.ssl_target_name_override', server_host_override,),))
+ return channel