private static boolean canSatisfyConstraints(ApplicationId appId,
      PlacementConstraint constraint, SchedulerNode node,
      AllocationTagsManager atm,
      Optional<DiagnosticsCollector> dcOpt)
      throws InvalidAllocationTagsQueryException {
    if (constraint == null) {
      LOG.debug("Constraint is found empty during constraint validation for"
          + " app:{}", appId);
      return true;
    }

    // If this is a single constraint, transform to SingleConstraint
    SingleConstraintTransformer singleTransformer =
        new SingleConstraintTransformer(constraint);
    constraint = singleTransformer.transform();
    AbstractConstraint sConstraintExpr = constraint.getConstraintExpr();

    // TODO handle other type of constraints, e.g CompositeConstraint
    if (sConstraintExpr instanceof SingleConstraint) {
      SingleConstraint single = (SingleConstraint) sConstraintExpr;
      return canSatisfySingleConstraint(appId, single, node, atm, dcOpt);
    } else if (sConstraintExpr instanceof And) {
      And and = (And) sConstraintExpr;
      return canSatisfyAndConstraint(appId, and, node, atm, dcOpt);
    } else if (sConstraintExpr instanceof Or) {
      Or or = (Or) sConstraintExpr;
      return canSatisfyOrConstraint(appId, or, node, atm, dcOpt);
    } else {
      throw new InvalidAllocationTagsQueryException(
          "Unsupported type of constraint: "
              + sConstraintExpr.getClass().getSimpleName());
    }
  }
@Test
  public void testInterAppConstriantsByAppTag()
      throws InvalidAllocationTagsQueryException {

    ApplicationId application1 = BuilderUtils.newApplicationId(1000, 123);
    ApplicationId application2 = BuilderUtils.newApplicationId(1001, 124);

    // app1: test-tag
    // app2: N/A
    RMContext mockedContext = Mockito.spy(rmContext);
    ConcurrentMap<ApplicationId, RMApp> allApps = new ConcurrentHashMap<>();
    allApps.put(application1, new MockRMApp(123, 1000,
        RMAppState.NEW, "userA", ImmutableSet.of("test-tag")));
    allApps.put(application2, new MockRMApp(124, 1001,
        RMAppState.NEW, "userA", ImmutableSet.of("")));
    when(mockedContext.getRMApps()).thenReturn(allApps);

    AllocationTagsManager tm = new AllocationTagsManager(mockedContext);
    PlacementConstraintManagerService pcm =
        new MemoryPlacementConstraintManager();
    mockedContext.setAllocationTagsManager(tm);
    mockedContext.setPlacementConstraintManager(pcm);

    // Register App1 with anti-affinity constraint map.
    RMNode n0r1 = rmNodes.get(0);
    RMNode n1r1 = rmNodes.get(1);
    RMNode n2r2 = rmNodes.get(2);
    RMNode n3r2 = rmNodes.get(3);

    /**
     * Place container:
     *  n0: app1/hbase-m(1)
     *  n1: ""
     *  n2: app1/hbase-m(1)
     *  n3: ""
     */
    tm.addContainer(n0r1.getNodeID(),
        newContainerId(application1), ImmutableSet.of("hbase-m"));
    tm.addContainer(n2r2.getNodeID(),
        newContainerId(application1), ImmutableSet.of("hbase-m"));

    SchedulerNode schedulerNode0 = newSchedulerNode(n0r1.getHostName(),
        n0r1.getRackName(), n0r1.getNodeID());
    SchedulerNode schedulerNode1 = newSchedulerNode(n1r1.getHostName(),
        n1r1.getRackName(), n1r1.getNodeID());
    SchedulerNode schedulerNode2 = newSchedulerNode(n2r2.getHostName(),
        n2r2.getRackName(), n2r2.getNodeID());
    SchedulerNode schedulerNode3 = newSchedulerNode(n3r2.getHostName(),
        n3r2.getRackName(), n3r2.getNodeID());

    TargetApplicationsNamespace namespace =
        new TargetApplicationsNamespace.AppTag("test-tag");
    Map<Set<String>, PlacementConstraint> constraintMap = new HashMap<>();
    PlacementConstraint constraint2 = PlacementConstraints
        .targetNotIn(NODE, allocationTagWithNamespace(namespace.toString(),
            "hbase-m"))
        .build();
    Set<String> srcTags2 = ImmutableSet.of("app2");
    constraintMap.put(srcTags2, constraint2);

    pcm.registerApplication(application2, constraintMap);

    // Anti-affinity with app-tag/test-tag/hbase-m,
    // app1 has tag "test-tag" so the constraint is equally to work on app1
    // onto n1 and n3 as they don't have "hbase-m" from app1.
    Assert.assertFalse(PlacementConstraintsUtil.canSatisfyConstraints(
        application2, createSchedulingRequest(srcTags2),
        schedulerNode0, pcm, tm));
    Assert.assertTrue(PlacementConstraintsUtil.canSatisfyConstraints(
        application2, createSchedulingRequest(srcTags2),
        schedulerNode1, pcm, tm));
    Assert.assertFalse(PlacementConstraintsUtil.canSatisfyConstraints(
        application2, createSchedulingRequest(srcTags2),
        schedulerNode2, pcm, tm));
    Assert.assertTrue(PlacementConstraintsUtil.canSatisfyConstraints(
        application2, createSchedulingRequest(srcTags2),
        schedulerNode3, pcm, tm));

    pcm.unregisterApplication(application1);
    pcm.unregisterApplication(application2);
  }