public void setWriteTimeout(int writeTimeout) {
    this.writeTimeout = writeTimeout;
  }
@Test
  public void testRetryableErrorRetryEnoughTimes() throws IOException {
    List<MockLowLevelHttpResponse> responses = new ArrayList<>();
    final int retries = 10;

    // The underlying http library calls getStatusCode method of a response multiple times. For a
    // response, the method should return the same value. Therefore this test cannot rely on
    // `mockLowLevelResponse` variable that are reused across responses.
    when(mockLowLevelRequest.execute())
        .thenAnswer(
            new Answer<MockLowLevelHttpResponse>() {
              int n = 0;

              @Override
              public MockLowLevelHttpResponse answer(InvocationOnMock invocation) throws Throwable {
                MockLowLevelHttpResponse response = mock(MockLowLevelHttpResponse.class);
                responses.add(response);
                when(response.getStatusCode()).thenReturn(n++ < retries ? 503 : 9999);
                return response;
              }
            });

    Storage.Buckets.Get result = storage.buckets().get("test");
    try {
      result.executeUnparsed();
      fail();
    } catch (IOException e) {
    }

    verify(mockHttpResponseInterceptor).interceptResponse(any(HttpResponse.class));
    verify(mockLowLevelRequest, atLeastOnce()).addHeader(anyString(), anyString());
    verify(mockLowLevelRequest, times(retries + 1)).setTimeout(anyInt(), anyInt());
    verify(mockLowLevelRequest, times(retries + 1)).setWriteTimeout(anyInt());
    verify(mockLowLevelRequest, times(retries + 1)).execute();
    assertThat(responses, Matchers.hasSize(retries + 1));
    for (MockLowLevelHttpResponse response : responses) {
      verify(response, atLeastOnce()).getStatusCode();
    }
    expectedLogs.verifyWarn("performed 10 retries due to unsuccessful status codes");
  }