@Override
  public Future<RestResponse> restRequest(RestRequest request)
  {
    return restRequest(request, new RequestContext());
  }
@Test(retryAnalyzer = ThreeRetries.class) // Known to be flaky in CI
  public void testRestRetryExceedsClientRetryRatio() throws Exception
  {
    SimpleLoadBalancer balancer = prepareLoadBalancer(Arrays.asList("http://test.linkedin.com/retry1", "http://test.linkedin.com/good"),
        HttpClientFactory.DEFAULT_MAX_CLIENT_REQUEST_RETRY_RATIO);
    SettableClock clock = new SettableClock();
    DynamicClient dynamicClient = new DynamicClient(balancer, null);
    RetryClient client = new RetryClient(
        dynamicClient,
        balancer,
        D2ClientConfig.DEFAULT_RETRY_LIMIT,
        RetryClient.DEFAULT_UPDATE_INTERVAL_MS,
        RetryClient.DEFAULT_AGGREGATED_INTERVAL_NUM,
        clock,
        true,
        false);
    URI uri1 = URI.create("d2://retryService1?arg1=empty&arg2=empty");
    RestRequest restRequest1 = new RestRequestBuilder(uri1).build();

    URI uri2 = URI.create("d2://retryService2?arg1=empty&arg2=empty");
    RestRequest restRequest2 = new RestRequestBuilder(uri2).build();

    // This request will be retried and route to the good host
    DegraderTrackerClientTest.TestCallback<RestResponse> restCallback = new DegraderTrackerClientTest.TestCallback<>();
    client.restRequest(restRequest1, restCallback);

    assertNull(restCallback.e);
    assertNotNull(restCallback.t);

    // This request will not be retried because the retry ratio is exceeded
    clock.addDuration(RetryClient.DEFAULT_UPDATE_INTERVAL_MS);

    restCallback = new DegraderTrackerClientTest.TestCallback<>();
    client.restRequest(restRequest1, restCallback);

    assertNull(restCallback.t);
    assertNotNull(restCallback.e);
    assertTrue(restCallback.e.getMessage().contains("Data not available"));

    // If the client sends request to a different service endpoint, the retry ratio should not interfere
    restCallback = new DegraderTrackerClientTest.TestCallback<>();
    client.restRequest(restRequest2, restCallback);

    assertNull(restCallback.e);
    assertNotNull(restCallback.t);

    // After 5s interval, retry counter is reset and this request will be retried again
    clock.addDuration(RetryClient.DEFAULT_UPDATE_INTERVAL_MS * RetryClient.DEFAULT_AGGREGATED_INTERVAL_NUM);

    restCallback = new DegraderTrackerClientTest.TestCallback<>();
    client.restRequest(restRequest1, restCallback);

    assertNull(restCallback.e);
    assertNotNull(restCallback.t);
  }