def testLonelyClient(self): host = 'nosuchhostexists' port = 54321 method = 'test method' deadline = time.time() + _TIMEOUT after_deadline = deadline + _AFTER_DELAY metadata_tag = object() finish_tag = object() completion_queue = _low.CompletionQueue() channel = _low.Channel('%s:%d' % (host, port), None) client_call = _low.Call(channel, completion_queue, method, host, deadline) client_call.invoke(completion_queue, metadata_tag, finish_tag) first_event = completion_queue.get(after_deadline) self.assertIsNotNone(first_event) second_event = completion_queue.get(after_deadline) self.assertIsNotNone(second_event) kinds = [event.kind for event in (first_event, second_event)] six.assertCountEqual(self, (_low.Event.Kind.METADATA_ACCEPTED, _low.Event.Kind.FINISH), kinds) self.assertIsNone(completion_queue.get(after_deadline)) completion_queue.stop() stop_event = completion_queue.get(_FUTURE) self.assertEqual(_low.Event.Kind.STOP, stop_event.kind) del client_call del channel del completion_queue
def _invoke(self, operation_id, group, method, initial_metadata, payload, termination, timeout, allowance): """Invoke an RPC. Args: operation_id: Any object to be used as an operation ID for the RPC. group: The group to which the RPC method belongs. method: The RPC method name. initial_metadata: The initial metadata object for the RPC. payload: A payload object for the RPC or None if no payload was given at invocation-time. termination: A links.Ticket.Termination value or None indicated whether or not more writes will follow from this side of the RPC. timeout: A duration of time in seconds to allow for the RPC. allowance: The number of payloads (beyond the free first one) that the local ticket exchange mate has granted permission to be read. """ if termination is links.Ticket.Termination.COMPLETION: high_write = _HighWrite.CLOSED elif termination is None: high_write = _HighWrite.OPEN else: return request_serializer = self._request_serializers.get((group, method)) response_deserializer = self._response_deserializers.get( (group, method)) if request_serializer is None or response_deserializer is None: cancellation_ticket = links.Ticket( operation_id, 0, None, None, None, None, None, None, None, None, None, None, links.Ticket.Termination.CANCELLATION) self._relay.add_value(cancellation_ticket) return call = _intermediary_low.Call(self._channel, self._completion_queue, '/%s/%s' % (group, method), self._host, time.time() + timeout) if initial_metadata is not None: for metadata_key, metadata_value in initial_metadata: call.add_metadata(metadata_key, metadata_value) call.invoke(self._completion_queue, operation_id, operation_id) if payload is None: if high_write is _HighWrite.CLOSED: call.complete(operation_id) low_write = _LowWrite.CLOSED else: low_write = _LowWrite.OPEN else: call.write(request_serializer(payload), operation_id) low_write = _LowWrite.ACTIVE self._rpc_states[operation_id] = _RPCState( call, request_serializer, response_deserializer, 0, _Read.AWAITING_METADATA, 1 if allowance is None else (1 + allowance), high_write, low_write)
def _invoke(self, operation_id, name, high_state, payload, timeout): """Invoke an RPC. Args: operation_id: Any object to be used as an operation ID for the RPC. name: The RPC method name. high_state: A _common.HighWrite value representing the "high write state" of the RPC. payload: A payload object for the RPC or None if no payload was given at invocation-time. timeout: A duration of time in seconds to allow for the RPC. """ request_serializer = self._request_serializers[name] call = _low.Call(self._channel, self._completion_queue, name, self._host, time.time() + timeout) if self._metadata_transformer is not None: metadata = self._metadata_transformer([]) for metadata_key, metadata_value in metadata: call.add_metadata(metadata_key, metadata_value) call.invoke(self._completion_queue, operation_id, operation_id) outstanding = set(_INVOCATION_EVENT_KINDS) if payload is None: if high_state is _common.HighWrite.CLOSED: call.complete(operation_id) low_state = _LowWrite.CLOSED outstanding.add(_low.Event.Kind.COMPLETE_ACCEPTED) else: low_state = _LowWrite.OPEN else: serialized_payload = request_serializer(payload) call.write(serialized_payload, operation_id) outstanding.add(_low.Event.Kind.WRITE_ACCEPTED) low_state = _LowWrite.ACTIVE write_state = _common.WriteState(low_state, high_state, []) common_state = _common.CommonRPCState( write_state, 0, self._response_deserializers[name], request_serializer) self._rpc_states[operation_id] = _RPCState(call, outstanding, True, common_state) if not self._spinning: self._pool.submit(self._spin, self._completion_queue) self._spinning = True
def testCancellation(self): method = 'test method' deadline = _FUTURE metadata_tag = object() finish_tag = object() write_tag = object() service_tag = object() read_tag = object() test_data = _BYTE_SEQUENCE_SEQUENCE server_data = [] client_data = [] client_call = _low.Call(self.channel, self.client_completion_queue, method, self.host, deadline) client_call.invoke(self.client_completion_queue, metadata_tag, finish_tag) self.server.service(service_tag) service_accepted = self.server_events.get() server_call = service_accepted.service_acceptance.call server_call.accept(self.server_completion_queue, finish_tag) server_call.premetadata() metadata_accepted = self.client_events.get() self.assertIsNotNone(metadata_accepted) for datum in test_data: client_call.write(datum, write_tag, 0) write_accepted = self.client_events.get() server_call.read(read_tag) read_accepted = self.server_events.get() server_data.append(read_accepted.bytes) server_call.write(read_accepted.bytes, write_tag, 0) write_accepted = self.server_events.get() self.assertIsNotNone(write_accepted) client_call.read(read_tag) read_accepted = self.client_events.get() client_data.append(read_accepted.bytes) client_call.cancel() # cancel() is idempotent. client_call.cancel() client_call.cancel() client_call.cancel() server_call.read(read_tag) server_terminal_event_one = self.server_events.get() server_terminal_event_two = self.server_events.get() if server_terminal_event_one.kind == _low.Event.Kind.READ_ACCEPTED: read_accepted = server_terminal_event_one rpc_accepted = server_terminal_event_two else: read_accepted = server_terminal_event_two rpc_accepted = server_terminal_event_one self.assertIsNotNone(read_accepted) self.assertIsNotNone(rpc_accepted) self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind) self.assertIsNone(read_accepted.bytes) self.assertEqual(_low.Event.Kind.FINISH, rpc_accepted.kind) self.assertEqual(_low.Status(_low.Code.CANCELLED, ''), rpc_accepted.status) finish_event = self.client_events.get() self.assertEqual(_low.Event.Kind.FINISH, finish_event.kind) self.assertEqual(_low.Status(_low.Code.CANCELLED, 'Cancelled'), finish_event.status) self.assertSequenceEqual(test_data, server_data) self.assertSequenceEqual(test_data, client_data)
def _perform_echo_test(self, test_data): method = 'test method' details = 'test details' server_leading_metadata_key = 'my_server_leading_key' server_leading_metadata_value = 'my_server_leading_value' server_trailing_metadata_key = 'my_server_trailing_key' server_trailing_metadata_value = 'my_server_trailing_value' client_metadata_key = 'my_client_key' client_metadata_value = 'my_client_value' server_leading_binary_metadata_key = 'my_server_leading_key-bin' server_leading_binary_metadata_value = b'\0'*2047 server_trailing_binary_metadata_key = 'my_server_trailing_key-bin' server_trailing_binary_metadata_value = b'\0'*2047 client_binary_metadata_key = 'my_client_key-bin' client_binary_metadata_value = b'\0'*2047 deadline = _FUTURE metadata_tag = object() finish_tag = object() write_tag = object() complete_tag = object() service_tag = object() read_tag = object() status_tag = object() server_data = [] client_data = [] client_call = _low.Call(self.channel, self.client_completion_queue, method, self.host, deadline) client_call.add_metadata(client_metadata_key, client_metadata_value) client_call.add_metadata(client_binary_metadata_key, client_binary_metadata_value) client_call.invoke(self.client_completion_queue, metadata_tag, finish_tag) self.server.service(service_tag) service_accepted = self.server_events.get() self.assertIsNotNone(service_accepted) self.assertIs(service_accepted.kind, _low.Event.Kind.SERVICE_ACCEPTED) self.assertIs(service_accepted.tag, service_tag) self.assertEqual(method, service_accepted.service_acceptance.method) self.assertEqual(self.host, service_accepted.service_acceptance.host) self.assertIsNotNone(service_accepted.service_acceptance.call) metadata = dict(service_accepted.metadata) self.assertIn(client_metadata_key, metadata) self.assertEqual(client_metadata_value, metadata[client_metadata_key]) self.assertIn(client_binary_metadata_key, metadata) self.assertEqual(client_binary_metadata_value, metadata[client_binary_metadata_key]) server_call = service_accepted.service_acceptance.call server_call.accept(self.server_completion_queue, finish_tag) server_call.add_metadata(server_leading_metadata_key, server_leading_metadata_value) server_call.add_metadata(server_leading_binary_metadata_key, server_leading_binary_metadata_value) server_call.premetadata() metadata_accepted = self.client_events.get() self.assertIsNotNone(metadata_accepted) self.assertEqual(_low.Event.Kind.METADATA_ACCEPTED, metadata_accepted.kind) self.assertEqual(metadata_tag, metadata_accepted.tag) metadata = dict(metadata_accepted.metadata) self.assertIn(server_leading_metadata_key, metadata) self.assertEqual(server_leading_metadata_value, metadata[server_leading_metadata_key]) self.assertIn(server_leading_binary_metadata_key, metadata) self.assertEqual(server_leading_binary_metadata_value, metadata[server_leading_binary_metadata_key]) for datum in test_data: client_call.write(datum, write_tag, _low.WriteFlags.WRITE_NO_COMPRESS) write_accepted = self.client_events.get() self.assertIsNotNone(write_accepted) self.assertIs(write_accepted.kind, _low.Event.Kind.WRITE_ACCEPTED) self.assertIs(write_accepted.tag, write_tag) self.assertIs(write_accepted.write_accepted, True) server_call.read(read_tag) read_accepted = self.server_events.get() self.assertIsNotNone(read_accepted) self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind) self.assertEqual(read_tag, read_accepted.tag) self.assertIsNotNone(read_accepted.bytes) server_data.append(read_accepted.bytes) server_call.write(read_accepted.bytes, write_tag, 0) write_accepted = self.server_events.get() self.assertIsNotNone(write_accepted) self.assertEqual(_low.Event.Kind.WRITE_ACCEPTED, write_accepted.kind) self.assertEqual(write_tag, write_accepted.tag) self.assertTrue(write_accepted.write_accepted) client_call.read(read_tag) read_accepted = self.client_events.get() self.assertIsNotNone(read_accepted) self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind) self.assertEqual(read_tag, read_accepted.tag) self.assertIsNotNone(read_accepted.bytes) client_data.append(read_accepted.bytes) client_call.complete(complete_tag) complete_accepted = self.client_events.get() self.assertIsNotNone(complete_accepted) self.assertIs(complete_accepted.kind, _low.Event.Kind.COMPLETE_ACCEPTED) self.assertIs(complete_accepted.tag, complete_tag) self.assertIs(complete_accepted.complete_accepted, True) server_call.read(read_tag) read_accepted = self.server_events.get() self.assertIsNotNone(read_accepted) self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind) self.assertEqual(read_tag, read_accepted.tag) self.assertIsNone(read_accepted.bytes) server_call.add_metadata(server_trailing_metadata_key, server_trailing_metadata_value) server_call.add_metadata(server_trailing_binary_metadata_key, server_trailing_binary_metadata_value) server_call.status(_low.Status(_low.Code.OK, details), status_tag) server_terminal_event_one = self.server_events.get() server_terminal_event_two = self.server_events.get() if server_terminal_event_one.kind == _low.Event.Kind.COMPLETE_ACCEPTED: status_accepted = server_terminal_event_one rpc_accepted = server_terminal_event_two else: status_accepted = server_terminal_event_two rpc_accepted = server_terminal_event_one self.assertIsNotNone(status_accepted) self.assertIsNotNone(rpc_accepted) self.assertEqual(_low.Event.Kind.COMPLETE_ACCEPTED, status_accepted.kind) self.assertEqual(status_tag, status_accepted.tag) self.assertTrue(status_accepted.complete_accepted) self.assertEqual(_low.Event.Kind.FINISH, rpc_accepted.kind) self.assertEqual(finish_tag, rpc_accepted.tag) self.assertEqual(_low.Status(_low.Code.OK, ''), rpc_accepted.status) client_call.read(read_tag) client_terminal_event_one = self.client_events.get() client_terminal_event_two = self.client_events.get() if client_terminal_event_one.kind == _low.Event.Kind.READ_ACCEPTED: read_accepted = client_terminal_event_one finish_accepted = client_terminal_event_two else: read_accepted = client_terminal_event_two finish_accepted = client_terminal_event_one self.assertIsNotNone(read_accepted) self.assertIsNotNone(finish_accepted) self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind) self.assertEqual(read_tag, read_accepted.tag) self.assertIsNone(read_accepted.bytes) self.assertEqual(_low.Event.Kind.FINISH, finish_accepted.kind) self.assertEqual(finish_tag, finish_accepted.tag) self.assertEqual(_low.Status(_low.Code.OK, details), finish_accepted.status) metadata = dict(finish_accepted.metadata) self.assertIn(server_trailing_metadata_key, metadata) self.assertEqual(server_trailing_metadata_value, metadata[server_trailing_metadata_key]) self.assertIn(server_trailing_binary_metadata_key, metadata) self.assertEqual(server_trailing_binary_metadata_value, metadata[server_trailing_binary_metadata_key]) self.assertSetEqual(set(key for key, _ in finish_accepted.metadata), set((server_trailing_metadata_key, server_trailing_binary_metadata_key,))) self.assertSequenceEqual(test_data, server_data) self.assertSequenceEqual(test_data, client_data)
def _invoke(self, operation_id, group, method, initial_metadata, payload, termination, timeout, allowance, options): """Invoke an RPC. Args: operation_id: Any object to be used as an operation ID for the RPC. group: The group to which the RPC method belongs. method: The RPC method name. initial_metadata: The initial metadata object for the RPC. payload: A payload object for the RPC or None if no payload was given at invocation-time. termination: A links.Ticket.Termination value or None indicated whether or not more writes will follow from this side of the RPC. timeout: A duration of time in seconds to allow for the RPC. allowance: The number of payloads (beyond the free first one) that the local ticket exchange mate has granted permission to be read. options: A beta_interfaces.GRPCCallOptions value or None. """ if termination is links.Ticket.Termination.COMPLETION: high_write = _HighWrite.CLOSED elif termination is None: high_write = _HighWrite.OPEN else: return transformed_initial_metadata = self._metadata_transformer( initial_metadata) request_serializer = self._request_serializers.get((group, method), _IDENTITY) response_deserializer = self._response_deserializers.get( (group, method), _IDENTITY) call = _intermediary_low.Call(self._channel, self._completion_queue, '/%s/%s' % (group, method), self._host, time.time() + timeout) if options is not None and options.credentials is not None: call.set_credentials(options.credentials._low_credentials) if transformed_initial_metadata is not None: for metadata_key, metadata_value in transformed_initial_metadata: call.add_metadata(metadata_key, metadata_value) call.invoke(self._completion_queue, operation_id, operation_id) if payload is None: if high_write is _HighWrite.CLOSED: call.complete(operation_id) low_write = _LowWrite.CLOSED due = set(( _METADATA, _COMPLETE, _FINISH, )) else: low_write = _LowWrite.OPEN due = set(( _METADATA, _FINISH, )) else: if options is not None and options.disable_compression: flags = _intermediary_low.WriteFlags.WRITE_NO_COMPRESS else: flags = 0 call.write(request_serializer(payload), operation_id, flags) low_write = _LowWrite.ACTIVE due = set(( _WRITE, _METADATA, _FINISH, )) context = _Context() self._rpc_states[operation_id] = _RPCState( call, request_serializer, response_deserializer, 1, _Read.AWAITING_METADATA, 1 if allowance is None else (1 + allowance), high_write, low_write, due, context) protocol = links.Protocol(links.Protocol.Kind.INVOCATION_CONTEXT, context) ticket = links.Ticket(operation_id, 0, None, None, None, None, None, None, None, None, None, None, None, protocol) self._relay.add_value(ticket)