@Test
  public void testHostFullAutoWithMultipleTags() throws Exception {
    // For aggregated view, it will always return false
    assumeTrue(!useComposite && !useAggregatedView);

    // Create a new helix cluster with "maxPartitionsInOneResource" set to 2 when creating MockHelixCluster below so
    // that there are atleast 2 resources created in helix.
    clusterManager.close();
    metricRegistry = new MetricRegistry();
    String staticClusterName = "TestOnly";
    File tempDir = Files.createTempDirectory("helixClusterManagerTest").toFile();
    tempDir.deleteOnExit();
    String tempDirPath = tempDir.getAbsolutePath();
    String testHardwareLayoutPath = tempDirPath + File.separator + "hardwareLayoutTest.json";
    String testPartitionLayoutPath = tempDirPath + File.separator + "partitionLayoutTest.json";
    String testZkLayoutPath = tempDirPath + File.separator + "zkLayoutPath.json";
    // initialize test hardware layout and partition layout, create mock helix cluster for testing.
    TestHardwareLayout testHardwareLayout = constructInitialHardwareLayoutJSON(staticClusterName);
    TestPartitionLayout testPartitionLayout = constructInitialPartitionLayoutJSON(testHardwareLayout, 3, localDc);
    JSONObject zkJson = constructZkLayoutJSON(dcsToZkInfo.values());
    Utils.writeJsonObjectToFile(zkJson, testZkLayoutPath);
    Utils.writeJsonObjectToFile(testHardwareLayout.getHardwareLayout().toJSONObject(), testHardwareLayoutPath);
    Utils.writeJsonObjectToFile(testPartitionLayout.getPartitionLayout().toJSONObject(), testPartitionLayoutPath);
    MockHelixCluster helixCluster =
        new MockHelixCluster("AmbryTest-", testHardwareLayoutPath, testPartitionLayoutPath, testZkLayoutPath, localDc,
            useAggregatedView, 2, 0);

    HelixClusterManager helixClusterManager = new HelixClusterManager(clusterMapConfig, selfInstanceName,
        new MockHelixManagerFactory(helixCluster, null, null, useAggregatedView), metricRegistry);

    verifyInitialClusterChanges(helixClusterManager, helixCluster, helixDcs);

    List<DataNode> allLocalDcDataNodes = testHardwareLayout.getAllDataNodesFromDc(localDc);

    // Should have more than one Resource when bootup
    List<String> resourceNames = helixCluster.getResources(localDc);
    assertEquals("Should have more than one resource when bootup", 2, resourceNames.size());
    String resource1 = resourceNames.get(0);
    String resource2 = resourceNames.get(1);

    // 1. Verify data nodes with multiple resource tags are in Full-Auto if all resources are in Full Auto
    IdealState idealStateForResource1 = helixCluster.getResourceIdealState(resource1, localDc);
    IdealState idealStateForResource2 = helixCluster.getResourceIdealState(resource2, localDc);

    // Add a tag for each resource
    final String tag1 = "TAG_1000000";
    final String tag2 = "TAG_1000001";
    idealStateForResource1.setInstanceGroupTag(tag1);
    idealStateForResource2.setInstanceGroupTag(tag2);

    // Add both tags to data nodes
    for (DataNode dataNode : allLocalDcDataNodes) {
      String instanceName = ClusterMapUtils.getInstanceName(dataNode.getHostname(), dataNode.getPort());
      InstanceConfig instanceConfig =
          helixCluster.getHelixAdminFromDc(localDc).getInstanceConfig(helixCluster.getClusterName(), instanceName);
      instanceConfig.addTag(tag1);
      instanceConfig.addTag(tag2);
    }

    // Update resource to FULL_AUTO
    idealStateForResource1.setRebalanceMode(IdealState.RebalanceMode.FULL_AUTO);
    idealStateForResource2.setRebalanceMode(IdealState.RebalanceMode.FULL_AUTO);

    // Refresh ideal state
    helixCluster.refreshIdealState();

    // All the data nodes must be in Full Auto
    for (DataNode dataNode : allLocalDcDataNodes) {
      assertTrue("Should be in FULL_AUTO mode", helixClusterManager.isDataNodeInFullAutoMode(dataNode));
    }

    // 2. Verify data nodes is in SEMI_AUTO if one the resource tags are in SEMI_AUTO
    idealStateForResource2 = helixCluster.getResourceIdealState(resource2, localDc);
    idealStateForResource2.setRebalanceMode(IdealState.RebalanceMode.SEMI_AUTO);
    helixCluster.refreshIdealState();
    // All the data nodes must be in Full Auto
    for (DataNode dataNode : allLocalDcDataNodes) {
      assertFalse("Should be in SEMI_AUTO mode since resource 2 is in SEMI_AUTO",
          helixClusterManager.isDataNodeInFullAutoMode(dataNode));
    }

    // 3. Verify data node is still in FULL_AUTO if the SEMI_AUTO resources are present in /AdminConfigs/FullAutoMigration
    String addr = "localhost:" + dcsToZkInfo.get(localDc).getPort();
    HelixPropertyStore<ZNRecord> propertyStore =
        CommonUtils.createHelixPropertyStore(addr, "/" + helixCluster.getClusterName() + "/" + PROPERTYSTORE_STR, null);
    ZNRecord zNRecord = new ZNRecord(FULL_AUTO_MIGRATION_STR);
    zNRecord.setListField(RESOURCES_STR, Collections.singletonList(resource2));
    propertyStore.set(FULL_AUTO_MIGRATION_ZNODE_PATH, zNRecord, AccessOption.PERSISTENT);
    helixCluster.refreshIdealState();
    for (DataNode dataNode : allLocalDcDataNodes) {
      assertTrue("Resource should considered as FULL AUTO while it is rolling back to help with local disk selection",
          helixClusterManager.isDataNodeInFullAutoMode(dataNode, true));
      assertFalse("Resource should considered NOT IN FULL AUTO when not checking the property store",
          helixClusterManager.isDataNodeInFullAutoMode(dataNode, false));
    }
  }
Test {@link ClusterMap#isDataNodeInFullAutoMode}.
@throws Exception
ambry-clustermap/src/test/java/com/github/ambry/clustermap/HelixClusterManagerTest.java