@VisibleForTesting
  @Nullable
  GoogleMediaItem getGoogleMediaItem(String photoIdempotentId, String photoDataId,
      String photoName, TokensAndUrlAuthData authData) throws IOException, InvalidTokenException, PermissionDeniedException {
    if (retryingExecutor == null || !enableRetrying) {
      return getOrCreatePhotosInterface(authData).getMediaItem(photoDataId);
    }

    try {
      GoogleMediaItem googleMediaItem = retryingExecutor.executeAndSwallowIOExceptions(
          photoIdempotentId, photoName,
          () -> getOrCreatePhotosInterface(authData).getMediaItem(photoDataId)
      );
      return googleMediaItem;
    } catch (Exception e) {
      monitor.info(() -> format("Retry exception encountered while fetching a photo: %s", e));
    }
    return null;
  }
@Test
  public void testGetGoogleMediaItemFailed() throws IOException, InvalidTokenException, PermissionDeniedException {
    String mediaItemID = "media_id";
    when(photosInterface.getMediaItem(mediaItemID)).thenThrow(IOException.class);

    long start = System.currentTimeMillis();
    assertThat(retryingGoogleMediaExporter.getGoogleMediaItem(mediaItemID, mediaItemID, mediaItemID, authData)).isNull();
    long end = System.currentTimeMillis();

    // If retrying occurred, then the retry_interval must have been waited at least max_attempts
    // amount of times.
    assertThat(end - start).isAtLeast(RETRY_INTERVAL_MILLIS * RETRY_MAX_ATTEMPTS);
    assertThat(retryingExecutor.getErrors().size()).isEqualTo(1);
    assertThat(retryingExecutor.getErrors().stream().findFirst().toString()).contains("IOException");


    start = System.currentTimeMillis();
    assertThrows(IOException.class, () -> googleMediaExporter.getGoogleMediaItem(mediaItemID, mediaItemID, mediaItemID, authData));
    end = System.currentTimeMillis();

    assertThat(end - start).isLessThan(RETRY_INTERVAL_MILLIS * RETRY_MAX_ATTEMPTS);
  }