@Test
  public void testRespectsTime() throws Exception {
    final long startTime = System.nanoTime();
    final AtomicLong currentTime = new AtomicLong(startTime);
    Ticker ticker =
        new Ticker() {
          @Override
          public long read() {
            return currentTime.get();
          }
        };
    ProportionalZoneFailureDetector detector =
        new ProportionalZoneFailureDetector(2, Duration.ONE_HOUR, 0.9, ticker);

    for (int i = 0; i < 2; i++) {
      detector.onStartupFailure(loc1, entity1, new Throwable("simulated failure"));
    }
    assertTrue(detector.hasFailed(loc1));

    currentTime.set(startTime + TimeUnit.MILLISECONDS.toNanos(1000 * 60 * 60 - 1));
    assertTrue(detector.hasFailed(loc1));

    currentTime.set(startTime + TimeUnit.MILLISECONDS.toNanos(1000 * 60 * 60 + 1));
    assertFalse(detector.hasFailed(loc1));
  }
  @Test
  public void testRespectsProportion() throws Exception {
    ProportionalZoneFailureDetector detector =
        new ProportionalZoneFailureDetector(2, Duration.ONE_HOUR, 0.9);

    for (int i = 0; i < 9; i++) {
      detector.onStartupFailure(loc1, entity1, new Throwable("simulated failure"));
    }
    assertTrue(detector.hasFailed(loc1));

    detector.onStartupSuccess(loc1, entity1);
    assertTrue(detector.hasFailed(loc1));

    detector.onStartupSuccess(loc1, entity1);
    assertFalse(detector.hasFailed(loc1));
  }