static void mockServerEventsAndVerify(ClusterMap clusterManager, ClusterMapConfig clusterMapConfig,
      ResourceState[] initialStates, ServerErrorCode serverErrorCode, ResourceState[] expectedStates) {
    ResponseHandler handler = new ResponseHandler(clusterManager);
    // choose a disk backed replica
    ReplicaId replica = clusterManager.getWritablePartitionIds(null)
        .get(0)
        .getReplicaIds()
        .stream()
        .filter(replicaId -> replicaId.getReplicaType() != ReplicaType.CLOUD_BACKED)
        .findFirst()
        .get();
    DataNodeId dataNode = replica.getDataNodeId();
    assertTrue(clusterManager.getReplicaIds(dataNode).contains(replica));
    DiskId disk = replica.getDiskId();

    // Verify that everything is up in the beginning.
    assertFalse(replica.isDown());
    assertEquals(HardwareState.AVAILABLE, dataNode.getState());
    assertEquals(HardwareState.AVAILABLE, disk.getState());

    // Mock initial states for node, disk and replica
    if (initialStates[0] == ResourceState.Node_Down) {
      for (int i = 0; i < clusterMapConfig.clusterMapFixedTimeoutDatanodeErrorThreshold; i++) {
        clusterManager.onReplicaEvent(replica, ReplicaEventType.Node_Timeout);
      }
    }
    if (initialStates[1] == ResourceState.Disk_Down) {
      for (int i = 0; i < clusterMapConfig.clusterMapFixedTimeoutDiskErrorThreshold; i++) {
        clusterManager.onReplicaEvent(replica, ReplicaEventType.Disk_Error);
      }
    }
    if (initialStates[2] == ResourceState.Replica_Down) {
      for (int i = 0; i < clusterMapConfig.clusterMapFixedTimeoutReplicaErrorThreshold; i++) {
        clusterManager.onReplicaEvent(replica, ReplicaEventType.Replica_Unavailable);
      }
    }

    // Make sure node, disk and replica match specified initial states
    if (dataNode.getState() == HardwareState.AVAILABLE && disk.getState() == HardwareState.AVAILABLE) {
      // Since replica.isDown() will check the state of disk, if we try to mock disk is down and replica is up, we should
      // skip this check for initial state. Only when node and disk are up, we check the initial state of replica.
      assertEquals(initialStates[2], replica.isDown() ? ResourceState.Replica_Down : ResourceState.Replica_Up);
    }
    if (dataNode.getState() == HardwareState.AVAILABLE) {
      assertEquals(initialStates[1],
          disk.getState() == HardwareState.UNAVAILABLE ? ResourceState.Disk_Down : ResourceState.Disk_Up);
    }
    assertEquals(initialStates[0],
        dataNode.getState() == HardwareState.UNAVAILABLE ? ResourceState.Node_Down : ResourceState.Node_Up);

    // Trigger server event
    handler.onEvent(replica, serverErrorCode);

    // Verify node, disk and replica match expected states after server event
    assertEquals(expectedStates[2], replica.isDown() ? ResourceState.Replica_Down : ResourceState.Replica_Up);
    assertEquals(expectedStates[1],
        disk.getState() == HardwareState.UNAVAILABLE ? ResourceState.Disk_Down : ResourceState.Disk_Up);
    assertEquals(expectedStates[0],
        dataNode.getState() == HardwareState.UNAVAILABLE ? ResourceState.Node_Down : ResourceState.Node_Up);
  }
The helper method sets up initial states for datanode, disk and replica. Then it triggers specified server event and
verifies the states of datanode, disk and replica are expected after event.
@param clusterManager the {@link ClusterMap} to use.
@param clusterMapConfig the {@link ClusterMapConfig} to use.
@param initialStates the initial states for datanode, disk and replica (default order).
@param serverErrorCode the {@link ServerErrorCode} received for mocking event.
@param expectedStates the expected states for datanode, disk and replica (default order).
ambry-clustermap/src/test/java/com/github/ambry/clustermap/TestUtils.java