private void executeOpAndVerify(Collection<String> ids, RouterErrorCode expectedErrorCode, boolean advanceTime,
      boolean withSimpleOperationTracker) throws Exception {
    FutureResult<Void> future = new FutureResult<>();
    router.currentOperationsCount.addAndGet(ids.size() == 1 ? 1 : ids.size() - 1);
    List<String> chunkIds = new ArrayList<>(ids);
    undeleteManager.submitUndeleteOperation(chunkIds.get(0), chunkIds.subList(1, chunkIds.size()), UNDELETE_SERVICE_ID,
        future, future::done, quotaChargeCallback);
    sendRequestsGetResponse(future, undeleteManager, advanceTime, false);
    if (expectedErrorCode == null) {
      // Should return no error
      future.get(1, TimeUnit.MILLISECONDS);
      for (String blobId : ids) {
        if (withSimpleOperationTracker) {
          verifyUndeleteWithSimpleOperationTracker(blobId);
        } else {
          verifyUndelete(blobId);
        }
      }
    } else {
      try {
        future.get(1, TimeUnit.MILLISECONDS);
        fail("Operation should fail, exception is expected");
      } catch (Exception e) {
        assertEquals("RouterErrorCode should be " + expectedErrorCode + " (future)", expectedErrorCode,
            ((RouterException) e.getCause()).getErrorCode());
      }
    }
  }
Generates {@link Properties} that includes initial configuration.
@param parallelism undelete request parallelism.
@return Properties
ambry-router/src/test/java/com/github/ambry/router/UndeleteManagerTest.java