@Test
  public void testRecoveryReplication() throws StoreException {
    int numPages = (NUM_BLOBS/AZURE_BLOB_STORAGE_MAX_RESULTS_PER_PAGE)
        + (NUM_BLOBS % AZURE_BLOB_STORAGE_MAX_RESULTS_PER_PAGE == 0 ? 0 : 1)
        + 10; // Extra iter to test end-of-partition
    ReplicaThread recoveryThread = createRecoveryThread(createRecoveryClient(null));
    // Iterate N times to retrieve all blobIDs from cloud and store to disk
    IntStream.rangeClosed(1, numPages).forEach(i -> recoveryThread.replicate());
    // Get local blobs
    StoreInfo localBlobs = localStore.get(
        azureBlobs.values().stream().map(MessageInfo::getStoreKey).collect(Collectors.toList()),
        EnumSet.noneOf(StoreGetOptions.class));
    // Assert we recovered all blobIds intact
    assertTrue(((RecoveryToken) remoteStore.getToken()).isEndOfPartition());
    assertEquals(azureBlobs.size(), localBlobs.getMessageReadSetInfo().size());
    IntStream.range(0, localBlobs.getMessageReadSetInfo().size()).forEach(i -> {
      // Match metadata
      MessageInfo localInfo = localBlobs.getMessageReadSetInfo().get(i);
      String blobIdStr = localInfo.getStoreKey().getID();
      if (!azureBlobs.get(blobIdStr).equals(localInfo)) {
        logger.error("Azure blob metadata for blob-%s %s does not match that in local disk, expected = {}, found = {}",
            i, blobIdStr, azureBlobs.get(blobIdStr), localInfo);
        fail("Metadata mismatch");
      }
      // Match data
      try {
        localBlobs.getMessageReadSet().doPrefetch(i, 0, BLOB_SIZE);
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
      ByteBuffer localData = ByteBuffer.wrap(new byte[(int) BLOB_SIZE]);
      localBlobs.getMessageReadSet().getPrefetchedData(i).readBytes(localData);
      if (!Arrays.equals(BLOB_DATA.getBytes(), localData.array())) {
        logger.error("Azure blob data for blob-%s %s does not match that in local disk, expected = {}, found = {}",
            i, blobIdStr, BLOB_DATA, new String(localData.array()));
        fail("Data mismatch");
      }
    });
  }
Tests that replication code downloads all blobs from Azurite
@throws StoreException
ambry-cloud/src/test/java/com/github/ambry/cloud/RecoveryNetworkClientTest.java