Masood Malekghassemi | 743c10c | 2015-06-16 18:05:27 -0700 | [diff] [blame] | 1 | # Copyright 2015, Google Inc. |
| 2 | # All rights reserved. |
| 3 | # |
| 4 | # Redistribution and use in source and binary forms, with or without |
| 5 | # modification, are permitted provided that the following conditions are |
| 6 | # met: |
| 7 | # |
| 8 | # * Redistributions of source code must retain the above copyright |
| 9 | # notice, this list of conditions and the following disclaimer. |
| 10 | # * Redistributions in binary form must reproduce the above |
| 11 | # copyright notice, this list of conditions and the following disclaimer |
| 12 | # in the documentation and/or other materials provided with the |
| 13 | # distribution. |
| 14 | # * Neither the name of Google Inc. nor the names of its |
| 15 | # contributors may be used to endorse or promote products derived from |
| 16 | # this software without specific prior written permission. |
| 17 | # |
| 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 21 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 | |
| 30 | # Fork of grpc._adapter._low_test; the grpc._cython.types adapter in |
| 31 | # grpc._cython.low should transparently support the semantics expected of |
| 32 | # grpc._adapter._low. |
| 33 | |
| 34 | import time |
| 35 | import unittest |
| 36 | |
| 37 | from grpc._adapter import _types |
| 38 | from grpc._cython import adapter_low as _low |
| 39 | |
| 40 | |
| 41 | class InsecureServerInsecureClient(unittest.TestCase): |
| 42 | |
| 43 | def setUp(self): |
| 44 | self.server_completion_queue = _low.CompletionQueue() |
| 45 | self.server = _low.Server(self.server_completion_queue, []) |
| 46 | self.port = self.server.add_http2_port('[::]:0') |
| 47 | self.client_completion_queue = _low.CompletionQueue() |
| 48 | self.client_channel = _low.Channel('localhost:%d'%self.port, []) |
| 49 | |
| 50 | self.server.start() |
| 51 | |
| 52 | def tearDown(self): |
| 53 | self.server.shutdown() |
| 54 | del self.client_channel |
| 55 | |
| 56 | self.client_completion_queue.shutdown() |
| 57 | while (self.client_completion_queue.next().type != |
| 58 | _types.EventType.QUEUE_SHUTDOWN): |
| 59 | pass |
| 60 | self.server_completion_queue.shutdown() |
| 61 | while (self.server_completion_queue.next().type != |
| 62 | _types.EventType.QUEUE_SHUTDOWN): |
| 63 | pass |
| 64 | |
| 65 | del self.client_completion_queue |
| 66 | del self.server_completion_queue |
| 67 | del self.server |
| 68 | |
| 69 | @unittest.skip('TODO(atash): implement grpc._cython.adapter_low') |
| 70 | def testEcho(self): |
| 71 | DEADLINE = time.time()+5 |
| 72 | DEADLINE_TOLERANCE = 0.25 |
| 73 | CLIENT_METADATA_ASCII_KEY = 'key' |
| 74 | CLIENT_METADATA_ASCII_VALUE = 'val' |
| 75 | CLIENT_METADATA_BIN_KEY = 'key-bin' |
| 76 | CLIENT_METADATA_BIN_VALUE = b'\0'*1000 |
| 77 | SERVER_INITIAL_METADATA_KEY = 'init_me_me_me' |
| 78 | SERVER_INITIAL_METADATA_VALUE = 'whodawha?' |
Craig Tiller | 987263a | 2015-08-21 16:14:43 -0700 | [diff] [blame] | 79 | SERVER_TRAILING_METADATA_KEY = 'california_is_in_a_drought' |
Masood Malekghassemi | 743c10c | 2015-06-16 18:05:27 -0700 | [diff] [blame] | 80 | SERVER_TRAILING_METADATA_VALUE = 'zomg it is' |
| 81 | SERVER_STATUS_CODE = _types.StatusCode.OK |
| 82 | SERVER_STATUS_DETAILS = 'our work is never over' |
| 83 | REQUEST = 'in death a member of project mayhem has a name' |
| 84 | RESPONSE = 'his name is robert paulson' |
| 85 | METHOD = 'twinkies' |
| 86 | HOST = 'hostess' |
| 87 | server_request_tag = object() |
| 88 | request_call_result = self.server.request_call(self.server_completion_queue, |
| 89 | server_request_tag) |
| 90 | |
| 91 | self.assertEqual(_types.CallError.OK, request_call_result) |
| 92 | |
| 93 | client_call_tag = object() |
| 94 | client_call = self.client_channel.create_call(self.client_completion_queue, |
| 95 | METHOD, HOST, DEADLINE) |
| 96 | client_initial_metadata = [ |
| 97 | (CLIENT_METADATA_ASCII_KEY, CLIENT_METADATA_ASCII_VALUE), |
| 98 | (CLIENT_METADATA_BIN_KEY, CLIENT_METADATA_BIN_VALUE)] |
| 99 | client_start_batch_result = client_call.start_batch([ |
| 100 | _types.OpArgs.send_initial_metadata(client_initial_metadata), |
| 101 | _types.OpArgs.send_message(REQUEST), |
| 102 | _types.OpArgs.send_close_from_client(), |
| 103 | _types.OpArgs.recv_initial_metadata(), |
| 104 | _types.OpArgs.recv_message(), |
| 105 | _types.OpArgs.recv_status_on_client() |
| 106 | ], client_call_tag) |
| 107 | self.assertEqual(_types.CallError.OK, client_start_batch_result) |
| 108 | |
| 109 | request_event = self.server_completion_queue.next(DEADLINE) |
| 110 | self.assertEqual(_types.EventType.OP_COMPLETE, request_event.type) |
| 111 | self.assertIsInstance(request_event.call, _low.Call) |
| 112 | self.assertIs(server_request_tag, request_event.tag) |
| 113 | self.assertEqual(1, len(request_event.results)) |
| 114 | self.assertEqual(dict(client_initial_metadata), |
| 115 | dict(request_event.results[0].initial_metadata)) |
| 116 | self.assertEqual(METHOD, request_event.call_details.method) |
| 117 | self.assertEqual(HOST, request_event.call_details.host) |
| 118 | self.assertLess(abs(DEADLINE - request_event.call_details.deadline), |
| 119 | DEADLINE_TOLERANCE) |
| 120 | |
| 121 | server_call_tag = object() |
| 122 | server_call = request_event.call |
| 123 | server_initial_metadata = [ |
| 124 | (SERVER_INITIAL_METADATA_KEY, SERVER_INITIAL_METADATA_VALUE)] |
| 125 | server_trailing_metadata = [ |
| 126 | (SERVER_TRAILING_METADATA_KEY, SERVER_TRAILING_METADATA_VALUE)] |
| 127 | server_start_batch_result = server_call.start_batch([ |
| 128 | _types.OpArgs.send_initial_metadata(server_initial_metadata), |
| 129 | _types.OpArgs.recv_message(), |
| 130 | _types.OpArgs.send_message(RESPONSE), |
| 131 | _types.OpArgs.recv_close_on_server(), |
| 132 | _types.OpArgs.send_status_from_server( |
| 133 | server_trailing_metadata, SERVER_STATUS_CODE, SERVER_STATUS_DETAILS) |
| 134 | ], server_call_tag) |
| 135 | self.assertEqual(_types.CallError.OK, server_start_batch_result) |
| 136 | |
| 137 | client_event = self.client_completion_queue.next(DEADLINE) |
| 138 | server_event = self.server_completion_queue.next(DEADLINE) |
| 139 | |
| 140 | self.assertEqual(6, len(client_event.results)) |
| 141 | found_client_op_types = set() |
| 142 | for client_result in client_event.results: |
| 143 | # we expect each op type to be unique |
| 144 | self.assertNotIn(client_result.type, found_client_op_types) |
| 145 | found_client_op_types.add(client_result.type) |
| 146 | if client_result.type == _types.OpType.RECV_INITIAL_METADATA: |
| 147 | self.assertEqual(dict(server_initial_metadata), |
| 148 | dict(client_result.initial_metadata)) |
| 149 | elif client_result.type == _types.OpType.RECV_MESSAGE: |
| 150 | self.assertEqual(RESPONSE, client_result.message) |
| 151 | elif client_result.type == _types.OpType.RECV_STATUS_ON_CLIENT: |
| 152 | self.assertEqual(dict(server_trailing_metadata), |
| 153 | dict(client_result.trailing_metadata)) |
| 154 | self.assertEqual(SERVER_STATUS_DETAILS, client_result.status.details) |
| 155 | self.assertEqual(SERVER_STATUS_CODE, client_result.status.code) |
| 156 | self.assertEqual(set([ |
| 157 | _types.OpType.SEND_INITIAL_METADATA, |
| 158 | _types.OpType.SEND_MESSAGE, |
| 159 | _types.OpType.SEND_CLOSE_FROM_CLIENT, |
| 160 | _types.OpType.RECV_INITIAL_METADATA, |
| 161 | _types.OpType.RECV_MESSAGE, |
| 162 | _types.OpType.RECV_STATUS_ON_CLIENT |
| 163 | ]), found_client_op_types) |
| 164 | |
| 165 | self.assertEqual(5, len(server_event.results)) |
| 166 | found_server_op_types = set() |
| 167 | for server_result in server_event.results: |
| 168 | self.assertNotIn(client_result.type, found_server_op_types) |
| 169 | found_server_op_types.add(server_result.type) |
| 170 | if server_result.type == _types.OpType.RECV_MESSAGE: |
| 171 | self.assertEqual(REQUEST, server_result.message) |
| 172 | elif server_result.type == _types.OpType.RECV_CLOSE_ON_SERVER: |
| 173 | self.assertFalse(server_result.cancelled) |
| 174 | self.assertEqual(set([ |
| 175 | _types.OpType.SEND_INITIAL_METADATA, |
| 176 | _types.OpType.RECV_MESSAGE, |
| 177 | _types.OpType.SEND_MESSAGE, |
| 178 | _types.OpType.RECV_CLOSE_ON_SERVER, |
| 179 | _types.OpType.SEND_STATUS_FROM_SERVER |
| 180 | ]), found_server_op_types) |
| 181 | |
| 182 | del client_call |
| 183 | del server_call |
| 184 | |
| 185 | |
| 186 | if __name__ == '__main__': |
| 187 | unittest.main(verbosity=2) |