@Test
  public void testRetryFileSize() throws IOException {
    GcsOptions pipelineOptions = gcsOptionsWithTestCredential();
    GcsUtil gcsUtil = pipelineOptions.getGcsUtil();

    Storage mockStorage = Mockito.mock(Storage.class);
    gcsUtil.setStorageClient(mockStorage);

    Storage.Objects mockStorageObjects = Mockito.mock(Storage.Objects.class);
    Storage.Objects.Get mockStorageGet = Mockito.mock(Storage.Objects.Get.class);

    BackOff mockBackOff = new AttemptBoundedExponentialBackOff(3, 200);

    when(mockStorage.objects()).thenReturn(mockStorageObjects);
    when(mockStorageObjects.get("testbucket", "testobject")).thenReturn(mockStorageGet);
    when(mockStorageGet.execute())
        .thenThrow(new SocketTimeoutException("SocketException"))
        .thenThrow(new SocketTimeoutException("SocketException"))
        .thenReturn(new StorageObject().setSize(BigInteger.valueOf(1000)));

    assertEquals(
        1000,
        gcsUtil.fileSize(
            GcsPath.fromComponents("testbucket", "testobject"),
            mockBackOff,
            new FastNanoClockAndSleeper()));
    assertEquals(mockBackOff.nextBackOffMillis(), BackOff.STOP);
  }
 /**
  * Sleep and/or determine if the backoff has timed out.
  *
  * @param backoff
  * @return RetryState indicating the current state of the retry logic.
  * @throws IOException in some cases from {@link BackOff#nextBackOffMillis()}
  */
 protected RetryState getRetryState(BackOff backoff) throws IOException {
   long nextBackOffMillis = backoff.nextBackOffMillis();
   if (nextBackOffMillis == BackOff.STOP) {
     logger.warn(
         "Exhausted the number of retries for credentials refresh after "
             + this.retryOptions.getMaxElaspedBackoffMillis()
             + " milliseconds.");
     return RetryState.RetriesExhausted;
   }
   try {
     sleeper.sleep(nextBackOffMillis);
     // Try to perform another call.
     return RetryState.PerformRetry;
   } catch (InterruptedException e) {
     logger.warn("Interrupted while trying to refresh credentials.");
     Thread.interrupted();
     // If the thread is interrupted, terminate immediately.
     return RetryState.Interrupted;
   }
 }