blob: f1bec238cf5503eb8411a43dcf91b765a07ab7c0 [file] [log] [blame]
# 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.
# Fork of grpc._adapter._low_test; the grpc._cython.types adapter in
# grpc._cython.low should transparently support the semantics expected of
# grpc._adapter._low.
import time
import unittest
from grpc._adapter import _types
from grpc._cython import adapter_low as _low
class InsecureServerInsecureClient(unittest.TestCase):
def setUp(self):
self.server_completion_queue = _low.CompletionQueue()
self.server = _low.Server(self.server_completion_queue, [])
self.port = self.server.add_http2_port('[::]:0')
self.client_completion_queue = _low.CompletionQueue()
self.client_channel = _low.Channel('localhost:%d'%self.port, [])
self.server.start()
def tearDown(self):
self.server.shutdown()
del self.client_channel
self.client_completion_queue.shutdown()
while (self.client_completion_queue.next().type !=
_types.EventType.QUEUE_SHUTDOWN):
pass
self.server_completion_queue.shutdown()
while (self.server_completion_queue.next().type !=
_types.EventType.QUEUE_SHUTDOWN):
pass
del self.client_completion_queue
del self.server_completion_queue
del self.server
@unittest.skip('TODO(atash): implement grpc._cython.adapter_low')
def testEcho(self):
DEADLINE = time.time()+5
DEADLINE_TOLERANCE = 0.25
CLIENT_METADATA_ASCII_KEY = 'key'
CLIENT_METADATA_ASCII_VALUE = 'val'
CLIENT_METADATA_BIN_KEY = 'key-bin'
CLIENT_METADATA_BIN_VALUE = b'\0'*1000
SERVER_INITIAL_METADATA_KEY = 'init_me_me_me'
SERVER_INITIAL_METADATA_VALUE = 'whodawha?'
SERVER_TRAILING_METADATA_KEY = 'california_is_in_a_drought'
SERVER_TRAILING_METADATA_VALUE = 'zomg it is'
SERVER_STATUS_CODE = _types.StatusCode.OK
SERVER_STATUS_DETAILS = 'our work is never over'
REQUEST = 'in death a member of project mayhem has a name'
RESPONSE = 'his name is robert paulson'
METHOD = 'twinkies'
HOST = 'hostess'
server_request_tag = object()
request_call_result = self.server.request_call(self.server_completion_queue,
server_request_tag)
self.assertEqual(_types.CallError.OK, request_call_result)
client_call_tag = object()
client_call = self.client_channel.create_call(self.client_completion_queue,
METHOD, HOST, DEADLINE)
client_initial_metadata = [
(CLIENT_METADATA_ASCII_KEY, CLIENT_METADATA_ASCII_VALUE),
(CLIENT_METADATA_BIN_KEY, CLIENT_METADATA_BIN_VALUE)]
client_start_batch_result = client_call.start_batch([
_types.OpArgs.send_initial_metadata(client_initial_metadata),
_types.OpArgs.send_message(REQUEST),
_types.OpArgs.send_close_from_client(),
_types.OpArgs.recv_initial_metadata(),
_types.OpArgs.recv_message(),
_types.OpArgs.recv_status_on_client()
], client_call_tag)
self.assertEqual(_types.CallError.OK, client_start_batch_result)
request_event = self.server_completion_queue.next(DEADLINE)
self.assertEqual(_types.EventType.OP_COMPLETE, request_event.type)
self.assertIsInstance(request_event.call, _low.Call)
self.assertIs(server_request_tag, request_event.tag)
self.assertEqual(1, len(request_event.results))
self.assertEqual(dict(client_initial_metadata),
dict(request_event.results[0].initial_metadata))
self.assertEqual(METHOD, request_event.call_details.method)
self.assertEqual(HOST, request_event.call_details.host)
self.assertLess(abs(DEADLINE - request_event.call_details.deadline),
DEADLINE_TOLERANCE)
server_call_tag = object()
server_call = request_event.call
server_initial_metadata = [
(SERVER_INITIAL_METADATA_KEY, SERVER_INITIAL_METADATA_VALUE)]
server_trailing_metadata = [
(SERVER_TRAILING_METADATA_KEY, SERVER_TRAILING_METADATA_VALUE)]
server_start_batch_result = server_call.start_batch([
_types.OpArgs.send_initial_metadata(server_initial_metadata),
_types.OpArgs.recv_message(),
_types.OpArgs.send_message(RESPONSE),
_types.OpArgs.recv_close_on_server(),
_types.OpArgs.send_status_from_server(
server_trailing_metadata, SERVER_STATUS_CODE, SERVER_STATUS_DETAILS)
], server_call_tag)
self.assertEqual(_types.CallError.OK, server_start_batch_result)
client_event = self.client_completion_queue.next(DEADLINE)
server_event = self.server_completion_queue.next(DEADLINE)
self.assertEqual(6, len(client_event.results))
found_client_op_types = set()
for client_result in client_event.results:
# we expect each op type to be unique
self.assertNotIn(client_result.type, found_client_op_types)
found_client_op_types.add(client_result.type)
if client_result.type == _types.OpType.RECV_INITIAL_METADATA:
self.assertEqual(dict(server_initial_metadata),
dict(client_result.initial_metadata))
elif client_result.type == _types.OpType.RECV_MESSAGE:
self.assertEqual(RESPONSE, client_result.message)
elif client_result.type == _types.OpType.RECV_STATUS_ON_CLIENT:
self.assertEqual(dict(server_trailing_metadata),
dict(client_result.trailing_metadata))
self.assertEqual(SERVER_STATUS_DETAILS, client_result.status.details)
self.assertEqual(SERVER_STATUS_CODE, client_result.status.code)
self.assertEqual(set([
_types.OpType.SEND_INITIAL_METADATA,
_types.OpType.SEND_MESSAGE,
_types.OpType.SEND_CLOSE_FROM_CLIENT,
_types.OpType.RECV_INITIAL_METADATA,
_types.OpType.RECV_MESSAGE,
_types.OpType.RECV_STATUS_ON_CLIENT
]), found_client_op_types)
self.assertEqual(5, len(server_event.results))
found_server_op_types = set()
for server_result in server_event.results:
self.assertNotIn(client_result.type, found_server_op_types)
found_server_op_types.add(server_result.type)
if server_result.type == _types.OpType.RECV_MESSAGE:
self.assertEqual(REQUEST, server_result.message)
elif server_result.type == _types.OpType.RECV_CLOSE_ON_SERVER:
self.assertFalse(server_result.cancelled)
self.assertEqual(set([
_types.OpType.SEND_INITIAL_METADATA,
_types.OpType.RECV_MESSAGE,
_types.OpType.SEND_MESSAGE,
_types.OpType.RECV_CLOSE_ON_SERVER,
_types.OpType.SEND_STATUS_FROM_SERVER
]), found_server_op_types)
del client_call
del server_call
if __name__ == '__main__':
unittest.main(verbosity=2)