@Test
  public void testStateModelParticipation() throws Exception {
    assumeTrue(stateModelDef.equals(ClusterMapConfig.AMBRY_STATE_MODEL_DEF));
    ClusterMapConfig clusterMapConfig = new ClusterMapConfig(new VerifiableProperties(props));
    MetricRegistry metricRegistry = new MetricRegistry();
    HelixParticipant helixParticipant =
        new HelixParticipant(mock(HelixClusterManager.class), clusterMapConfig, new HelixFactory(), metricRegistry,
            getDefaultZkConnectStr(clusterMapConfig), true);
    // participate
    helixParticipant.participateAndBlockStateTransition(Collections.emptyList(), null, null);
    helixParticipant.unblockStateTransition();
    HelixManager manager = helixParticipant.getHelixManager();
    StateModelFactory<? extends StateModel> factory =
        manager.getStateMachineEngine().getStateModelFactory(ClusterMapConfig.AMBRY_STATE_MODEL_DEF);
    assertTrue(factory instanceof AmbryStateModelFactory);

    ClusterMap cm = new StaticClusterManager(testPartitionLayout.partitionLayout, dcName, new MetricRegistry());
    List<? extends ReplicaId> replicaIds =
        cm.getReplicaIds(cm.getDataNodeId("localhost", clusterMapConfig.clusterMapPort));
    String resource = "10000"; // There is only one resource
    // send state transition messages, this is controller logic, just put it down here to make sure the pipeline
    // of state transition works
    sendStateTransitionMessages(manager, resource, replicaIds, "OFFLINE", "BOOTSTRAP");
    // sleep some time so the state transition can happen
    Thread.sleep(1000);
    // have to get offline to refresh the cache?
    getNumberOfReplicaInStateFromMetric("offline", metricRegistry);
    assertEquals(replicaIds.size(), getNumberOfReplicaInStateFromMetric("bootstrap", metricRegistry));

    sendStateTransitionMessages(manager, resource, replicaIds, "BOOTSTRAP", "STANDBY");
    Thread.sleep(500);
    getNumberOfReplicaInStateFromMetric("offline", metricRegistry);
    assertEquals(replicaIds.size(), getNumberOfReplicaInStateFromMetric("standby", metricRegistry));

    sendStateTransitionMessages(manager, resource, replicaIds, "STANDBY", "LEADER");
    Thread.sleep(500);
    getNumberOfReplicaInStateFromMetric("offline", metricRegistry);
    assertEquals(replicaIds.size(), getNumberOfReplicaInStateFromMetric("leader", metricRegistry));

    sendStateTransitionMessages(manager, resource, replicaIds, "LEADER", "STANDBY");
    Thread.sleep(500);
    getNumberOfReplicaInStateFromMetric("offline", metricRegistry);
    assertEquals(replicaIds.size(), getNumberOfReplicaInStateFromMetric("standby", metricRegistry));

    sendStateTransitionMessages(manager, resource, replicaIds, "STANDBY", "INACTIVE");
    Thread.sleep(500);
    getNumberOfReplicaInStateFromMetric("offline", metricRegistry);
    assertEquals(replicaIds.size(), getNumberOfReplicaInStateFromMetric("inactive", metricRegistry));

    sendStateTransitionMessages(manager, resource, replicaIds, "INACTIVE", "OFFLINE");
    Thread.sleep(500);
    getNumberOfReplicaInStateFromMetric("offline", metricRegistry);
    assertEquals(replicaIds.size(), getNumberOfReplicaInStateFromMetric("offline", metricRegistry));

    helixParticipant.close();
  }
Test participate method, which triggers state transition.
@throws Exception
ambry-clustermap/src/test/java/com/github/ambry/clustermap/HelixParticipantTest.java