@Test
  public void testMultiNodeCluster()
      throws Exception {
    Set<String> hostNames = new HashSet<String>() {{
      add("Host1");
      add("Host2");
    }};

    // Create a cluster with 2 hosts
    Cluster cluster = getDummyCluster(hostNames);

    RepositoryVersionEntity repositoryVersion = helper.getOrCreateRepositoryVersion(cluster);

    // Add HDFS service with DATANODE component to the cluster
    Service hdfs = cluster.addService(HDFS, repositoryVersion);

    hdfs.addServiceComponent(DATANODE).setRecoveryEnabled(true);

    // Add SCH to Host1 and Host2
    hdfs.getServiceComponent(DATANODE).addServiceComponentHost("Host1");
    hdfs.getServiceComponent(DATANODE).addServiceComponentHost("Host2");

    // Simulate registration for Host1: Get the recovery configuration right away for Host1.
    // It makes an entry for cluster name and Host1 in the timestamp dictionary.
    RecoveryConfig recoveryConfig = recoveryConfigHelper.getRecoveryConfig(cluster.getClusterName(), "Host1");
    assertEquals(Lists.newArrayList(
      new RecoveryConfigComponent(DATANODE, HDFS, State.INIT)
    ), recoveryConfig.getEnabledComponents());

    // Simulate heartbeat for Host2: When second host heartbeats, it first checks if config stale.
    // This should return true since it did not get the configuration during registration.
    // There is an entry for the cluster name, made by Host1, but no entry for Host2 in the timestamp
    // dictionary since we skipped registration. Lookup for cluster name will succeed but lookup for Host2
    // will return null.
    boolean isConfigStale = recoveryConfigHelper.isConfigStale(cluster.getClusterName(), "Host2", -1);
    assertTrue(isConfigStale);
  }
Test a cluster with two hosts. The first host gets the configuration during
registration. The second host gets it during it's first heartbeat.

@throws Exception
ambari-server/src/test/java/org/apache/ambari/server/configuration/RecoveryConfigHelperTest.java