@Test
  public void concurrentBatchDeleteTestOnSameBlobList() throws Exception {
    final List<MockId> idsToDelete = put(5, PUT_RECORD_SIZE, Utils.Infinite_Time);
    assertNotNull(idsToDelete);
    int count = 2;
    long logEndOffsetBeforeDelete = store.getLogEndOffsetInBytes();
    long indexEndOffsetBeforeDelete = store.getSizeInBytes();
    ExecutorService executorService = Executors.newFixedThreadPool(count);
    try {
      List<Future<StoreBatchDeleteInfo>> futures = new ArrayList<>();
      for (int i = 0; i < count; i++) {
        futures.add(executorService.submit(() -> batchDelete(idsToDelete)));
      }
      int failedCount = 0;
      int succeededCount = 0;
      for (Future<StoreBatchDeleteInfo> future : futures) {
        try {
          StoreBatchDeleteInfo storeBatchDeleteInfo = future.get();
          succeededCount++;
          assertEquals(idsToDelete.size(), storeBatchDeleteInfo.getMessageErrorInfos().size());
        } catch (ExecutionException e) {
          failedCount++;
          assertTrue(e.getCause() instanceof StoreException);
          assertEquals(StoreErrorCodes.UnknownError, ((StoreException) e.getCause()).getErrorCode());
        }
      }

      assertEquals(1, succeededCount);
      assertEquals(count - 1, failedCount);
      long logEndOffsetAfterDelete = store.getLogEndOffsetInBytes();
      long indexEndOffsetAfterDelete = store.getSizeInBytes();
      assertEquals((long) DELETE_RECORD_SIZE * idsToDelete.size(), logEndOffsetAfterDelete - logEndOffsetBeforeDelete);
      assertEquals((long) DELETE_RECORD_SIZE * idsToDelete.size(), indexEndOffsetAfterDelete - indexEndOffsetBeforeDelete);
    } finally {
      executorService.shutdownNow();
    }
  }
Test when batch deleting the same list of blobs at the same time. Only one batch delete can go through and only
one operation's log and index record should be persisted.
@throws Exception
ambry-store/src/test/java/com/github/ambry/store/BlobStoreTest.java