@Test
  public void originDcNotFoundNoTerminateEarlyTest() {
    initialize();
    originatingDcName = datanodes.get(datanodes.size() - 1).getDatacenterName();

    Properties props = new Properties();
    props.setProperty(RouterConfig.ROUTER_GET_SUCCESS_TARGET, Integer.toString(1));
    props.setProperty(RouterConfig.ROUTER_GET_REQUEST_PARALLELISM, Integer.toString(3));
    props.setProperty(RouterConfig.ROUTER_OPERATION_TRACKER_TERMINATE_ON_NOT_FOUND_ENABLED, Boolean.toString(false));
    OperationTracker ot = getOperationTracker(props, true, 3, RouterOperation.GetBlobOperation, true, false);

    sendRequests(ot, 3, false);
    assertEquals("Should have 3 replicas", 3, inflightReplicas.size());
    for (int i = 0; i < 3; i++) {
      ReplicaId replica = inflightReplicas.poll();
      // fail first 3 requests to local replicas
      assertEquals("Should be local DC name", localDcName, replica.getDataNodeId().getDatacenterName());
      ot.onResponse(replica, TrackedRequestFinalState.NOT_FOUND);
    }
    assertFalse("Operation should have not succeeded", ot.hasSucceeded());
    assertFalse("Operation should have not failed on NOT_FOUND", ot.hasFailedOnNotFound());
    assertFalse("Operation should not be done", ot.isDone());

    sendRequests(ot, 3, false);
    assertEquals("Should have 3 replicas", 3, inflightReplicas.size());
    // Send three not found response from originating dc, it should not terminate the operation.
    for (int i = 0; i < 3; i++) {
      ReplicaId replica = inflightReplicas.poll();
      // fail first 3 requests to originating dc replicas
      ot.onResponse(replica, TrackedRequestFinalState.NOT_FOUND);
      assertEquals("Should be originatingDcName DC", originatingDcName, replica.getDataNodeId().getDatacenterName());
    }
    assertFalse("Operation should have not succeeded", ot.hasSucceeded());
    assertTrue("Operation should have failed on NOT_FOUND", ot.hasFailedOnNotFound());
    assertFalse("Operation should not be done", ot.isDone());

    // fail next 6 requests to non local/originating dc replicas
    sendRequests(ot, 3, false);
    assertEquals("Should have 3 replicas", 3, inflightReplicas.size());
    for (int i = 0; i < 3; i++) {
      ReplicaId replica = inflightReplicas.poll();
      ot.onResponse(replica, TrackedRequestFinalState.NOT_FOUND);
    }
    assertFalse("Operation should have not succeeded", ot.hasSucceeded());
    assertTrue("Operation should not have failed on NOT_FOUND", ot.hasFailedOnNotFound());
    assertFalse("Operation should not be done", ot.isDone());

    sendRequests(ot, 3, false);
    assertEquals("Should have 3 replicas", 3, inflightReplicas.size());
    for (int i = 0; i < 3; i++) {
      ReplicaId replica = inflightReplicas.poll();
      ot.onResponse(replica, TrackedRequestFinalState.NOT_FOUND);
    }

    // Operation should be done now and hasFailedOnNotFound() should have returned true.
    assertFalse("Operation should have not succeeded", ot.hasSucceeded());
    assertTrue("Operation should have failed on NOT_FOUND", ot.hasFailedOnNotFound());
    assertTrue("Operation should be done", ot.isDone());
  }
Test the case when terminate on not found is disabled, operation is completed only after receiving responses from all
colos.
ambry-router/src/test/java/com/github/ambry/router/OperationTrackerTest.java