@Test
  public void testUpdateNodeInfoInCluster() throws Exception {
    // override some props for current test
    props.setProperty("clustermap.update.datanode.info", Boolean.toString(true));
    ClusterMapConfig clusterMapConfig = new ClusterMapConfig(new VerifiableProperties(props));
    HelixParticipant participant =
        new HelixParticipant(mock(HelixClusterManager.class), clusterMapConfig, new HelixFactory(),
            new MetricRegistry(), getDefaultZkConnectStr(clusterMapConfig), true);
    participant.markDisablePartitionComplete();
    // create InstanceConfig for local node. Also, put existing replica into sealed list
    String instanceName = ClusterMapUtils.getInstanceName("localhost", clusterMapConfig.clusterMapPort);
    HelixAdmin helixAdmin = participant.getHelixAdmin();
    DataNodeConfig dataNodeConfig = getDataNodeConfigInHelix(helixAdmin, instanceName);

    DataNodeConfig.DiskConfig diskConfig = dataNodeConfig.getDiskConfigs().values().iterator().next();
    String existingReplicaName = diskConfig.getReplicaConfigs().keySet().iterator().next();
    PartitionId correspondingPartition = testPartitionLayout.getPartitionLayout()
        .getPartitions(null)
        .stream()
        .filter(p -> p.toPathString().equals(existingReplicaName))
        .findFirst()
        .get();
    ReplicaId existingReplica = correspondingPartition.getReplicaIds()
        .stream()
        .filter(r -> r.getDataNodeId().getPort() == clusterMapConfig.clusterMapPort)
        .findFirst()
        .get();

    // generate exactly same config for comparison
    DataNodeConfig initialDataNodeConfig = deepCopyDataNodeConfig(dataNodeConfig);
    // 1. add existing replica's info to Helix should be no-op
    assertTrue("Adding existing replica's info should succeed",
        participant.updateDataNodeInfoInCluster(existingReplica, true));
    assertEquals("DataNodeConfig should stay unchanged", initialDataNodeConfig,
        getDataNodeConfigInHelix(helixAdmin, instanceName));
    // create two new replicas on the same disk of local node
    int currentPartitionCount = testPartitionLayout.getPartitionCount();
    Partition newPartition1 = new Partition(currentPartitionCount++, DEFAULT_PARTITION_CLASS, PartitionState.READ_WRITE,
        testPartitionLayout.replicaCapacityInBytes);
    Partition newPartition2 = new Partition(currentPartitionCount, DEFAULT_PARTITION_CLASS, PartitionState.READ_WRITE,
        testPartitionLayout.replicaCapacityInBytes);
    Disk disk = (Disk) existingReplica.getDiskId();
    // 2. add new partition2 (id = 10, replicaFromPartition2) to Helix
    ReplicaId replicaFromPartition2 = new Replica(newPartition2, disk, clusterMapConfig);
    assertTrue("Adding new replica info to Helix should succeed.",
        participant.updateDataNodeInfoInCluster(replicaFromPartition2, true));
    // verify new added replica (replicaFromPartition2) info is present in DataNodeConfig
    Thread.sleep(50);
    dataNodeConfig = getDataNodeConfigInHelix(helixAdmin, instanceName);
    verifyReplicaInfoInDataNodeConfig(dataNodeConfig, replicaFromPartition2, true);
    // 3. add new partition1 (replicaFromPartition1) into InstanceConfig
    ReplicaId replicaFromPartition1 = new Replica(newPartition1, disk, clusterMapConfig);
    assertTrue("Adding new replica info into InstanceConfig should succeed.",
        participant.updateDataNodeInfoInCluster(replicaFromPartition1, true));
    Thread.sleep(50);
    // verify new added replica (replicaFromPartition1) info is present in InstanceConfig
    dataNodeConfig = getDataNodeConfigInHelix(helixAdmin, instanceName);
    verifyReplicaInfoInDataNodeConfig(dataNodeConfig, replicaFromPartition1, true);
    // ensure previous added replica (replicaFromPartition2) still exists
    verifyReplicaInfoInDataNodeConfig(dataNodeConfig, replicaFromPartition2, true);
    // 4. remove recently added new replica (replicaFromPartition1)
    assertTrue("Removing replica info from InstanceConfig should succeed.",
        participant.updateDataNodeInfoInCluster(replicaFromPartition1, false));
    Thread.sleep(50);
    dataNodeConfig = getDataNodeConfigInHelix(helixAdmin, instanceName);
    verifyReplicaInfoInDataNodeConfig(dataNodeConfig, replicaFromPartition1, false);
    verifyReplicaInfoInDataNodeConfig(dataNodeConfig, replicaFromPartition2, true);
    // 5. remove same replica again (id = 9, replicaFromPartition1) should be no-op
    assertTrue("Removing non-found replica info from InstanceConfig should succeed.",
        participant.updateDataNodeInfoInCluster(replicaFromPartition1, false));
    // 6. remove recently added new replica (replicaFromPartition2)
    assertTrue("Removing replica info from InstanceConfig should succeed.",
        participant.updateDataNodeInfoInCluster(replicaFromPartition2, false));
    Thread.sleep(50);
    dataNodeConfig = getDataNodeConfigInHelix(helixAdmin, instanceName);
    verifyReplicaInfoInDataNodeConfig(dataNodeConfig, replicaFromPartition2, false);
    verifyReplicaInfoInDataNodeConfig(dataNodeConfig, existingReplica, true);
    // reset props
    props.setProperty("clustermap.update.datanode.info", Boolean.toString(false));
    participant.close();
  }
Test both replica info addition and removal cases when updating node info in Helix cluster.
@throws Exception
ambry-clustermap/src/test/java/com/github/ambry/clustermap/HelixParticipantTest.java