@Test
public void test() throws Exception {

    final AtomicDouble failedRatio = new AtomicDouble(0);
    final AtomicLong time = new AtomicLong(System.currentTimeMillis());
    final double errorRange = 0.0001;
    final TestDependency testDependency = new TestDependency(failedRatio, time, 0.05, 0.1, 0.2, 600 * 1000);
    // Test OK
    CheckResult checkResult = testDependency.call();
    assertEquals(CheckStatus.OK, checkResult.getStatus());
    assertEquals(0, Double.valueOf(checkResult.getErrorMessage()), errorRange);
    // Test MINOR
    failedRatio.set(0.12);
    time.addAndGet(100 * 1000);
    checkResult = testDependency.call();
    assertEquals(CheckStatus.MINOR, checkResult.getStatus());
    assertEquals(0.06, Double.valueOf(checkResult.getErrorMessage()), errorRange);
    // Test MAJOR
    failedRatio.set(0.24);
    time.addAndGet(100 * 1000);
    checkResult = testDependency.call();
    assertEquals(CheckStatus.MAJOR, checkResult.getStatus());
    assertEquals(0.12, Double.valueOf(checkResult.getErrorMessage()), errorRange);
    // Test OUTAGE
    failedRatio.set(0.48);
    time.addAndGet(200 * 1000);
    checkResult = testDependency.call();
    assertEquals(CheckStatus.OUTAGE, checkResult.getStatus());
    assertEquals(0.24, Double.valueOf(checkResult.getErrorMessage()), errorRange);
    // Test ping throw Exception
    failedRatio.set(100);
    time.addAndGet(100 * 1000);
    checkResult = testDependency.call();
    assertEquals(CheckStatus.OUTAGE, checkResult.getStatus());
    assertEquals(0.34, Double.valueOf(checkResult.getErrorMessage()), errorRange);
    // Remove one point
    failedRatio.set(0.48);
    time.addAndGet(100 * 1000);
    checkResult = testDependency.call();
    assertEquals(CheckStatus.OUTAGE, checkResult.getStatus());
    assertEquals(0.476, Double.valueOf(checkResult.getErrorMessage()), errorRange);
    // Remove two point
    failedRatio.set(0);
    time.addAndGet(200 * 1000);
    checkResult = testDependency.call();
    assertEquals(CheckStatus.OUTAGE, checkResult.getStatus());
    assertEquals(0.49, Double.valueOf(checkResult.getErrorMessage()), errorRange);
    // Remove all points and add a new one.
    failedRatio.set(0.04);
    time.addAndGet(700 * 1000);
    checkResult = testDependency.call();
    assertEquals(CheckStatus.OK, checkResult.getStatus());
    assertEquals(0.04, Double.valueOf(checkResult.getErrorMessage()), errorRange);
    // Test recalculate
    failedRatio.set(0.15);
    time.addAndGet(10000 * 1000);
    checkResult = testDependency.call();
    assertEquals(CheckStatus.MAJOR, checkResult.getStatus());
    assertEquals(0.15, Double.valueOf(checkResult.getErrorMessage()), errorRange);
    // Test recalculate with multiple points.
    failedRatio.set(0.1);
    time.addAndGet(3400 * 1000);
    testDependency.call();
    failedRatio.set(0.1);
    time.addAndGet(100 * 1000);
    testDependency.call();
    failedRatio.set(0.5);
    time.addAndGet(300 * 1000);
    checkResult = testDependency.call();
    assertEquals(CheckStatus.OUTAGE, checkResult.getStatus());
    assertEquals(0.25, Double.valueOf(checkResult.getErrorMessage()), errorRange);
}