def test_retriable_codes(): retriable_codes = [grpc.StatusCode.RESOURCE_EXHAUSTED, grpc.StatusCode.UNAVAILABLE, grpc.StatusCode.DATA_LOSS] service = _RetriableCodes(retriable_codes) server = grpc_server(service.handler) with default_channel() as channel: for retry_qty in range(len(retriable_codes)): interceptor = RetryInterceptor(max_retry_count=retry_qty, retriable_codes=retriable_codes) ch = grpc.intercept_channel(channel, interceptor) client = zone_service_pb2_grpc.ZoneServiceStub(ch) with pytest.raises(grpc.RpcError) as e: client.Get(zone_service_pb2.GetZoneRequest(zone_id="id")) assert e.value.code() == retriable_codes[retry_qty] service.reset_state() interceptor = RetryInterceptor(max_retry_count=len(retriable_codes), retriable_codes=retriable_codes) ch = grpc.intercept_channel(channel, interceptor) client = zone_service_pb2_grpc.ZoneServiceStub(ch) assert client.Get(zone_service_pb2.GetZoneRequest(zone_id="id")) == DEFAULT_ZONE server.stop(0)
def test_five_retries_internal(): service = _FailFirstAttempts(5, code=grpc.StatusCode.INTERNAL) server = grpc_server(service.handler) request = zone_service_pb2.GetZoneRequest(zone_id="id") retriable_codes = ( grpc.StatusCode.UNAVAILABLE, grpc.StatusCode.RESOURCE_EXHAUSTED, grpc.StatusCode.INTERNAL, ) with default_channel() as channel: for max_retry_count in range(4): interceptor = RetryInterceptor(max_retry_count=max_retry_count, retriable_codes=retriable_codes) ch = grpc.intercept_channel(channel, interceptor) client = zone_service_pb2_grpc.ZoneServiceStub(ch) with pytest.raises(grpc.RpcError) as e: client.Get(request) assert e.value.code() == grpc.StatusCode.INTERNAL service.reset(5) interceptor = RetryInterceptor(max_retry_count=5, retriable_codes=retriable_codes) ch = grpc.intercept_channel(channel, interceptor) client = zone_service_pb2_grpc.ZoneServiceStub(ch) res = client.Get(request) assert res == DEFAULT_ZONE server.stop(0)
def test_five_retries(): service = _FailFirstAttempts(5) server = grpc_server(service.handler) with default_channel() as channel: for max_retry_count in range(4): interceptor = RetryInterceptor(max_retry_count=max_retry_count) ch = grpc.intercept_channel(channel, interceptor) client = zone_service_pb2_grpc.ZoneServiceStub(ch) with pytest.raises(grpc.RpcError) as e: client.Get(zone_service_pb2.GetZoneRequest(zone_id="id")) assert e.value.code() == grpc.StatusCode.UNAVAILABLE service.reset(5) interceptor = RetryInterceptor(max_retry_count=5) ch = grpc.intercept_channel(channel, interceptor) client = zone_service_pb2_grpc.ZoneServiceStub(ch) res = client.Get(zone_service_pb2.GetZoneRequest(zone_id="id")) assert res == DEFAULT_ZONE server.stop(0)
def test_header_token_and_retry_count(): service = _HeaderTokenAndRetryCount() server = grpc_server(service.handler) with default_channel() as channel: interceptor = RetryInterceptor(max_retry_count=100, retriable_codes=[grpc.StatusCode.UNAVAILABLE], add_retry_count_to_header=True) ch = grpc.intercept_channel(channel, interceptor) client = zone_service_pb2_grpc.ZoneServiceStub(ch) with pytest.raises(grpc.RpcError) as e: client.Get(zone_service_pb2.GetZoneRequest(zone_id="id")) assert e.value.code() == grpc.StatusCode.UNAVAILABLE assert not service.error server.stop(0)
def test_infinite_retries_deadline_and_backoff(backoff): service = _AlwaysUnavailable() server = grpc_server(service.handler) with default_channel() as channel: interceptor = RetryInterceptor(max_retry_count=-1, retriable_codes=[grpc.StatusCode.UNAVAILABLE], add_retry_count_to_header=True, back_off_func=backoff) ch = grpc.intercept_channel(channel, interceptor) client = zone_service_pb2_grpc.ZoneServiceStub(ch) with pytest.raises(grpc.RpcError) as e: client.Get(zone_service_pb2.GetZoneRequest(zone_id="id"), timeout=5) assert e.value.code() == grpc.StatusCode.DEADLINE_EXCEEDED server.stop(0)
def test_idempotency_token_not_changed(): token = str(uuid.uuid4()) service = _TokenUnchanged(token) server = grpc_server(service.handler) with default_channel() as channel: interceptor = RetryInterceptor(max_retry_count=100, retriable_codes=[grpc.StatusCode.UNAVAILABLE], add_retry_count_to_header=True) ch = grpc.intercept_channel(channel, interceptor) client = zone_service_pb2_grpc.ZoneServiceStub(ch) with pytest.raises(grpc.RpcError) as e: client.Get(zone_service_pb2.GetZoneRequest(zone_id="id"), metadata=[("idempotency-key", token)]) assert e.value.code() == grpc.StatusCode.UNAVAILABLE assert not service.token_changed server.stop(0)
def test_per_call_timeout(): shutdown = Event() service = _NeverReturnsInTime(shutdown) server = grpc_server(service.handler) with default_channel() as channel: interceptor = RetryInterceptor(max_retry_count=10, retriable_codes=[grpc.StatusCode.UNAVAILABLE], per_call_timeout=1, add_retry_count_to_header=True) ch = grpc.intercept_channel(channel, interceptor) client = zone_service_pb2_grpc.ZoneServiceStub(ch) with pytest.raises(grpc.RpcError) as e: client.Get(zone_service_pb2.GetZoneRequest(zone_id="id")) assert e.value.code() == grpc.StatusCode.DEADLINE_EXCEEDED shutdown.set() server.stop(1)