hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/node/TestNodeManager.java
@Test
  public void testScmClusterIsInExpectedState2() throws IOException,
      InterruptedException, TimeoutException {
    final int healthyCount = 5000;
    final int staleCount = 100;
    final int deadCount = 10;

    OzoneConfiguration conf = getConf();
    conf.setTimeDuration(OZONE_SCM_HEARTBEAT_PROCESS_INTERVAL, 100,
        MILLISECONDS);
    conf.setTimeDuration(OZONE_SCM_HEARTBEAT_INTERVAL, 1, SECONDS);
    conf.setTimeDuration(OZONE_SCM_STALENODE_INTERVAL, 3, SECONDS);
    conf.setTimeDuration(OZONE_SCM_DEADNODE_INTERVAL, 6, SECONDS);
    conf.setInt(OZONE_SCM_MAX_HB_COUNT_TO_PROCESS, 7000);


    try (SCMNodeManager nodeManager = createNodeManager(conf)) {
      List<DatanodeDetails> healthyNodeList = createNodeSet(nodeManager,
          healthyCount);
      List<DatanodeDetails> staleNodeList = createNodeSet(nodeManager,
          staleCount);
      List<DatanodeDetails> deadNodeList = createNodeSet(nodeManager,
          deadCount);

      Runnable healthyNodeTask = () -> {
        try {
          // 2 second heartbeat makes these nodes stay healthy.
          heartbeatNodeSet(nodeManager, healthyNodeList, 2 * 1000);
        } catch (InterruptedException ignored) {
        }
      };

      Runnable staleNodeTask = () -> {
        try {
          // 4 second heartbeat makes these nodes go to stale and back to
          // healthy again.
          heartbeatNodeSet(nodeManager, staleNodeList, 4 * 1000);
        } catch (InterruptedException ignored) {
        }
      };


      // No Thread just one time HBs the node manager, so that these will be
      // marked as dead nodes eventually.
      for (DatanodeDetails dn : deadNodeList) {
        nodeManager.sendHeartbeat(dn.getProtoBufMessage(), null, reportState);
      }


      Thread thread1 = new Thread(healthyNodeTask);
      thread1.setDaemon(true);
      thread1.start();


      Thread thread2 = new Thread(staleNodeTask);
      thread2.setDaemon(true);
      thread2.start();

      Thread.sleep(10 * 1000);

      // Assert all healthy nodes are healthy now, this has to be a greater
      // than check since Stale nodes can be healthy when we check the state.

      assertTrue(nodeManager.getNodeCount(HEALTHY) >= healthyCount);

      assertEquals(deadCount, nodeManager.getNodeCount(DEAD));

      List<DatanodeDetails> deadList = nodeManager.getNodes(DEAD);

      for (DatanodeDetails node : deadList) {
        assertTrue(deadNodeList.contains(node));
      }



      // Checking stale nodes is tricky since they have to move between
      // healthy and stale to avoid becoming dead nodes. So we search for
      // that state for a while, if we don't find that state waitfor will
      // throw.
      GenericTestUtils.waitFor(() -> findNodes(nodeManager, staleCount, STALE),
          500, 4 * 1000);

      thread1.interrupt();
      thread2.interrupt();
    }
  }
/**
   * Asserts that we can create a set of nodes that send its heartbeats from
   * different threads and NodeManager behaves as expected.
   *
   * @throws IOException
   * @throws InterruptedException
   */
Asserts that we can create a set of nodes that send its heartbeats from
different threads and NodeManager behaves as expected.


