@Test
  public void simpleOperationTrackerTest() throws Exception {
    RouterConfig oldRouterConfig = routerConfig;
    NonBlockingRouter oldRouter = router;
    UndeleteManager oldUndeleteManager = undeleteManager;

    Properties props = getNonBlockingRouterProperties(DEFAULT_PARALLELISM);
    props.setProperty(RouterConfig.ROUTER_UNDELETE_OPERATION_TRACKER_TYPE,
        SimpleOperationTracker.class.getSimpleName());
    routerConfig = new RouterConfig(new VerifiableProperties(props));
    router =
        new NonBlockingRouter(routerConfig, metrics, networkClientFactory, new LoggingNotificationSystem(), clusterMap,
            null, null, null, new InMemAccountService(false, true), time, MockClusterMap.DEFAULT_PARTITION_CLASS, null);
    undeleteManager = new UndeleteManager(clusterMap, new ResponseHandler(clusterMap), new LoggingNotificationSystem(),
        accountService, routerConfig, metrics, time, router);

    try {
      // Case 1: simple router test
      String blobId = blobIds.get(0);
      deleteBlobInAllServer(blobId);
      // Undelete requires global quorum, so we have to make sure all the mock servers received a delete.
      router.undeleteBlob(blobId, UNDELETE_SERVICE_ID).get(AWAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
      verifyUndeleteWithSimpleOperationTracker(blobId);

      // Case 2: simple manager test
      blobId = blobIds.get(1);
      deleteBlobInAllServer(blobId);
      executeOpAndVerifyWithSimpleOperationTracker(Collections.singleton(blobId), null);
      executeOpAndVerifyWithSimpleOperationTracker(Collections.singleton(blobId), null);

      // Case 3: Blob_Not_Deleted error
      blobId = blobIds.get(3);
      deleteBlobInAllServer(blobId);
      List<MockServer> localServers = serverLayout.getMockServers()
          .stream()
          .filter(server -> server.getDataCenter().equals(LOCAL_DC))
          .collect(Collectors.toList());
      localServers.get(0).setServerErrorForAllRequests(ServerErrorCode.BlobNotDeleted);
      localServers.get(1).setServerErrorForAllRequests(ServerErrorCode.BlobAlreadyUndeleted);

      FutureResult<Void> future = new FutureResult<>();
      router.currentOperationsCount.addAndGet(1);
      List<String> chunkIds = Collections.singletonList(blobId);
      undeleteManager.submitUndeleteOperation(chunkIds.get(0), chunkIds.subList(1, chunkIds.size()), UNDELETE_SERVICE_ID,
          future, future::done, quotaChargeCallback);
      sendRequestsGetResponse(future, undeleteManager, false, false);
      future.get(1, TimeUnit.MILLISECONDS);

      router.close();
    } finally {
      routerConfig = oldRouterConfig;
      router = oldRouter;
      undeleteManager = oldUndeleteManager;
    }
  }
Test when the operation tracker is simple operation tracker
ambry-router/src/test/java/com/github/ambry/router/UndeleteManagerTest.java