@Test
  public void helixClusterManagerComponentsTest() throws Exception {
    MockClusterManagerQueryHelper mockClusterManagerCallback = new MockClusterManagerQueryHelper();
    // AmbryDataNode test
    try {
      new AmbryServerDataNode("DC1", clusterMapConfig2, HOST_NAME, PORT_NUM1, RACK_ID, null, null, XID,
          mockClusterManagerCallback);
      fail("Datanode construction should have failed when SSL is enabled and SSL port is null");
    } catch (IllegalArgumentException e) {
      // OK
    }
    try {
      new AmbryServerDataNode("DC1", clusterMapConfig1, HOST_NAME, MAX_PORT + 1, RACK_ID, null, null, XID,
          mockClusterManagerCallback);
      fail("Datanode construction should have failed when port num is outside the valid range");
    } catch (IllegalArgumentException e) {
      // OK
    }
    AmbryDataNode datanode1 =
        new AmbryServerDataNode("DC0", clusterMapConfig1, HOST_NAME, PORT_NUM1, RACK_ID, SSL_PORT_NUM, null, XID,
            mockClusterManagerCallback);
    AmbryDataNode datanode2 =
        new AmbryServerDataNode("DC1", clusterMapConfig2, HOST_NAME, PORT_NUM2, RACK_ID, SSL_PORT_NUM, null, XID,
            mockClusterManagerCallback);
    assertEquals(datanode1.getDatacenterName(), "DC0");
    assertEquals(datanode1.getHostname(), HOST_NAME);
    assertEquals(datanode1.getPort(), PORT_NUM1);
    assertEquals(datanode1.getSSLPort(), SSL_PORT_NUM);
    assertEquals(datanode1.getRackId(), RACK_ID);
    assertEquals(datanode1.getXid(), XID);
    assertTrue(datanode1.hasSSLPort());
    assertEquals(PortType.PLAINTEXT, datanode1.getPortToConnectTo().getPortType());
    assertTrue(datanode2.hasSSLPort());
    assertEquals(PortType.SSL, datanode2.getPortToConnectTo().getPortType());
    assertEquals(HardwareState.AVAILABLE, datanode1.getState());
    datanode1.setState(HardwareState.UNAVAILABLE);
    assertEquals(HardwareState.UNAVAILABLE, datanode1.getState());
    datanode1.setState(HardwareState.AVAILABLE);
    assertEquals(HardwareState.AVAILABLE, datanode1.getState());
    assertTrue(datanode1.compareTo(datanode1) == 0);
    assertTrue(datanode1.compareTo(datanode2) != 0);
    // the snapshot is for debug info, but just check that it works without throwing exceptions.
    assertNotNull(datanode1.getSnapshot());
    assertNotNull(datanode1.toString());
    long maxDiskCapacityInBytes = clusterMapConfig1.clustermapMaxDiskCapacityInBytes;

    // AmbryDisk tests
    String mountPath1 = "/mnt/1";
    String mountPath2 = "/mnt/2";
    try {
      new AmbryDisk(clusterMapConfig1, null, mountPath1, HardwareState.UNAVAILABLE, maxDiskCapacityInBytes);
      fail("disk initialization should fail with invalid arguments");
    } catch (IllegalStateException e) {
      // OK
    }
    try {
      new AmbryDisk(clusterMapConfig1, datanode1, null, HardwareState.UNAVAILABLE, maxDiskCapacityInBytes);
      fail("disk initialization should fail with invalid arguments");
    } catch (IllegalStateException e) {
      // OK
    }
    try {
      new AmbryDisk(clusterMapConfig1, datanode1, "", HardwareState.UNAVAILABLE,
          clusterMapConfig1.clustermapMaxDiskCapacityInBytes);
      fail("disk initialization should fail with invalid arguments");
    } catch (IllegalStateException e) {
      // OK
    }
    try {
      new AmbryDisk(clusterMapConfig1, datanode1, "0", HardwareState.UNAVAILABLE, maxDiskCapacityInBytes);
      fail("disk initialization should fail with invalid arguments");
    } catch (IllegalStateException e) {
      // OK
    }
    try {
      new AmbryDisk(clusterMapConfig1, datanode1, mountPath1, HardwareState.UNAVAILABLE, maxDiskCapacityInBytes + 1);
      fail("disk initialization should fail with invalid arguments");
    } catch (IllegalStateException e) {
      // OK
    }

    AmbryDisk disk1 =
        new AmbryDisk(clusterMapConfig1, datanode1, mountPath1, HardwareState.AVAILABLE, maxDiskCapacityInBytes);
    AmbryDisk disk2 =
        new AmbryDisk(clusterMapConfig2, datanode2, mountPath2, HardwareState.AVAILABLE, maxDiskCapacityInBytes);
    assertEquals(mountPath1, disk1.getMountPath());
    assertEquals(maxDiskCapacityInBytes, disk1.getRawCapacityInBytes());
    assertEquals(HardwareState.AVAILABLE, disk1.getState());
    disk1.setState(HardwareState.UNAVAILABLE);
    assertEquals(HardwareState.UNAVAILABLE, disk1.getState());
    disk1.setState(HardwareState.AVAILABLE);
    assertEquals(HardwareState.AVAILABLE, disk1.getState());
    assertEquals(disk1.getDataNode(), datanode1);
    datanode1.setState(HardwareState.UNAVAILABLE);
    assertEquals(HardwareState.UNAVAILABLE, disk1.getState());

    // AmbryPartition tests
    // All partitions are READ_WRITE initially.
    sealedStateChangeCounter = new AtomicLong(0);
    String partition1Class = getRandomString(10);
    String partition2Class = getRandomString(10);
    AmbryPartition partition1 = new AmbryPartition(1, partition1Class, mockClusterManagerCallback);
    AmbryPartition partition2 = new AmbryPartition(2, partition2Class, mockClusterManagerCallback);
    assertTrue(partition1.isEqual(partition1.toPathString()));
    assertTrue(partition1.compareTo(partition1) == 0);
    assertFalse(partition1.isEqual(partition2.toPathString()));
    assertTrue(partition1.compareTo(partition2) != 0);
    assertEquals("Partition class not as expected", partition1Class, partition1.getPartitionClass());
    assertEquals("Partition class not as expected", partition2Class, partition2.getPartitionClass());

    // AmbryReplica tests
    try {
      new AmbryServerReplica(clusterMapConfig1, null, disk1, false, MAX_REPLICA_CAPACITY_IN_BYTES,
          ReplicaSealStatus.NOT_SEALED);
      fail("Replica initialization should fail with invalid arguments");
    } catch (NullPointerException e) {
      // OK
    }

    try {
      new AmbryServerReplica(clusterMapConfig1, partition1, null, false, MAX_REPLICA_CAPACITY_IN_BYTES,
          ReplicaSealStatus.NOT_SEALED);
      fail("Replica initialization should fail with invalid arguments");
    } catch (NullPointerException e) {
      // OK
    }

    try {
      new AmbryServerReplica(clusterMapConfig1, partition1, disk1, false, MAX_REPLICA_CAPACITY_IN_BYTES + 1,
          ReplicaSealStatus.NOT_SEALED);
      fail("Replica initialization should fail with invalid arguments");
    } catch (IllegalStateException e) {
      // OK
    }

    // Create a few replicas and make the mockClusterManagerCallback aware of the association.
    AmbryReplica replica1 =
        new AmbryServerReplica(clusterMapConfig1, partition1, disk1, false, MAX_REPLICA_CAPACITY_IN_BYTES,
            ReplicaSealStatus.NOT_SEALED);
    mockClusterManagerCallback.addReplicaToPartition(partition1, replica1);
    AmbryReplica replica2 =
        new AmbryServerReplica(clusterMapConfig1, partition2, disk1, false, MIN_REPLICA_CAPACITY_IN_BYTES,
            ReplicaSealStatus.NOT_SEALED);
    mockClusterManagerCallback.addReplicaToPartition(partition2, replica2);
    AmbryReplica replica3 =
        new AmbryServerReplica(clusterMapConfig2, partition1, disk2, false, MIN_REPLICA_CAPACITY_IN_BYTES,
            ReplicaSealStatus.NOT_SEALED);
    mockClusterManagerCallback.addReplicaToPartition(partition1, replica3);
    AmbryReplica replica4 =
        new AmbryServerReplica(clusterMapConfig2, partition2, disk2, false, MIN_REPLICA_CAPACITY_IN_BYTES,
            ReplicaSealStatus.SEALED);
    mockClusterManagerCallback.addReplicaToPartition(partition2, replica4);
    AmbryReplica replica5 =
        new AmbryServerReplica(clusterMapConfig1, partition1, disk1, true, MIN_REPLICA_CAPACITY_IN_BYTES,
            ReplicaSealStatus.NOT_SEALED);
    mockClusterManagerCallback.addReplicaToPartition(partition1, replica5);

    sealedStateChangeCounter.incrementAndGet();

    assertEquals(replica1.getDiskId().getMountPath(), replica1.getMountPath());
    List<AmbryReplica> peerReplicas = replica1.getPeerReplicaIds();
    assertEquals(2, peerReplicas.size());
    assertEquals(replica1.getPartitionId(), peerReplicas.get(0).getPartitionId());
    assertEquals(replica3, peerReplicas.get(0));
    assertEquals(replica5, peerReplicas.get(1));
    assertTrue("Replica should be in stopped state", peerReplicas.get(1).isDown());

    List<AmbryReplica> replicaList1 = partition1.getReplicaIds();
    List<AmbryReplica> replicaList2 = partition2.getReplicaIds();
    assertEquals("Mismatch in number of replicas. Found: " + replicaList1.toString(), 3, replicaList1.size());
    assertTrue(replicaList1.contains(replica1));
    assertTrue(replicaList1.contains(replica3));
    assertTrue(replicaList1.contains(replica5));
    assertEquals(2, replicaList2.size());
    assertTrue(replicaList2.contains(replica2));
    assertTrue(replicaList2.contains(replica4));

    assertEquals(partition1.getPartitionState(), PartitionState.READ_WRITE);
    assertEquals(partition2.getPartitionState(), PartitionState.READ_ONLY);
    replica1.setSealedStatus(ReplicaSealStatus.SEALED);
    sealedStateChangeCounter.incrementAndGet();
    assertEquals(partition1.getPartitionState(), PartitionState.READ_ONLY);
    replica3.setSealedStatus(ReplicaSealStatus.SEALED);
    sealedStateChangeCounter.incrementAndGet();
    assertEquals(partition1.getPartitionState(), PartitionState.READ_ONLY);
    replica1.setSealedStatus(ReplicaSealStatus.NOT_SEALED);
    sealedStateChangeCounter.incrementAndGet();
    assertEquals(partition1.getPartitionState(), PartitionState.READ_ONLY);
    replica3.setSealedStatus(ReplicaSealStatus.NOT_SEALED);
    sealedStateChangeCounter.incrementAndGet();
    assertEquals(partition1.getPartitionState(), PartitionState.READ_WRITE);
    replica4.setSealedStatus(ReplicaSealStatus.NOT_SEALED);
    sealedStateChangeCounter.incrementAndGet();
    assertEquals(partition2.getPartitionState(), PartitionState.READ_WRITE);

    // the snapshot is for debug info, but just check that it works without throwing exceptions.
    assertNotNull(replica1.getSnapshot());
  }
Test {@link AmbryDataNode}, {@link AmbryDisk}, {@link AmbryPartition} and {@link AmbryReplica}.
@throws Exception
ambry-clustermap/src/test/java/com/github/ambry/clustermap/DynamicClusterManagerComponentsTest.java