Asserts that we can create a set of nodes that send its heartbeats from different threads and NodeManager behaves as expected .
@Test
  public void testScmClusterIsInExpectedState2() throws IOException,
      InterruptedException, TimeoutException {
    final int healthyCount = 5000;
    final int staleCount = 100;
    final int deadCount = 10;
    OzoneConfiguration conf = getConf();
    conf.setTimeDuration(OZONE_SCM_HEARTBEAT_PROCESS_INTERVAL, 100,
        MILLISECONDS);
    conf.setTimeDuration(OZONE_SCM_HEARTBEAT_INTERVAL, 1, SECONDS);
    conf.setTimeDuration(OZONE_SCM_STALENODE_INTERVAL, 3, SECONDS);
    conf.setTimeDuration(OZONE_SCM_DEADNODE_INTERVAL, 6, SECONDS);
    conf.setInt(OZONE_SCM_MAX_HB_COUNT_TO_PROCESS, 7000);
    try (SCMNodeManager nodeManager = createNodeManager(conf)) {
      List<DatanodeDetails> healthyNodeList = createNodeSet(nodeManager,
          healthyCount);
      List<DatanodeDetails> staleNodeList = createNodeSet(nodeManager,
          staleCount);
      List<DatanodeDetails> deadNodeList = createNodeSet(nodeManager,
          deadCount);
      Runnable healthyNodeTask = () -> {
        try {
          heartbeatNodeSet(nodeManager, healthyNodeList, 2 * 1000);
        } catch (InterruptedException ignored) {
        }
      };
      Runnable staleNodeTask = () -> {
        try {
          heartbeatNodeSet(nodeManager, staleNodeList, 4 * 1000);
        } catch (InterruptedException ignored) {
        }
      };
      for (DatanodeDetails dn : deadNodeList) {
        nodeManager.sendHeartbeat(dn.getProtoBufMessage(), null, reportState);
      }
      Thread thread1 = new Thread(healthyNodeTask);
      thread1.setDaemon(true);
      thread1.start();
      Thread thread2 = new Thread(staleNodeTask);
      thread2.setDaemon(true);
      thread2.start();
      Thread.sleep(10 * 1000);
      assertTrue(nodeManager.getNodeCount(HEALTHY) >= healthyCount);
      assertEquals(deadCount, nodeManager.getNodeCount(DEAD));
      List<DatanodeDetails> deadList = nodeManager.getNodes(DEAD);
      for (DatanodeDetails node : deadList) {
        assertTrue(deadNodeList.contains(node));
      }
      GenericTestUtils.waitFor(() -> findNodes(nodeManager, staleCount, STALE),
          500, 4 * 1000);
      thread1.interrupt();
      thread2.interrupt();
    }
  }
@ Test public void testScmClusterIsInExpectedState2 ( ) throws IOException , InterruptedException , TimeoutException { final int healthyCount = 5000 ; final int staleCount = 100 ; final int deadCount = 10 ; OzoneConfiguration conf = getConf ( ) ; conf . setTimeDuration ( OZONE_SCM_HEARTBEAT_PROCESS_INTERVAL , 100 , MILLISECONDS ) ; conf . setTimeDuration ( OZONE_SCM_HEARTBEAT_INTERVAL , 1 , SECONDS ) ; conf . setTimeDuration ( OZONE_SCM_STALENODE_INTERVAL , 3 , SECONDS ) ; conf . setTimeDuration ( OZONE_SCM_DEADNODE_INTERVAL , 6 , SECONDS ) ; conf . setInt ( OZONE_SCM_MAX_HB_COUNT_TO_PROCESS , 7000 ) ; try ( SCMNodeManager nodeManager = createNodeManager ( conf ) ) { List < DatanodeDetails > healthyNodeList = createNodeSet ( nodeManager , healthyCount ) ; List < DatanodeDetails > staleNodeList = createNodeSet ( nodeManager , staleCount ) ; List < DatanodeDetails > deadNodeList = createNodeSet ( nodeManager , deadCount ) ; Runnable healthyNodeTask = ( ) -> { try { heartbeatNodeSet ( nodeManager , healthyNodeList , 2 * 1000 ) ; } catch ( InterruptedException ignored ) { } } ; Runnable staleNodeTask = ( ) -> { try { heartbeatNodeSet ( nodeManager , staleNodeList , 4 * 1000 ) ; } catch ( InterruptedException ignored ) { } } ; for ( DatanodeDetails dn : deadNodeList ) { nodeManager . sendHeartbeat ( dn . getProtoBufMessage ( ) , null , reportState ) ; } Thread thread1 = new Thread ( healthyNodeTask ) ; thread1 . setDaemon ( true ) ; thread1 . start ( ) ; Thread thread2 = new Thread ( staleNodeTask ) ; thread2 . setDaemon ( true ) ; thread2 . start ( ) ; Thread . sleep ( 10 * 1000 ) ; assertTrue ( nodeManager . getNodeCount ( HEALTHY ) >= healthyCount ) ; assertEquals ( deadCount , nodeManager . getNodeCount ( DEAD ) ) ; List < DatanodeDetails > deadList = nodeManager . getNodes ( DEAD ) ; for ( DatanodeDetails node : deadList ) { assertTrue ( deadNodeList . contains ( node ) ) ; } GenericTestUtils . waitFor ( ( ) -> findNodes ( nodeManager , staleCount , STALE ) , 500 , 4 * 1000 ) ; thread1 . interrupt ( ) ; thread2 . interrupt ( ) ; } }
Asserts that we can create a set of nodes that send its heartbeats from
 different threads and NodeManager behaves as expected.
Asserts that we can create a set of nodes that send its heartbeats from different threads and NodeManager behaves as expected .
// 2 second heartbeat makes these nodes stay healthy. // 4 second heartbeat makes these nodes go to stale and back to // healthy again. // No Thread just one time HBs the node manager, so that these will be // marked as dead nodes eventually. // Assert all healthy nodes are healthy now, this has to be a greater // than check since Stale nodes can be healthy when we check the state. // Checking stale nodes is tricky since they have to move between // healthy and stale to avoid becoming dead nodes. So we search for // that state for a while, if we don't find that state waitfor will // throw.