@Test
  public void testHostFullAuto() throws Exception {
    // For aggregated view, it will always return false
    assumeTrue(!useComposite && !useAggregatedView && fullAutoCompatible);
    HelixClusterManager helixClusterManager = (HelixClusterManager) clusterManager;
    verifyInitialClusterChanges(helixClusterManager, helixCluster, helixDcs);

    // By default, all the hosts are not in FULL_AUTO mode.
    List<DataNode> allLocalDcDataNodes = testHardwareLayout.getAllDataNodesFromDc(localDc);
    for (DataNode dataNode : allLocalDcDataNodes) {
      assertFalse("By default, local node should not on FULL_AUTO",
          helixClusterManager.isDataNodeInFullAutoMode(dataNode));
    }
    List<DataNode> allRemoteDcDataNodes = testHardwareLayout.getAllDataNodesFromDc(remoteDc);
    for (DataNode dataNode : allRemoteDcDataNodes) {
      try {
        helixClusterManager.isDataNodeInFullAutoMode(dataNode);
        fail("By default, remote node should throw an exception");
      } catch (IllegalArgumentException e) {
      }
    }

    // Should have only one Resource when bootup
    List<String> resourceNames = helixCluster.getResources(localDc);
    assertEquals("Should only have one resource when bootup", 1, resourceNames.size());
    String resourceName = resourceNames.get(0);
    String totalInstanceMetricName =
        MetricRegistry.name(HelixClusterManager.class, "Resource_" + resourceName + "_TotalInstanceCount");
    // Make sure that we don't have any FULL AUTO related metrics
    MetricRegistry registry = helixClusterManager.getMetricRegistry();
    assertFalse(registry.getGauges().keySet().contains(totalInstanceMetricName));

    // Update the IdealState to CUSTOMIZED mode, this would keep all local data node as they were.
    IdealState idealState = helixCluster.getResourceIdealState(resourceName, localDc);
    // Update idealState here would impact the IdealState in the helixCluster since they reference to the same object
    idealState.setRebalanceMode(IdealState.RebalanceMode.CUSTOMIZED);
    helixCluster.refreshIdealState();
    allLocalDcDataNodes = testHardwareLayout.getAllDataNodesFromDc(localDc);
    for (DataNode dataNode : allLocalDcDataNodes) {
      assertFalse("Customized mode, local node should not on FULL_AUTO",
          helixClusterManager.isDataNodeInFullAutoMode(dataNode));
    }
    assertFalse(registry.getGauges().keySet().contains(totalInstanceMetricName));

    // Now update resource to have a tag
    final String instanceGroupTag = "TAG_1000000";
    idealState.setInstanceGroupTag(instanceGroupTag);
    helixCluster.refreshIdealState();
    for (DataNode dataNode : allLocalDcDataNodes) {
      assertFalse("Should not be in FULL_AUTO since IdealState is not on FULL_AUTO and instances don't have tags",
          helixClusterManager.isDataNodeInFullAutoMode(dataNode));
    }
    assertFalse(registry.getGauges().keySet().contains(totalInstanceMetricName));

    // Now update data node to have the same tag
    for (DataNode dataNode : allLocalDcDataNodes) {
      String instanceName = ClusterMapUtils.getInstanceName(dataNode.getHostname(), dataNode.getPort());
      InstanceConfig instanceConfig =
          helixCluster.getHelixAdminFromDc(localDc).getInstanceConfig(helixCluster.getClusterName(), instanceName);
      instanceConfig.addTag(instanceGroupTag);
      assertFalse("Should not be in FULL_AUTO since IdealState is not on FULL_AUTO",
          helixClusterManager.isDataNodeInFullAutoMode(dataNode));
    }
    assertFalse(registry.getGauges().keySet().contains(totalInstanceMetricName));

    // Now update resource to FULL_AUTO
    idealState.setRebalanceMode(IdealState.RebalanceMode.FULL_AUTO);
    helixCluster.refreshIdealState();
    for (DataNode dataNode : allLocalDcDataNodes) {
      assertTrue("Should be in FULL_AUTO mode", helixClusterManager.isDataNodeInFullAutoMode(dataNode));
    }
    assertTrue(registry.getGauges().keySet().contains(totalInstanceMetricName));

    // Now update data node to have another tag
    for (DataNode dataNode : allLocalDcDataNodes) {
      String instanceName = ClusterMapUtils.getInstanceName(dataNode.getHostname(), dataNode.getPort());
      InstanceConfig instanceConfig =
          helixCluster.getHelixAdminFromDc(localDc).getInstanceConfig(helixCluster.getClusterName(), instanceName);
      instanceConfig.addTag(instanceGroupTag + "_another_one");
      assertFalse("Instance has multiple tags", helixClusterManager.isDataNodeInFullAutoMode(dataNode));
    }

    // Now update data node to remove the extra tag
    for (DataNode dataNode : allLocalDcDataNodes) {
      String instanceName = ClusterMapUtils.getInstanceName(dataNode.getHostname(), dataNode.getPort());
      InstanceConfig instanceConfig =
          helixCluster.getHelixAdminFromDc(localDc).getInstanceConfig(helixCluster.getClusterName(), instanceName);
      instanceConfig.removeTag(instanceGroupTag + "_another_one");
      assertTrue("Should be on FULL_AUTO", helixClusterManager.isDataNodeInFullAutoMode(dataNode));
    }

    // Now update data node to remove the tag and add a new tag
    for (DataNode dataNode : allLocalDcDataNodes) {
      String instanceName = ClusterMapUtils.getInstanceName(dataNode.getHostname(), dataNode.getPort());
      InstanceConfig instanceConfig =
          helixCluster.getHelixAdminFromDc(localDc).getInstanceConfig(helixCluster.getClusterName(), instanceName);
      instanceConfig.removeTag(instanceGroupTag);
      instanceConfig.addTag("random_tag");
      assertFalse("Instance has random tag", helixClusterManager.isDataNodeInFullAutoMode(dataNode));
    }

    // Now update data node to has the same tag but switch resource back to semi auto
    idealState.setRebalanceMode(IdealState.RebalanceMode.SEMI_AUTO);
    helixCluster.refreshIdealState();
    assertFalse(registry.getGauges().keySet().contains(totalInstanceMetricName));
    for (DataNode dataNode : allLocalDcDataNodes) {
      String instanceName = ClusterMapUtils.getInstanceName(dataNode.getHostname(), dataNode.getPort());
      InstanceConfig instanceConfig =
          helixCluster.getHelixAdminFromDc(localDc).getInstanceConfig(helixCluster.getClusterName(), instanceName);
      instanceConfig.removeTag("random_tag");
      instanceConfig.addTag(instanceGroupTag);
      assertFalse("Resource is in SEMI AUTO", helixClusterManager.isDataNodeInFullAutoMode(dataNode));
    }
  }
Test {@link ClusterMap#isDataNodeInFullAutoMode}.
@throws Exception
ambry-clustermap/src/test/java/com/github/ambry/clustermap/HelixClusterManagerTest.java