@Test
  public void testUpdatePingSample() {
    fD.registerMonitored("id", 0, 100, 50);
    fD.updatePingSample("id", 50, 50, 2);

    Assert.assertEquals(100, fD.getTimeout("id").longValue());
  }
    public void run() {
      FailureDetectorConfig failureDetectorConfig = failureDetector.getConfig();

      try {
        updateNodeStoreAvailability(failureDetectorConfig, node, false);
        failureDetectorConfig.getTime().sleep(unavailabilityMillis);
        updateNodeStoreAvailability(failureDetectorConfig, node, true);

        failureDetector.waitForAvailability(node);

        countDownLatch.countDown();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  @Override
  public String test(FailureDetector failureDetector) throws Exception {
    Node node = Iterables.get(failureDetectorConfig.getCluster().getNodes(), 0);
    CountDownLatch countDownLatch = new CountDownLatch(1);
    Listener listener = new Listener(failureDetectorConfig.getTime());
    failureDetector.addFailureDetectorListener(listener);

    ExecutorService threadPool = Executors.newFixedThreadPool(11);

    for (int i = 0; i < 10; i++)
      threadPool.submit(
          new NodeAccessorRunnable(failureDetector, node, countDownLatch, null, null, null, 0, 10));

    threadPool.submit(new TimedUnavailability(failureDetector, node, countDownLatch));

    threadPool.shutdown();

    // If we get stuck, we should give the user the opportunity to get a
    // thread dump.
    if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
      System.out.println("Threads appear to be stuck");
      threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
    }

    return Class.forName(failureDetectorConfig.getImplementationClassName()).getSimpleName()
        + ", "
        + listener.getDelta();
  }
  @Test
  public void testHeartbeatReceiving() {
    Assert.assertFalse(fD.isFailed("id", 0));
    fD.registerMonitored("id", 0, 100, 50);

    Assert.assertFalse(fD.isFailed("id", 10));
    Assert.assertEquals(10, fD.getIdleTime("id", 10).longValue());
    Assert.assertEquals(40, fD.getTimeToNextPing("id", 10).longValue()); // timeout/2

    fD.messageSent("id", 50, MessageType.PING);

    Assert.assertFalse(fD.isFailed("id", 60));
    Assert.assertEquals(80, fD.getIdleTime("id", 80).longValue());

    fD.messageReceived("id", 90, MessageType.PING);

    Assert.assertFalse(fD.isFailed("id", 120));
    Assert.assertEquals(30, fD.getIdleTime("id", 120).longValue());

    Assert.assertTrue(fD.isFailed("id", 210));
  }
  @Test
  public void testPingObjects() {
    // no hb, works like a fixed fd
    Assert.assertFalse(fD.isFailed("id", 0));
    fD.registerMonitored("id", 0, 100, 50);

    Assert.assertFalse(fD.isFailed("id", 10));
    Assert.assertFalse(fD.shouldPing("id", 10));
    Assert.assertEquals(10, fD.getIdleTime("id", 10).longValue());
    Assert.assertEquals(40, fD.getTimeToNextPing("id", 10).longValue()); // timeout/2

    Assert.assertFalse(fD.isFailed("id", 50));
    Assert.assertTrue(fD.shouldPing("id", 50));
    Assert.assertEquals(80, fD.getIdleTime("id", 80).longValue());
    Assert.assertEquals(-30, fD.getTimeToNextPing("id", 80).longValue());

    fD.messageSent("id", 200, MessageType.PING);

    // We give a one interval grace period
    Assert.assertTrue(fD.isFailed("id", 220));
    Assert.assertFalse(fD.shouldPing("id", 220));
    Assert.assertEquals(220, fD.getIdleTime("id", 220).longValue());
    Assert.assertEquals(30, fD.getTimeToNextPing("id", 220).longValue());
  }
  @Test
  public void testNoPingNoHeartbeat() {
    Assert.assertFalse(fD.isFailed("id", 0));
    fD.registerMonitored("id", 0, 100, 50);

    Assert.assertFalse(fD.isFailed("id", 10));
    Assert.assertFalse(fD.shouldPing("id", 10));
    Assert.assertEquals(10, fD.getIdleTime("id", 10).longValue());
    Assert.assertEquals(40, fD.getTimeToNextPing("id", 10).longValue()); // timeout/2

    Assert.assertFalse(fD.isFailed("id", 80));
    Assert.assertTrue(fD.shouldPing("id", 80));
    Assert.assertEquals(80, fD.getIdleTime("id", 80).longValue());
    // no ping sent, negative time to next ping
    Assert.assertEquals(-30, fD.getTimeToNextPing("id", 80).longValue());

    // one interval grace period, should fail at t=200
    Assert.assertFalse(fD.isFailed("id", 120));

    Assert.assertTrue(fD.isFailed("id", 220));

    fD.releaseMonitored("id");
    Assert.assertFalse(fD.isFailed("id", 250));
    Assert.assertFalse(fD.shouldPing("id", 250));
  }