@Test
public void testHostEvictionDueToErrorRates() throws Exception {

    // First configure the error rate monitor
    ErrorRateMonitorConfigImpl errConfig = new ErrorRateMonitorConfigImpl();
    errConfig.checkFrequency = 1;
    errConfig.window = 1;
    errConfig.suppressWindow = 60;
    errConfig.addThreshold(10, 1, 100);
    final AtomicReference<String> badHost = new AtomicReference<String>();
    final ConnectionFactory<TestClient> badConnectionFactory = new ConnectionFactory<TestClient>() {
        @Override
        public Connection<TestClient> createConnection(final HostConnectionPool<TestClient> pool) throws DynoConnectException {
            return new TestConnection(pool) {
                @Override
                public <R> OperationResult<R> execute(Operation<TestClient, R> op) throws DynoException {
                    if (pool.getHost().getHostAddress().equals(badHost.get())) {
                        throw new FatalConnectionException("Fail for bad host");
                    }
                    return super.execute(op);
                }
            };
        }
        @Override
        public Connection<TestClient> createConnectionWithDataStore(HostConnectionPool<TestClient> pool) throws DynoConnectException {
            return null;
        }
        @Override
        public Connection<TestClient> createConnectionWithConsistencyLevel(HostConnectionPool<TestClient> pool, String consistency) throws DynoConnectException {
            return null;
        }
    };
    final ConnectionPoolImpl<TestClient> pool = new ConnectionPoolImpl<TestClient>(badConnectionFactory, cpConfig, cpMonitor);
    hostSupplierHosts.add(host1);
    hostSupplierHosts.add(host2);
    hostSupplierHosts.add(host3);
    pool.start();
    final Callable<Void> testLogic = new Callable<Void>() {
        @Override
        public Void call() throws Exception {
            Thread.sleep(2000);
            badHost.set("host2");
            Thread.sleep(2000);
            return null;
        }
    };
    runTest(pool, testLogic);
    Assert.assertTrue("Total ops: " + client.ops.get(), client.ops.get() > 0);
    Assert.assertTrue("Total errors: " + cpMonitor.getOperationFailureCount(), cpMonitor.getOperationFailureCount() > 0);
    Assert.assertEquals(3 * cpConfig.getMaxConnsPerHost(), cpMonitor.getConnectionCreatedCount());
    Assert.assertEquals(0, cpMonitor.getConnectionCreateFailedCount());
    Assert.assertEquals(3 * cpConfig.getMaxConnsPerHost(), cpMonitor.getConnectionClosedCount());
    Assert.assertEquals(client.ops.get() + cpMonitor.getOperationFailureCount(), cpMonitor.getConnectionBorrowedCount());
    Assert.assertEquals(client.ops.get() + cpMonitor.getOperationFailureCount(), cpMonitor.getConnectionReturnedCount());
    checkHostStats(host1);
    checkHostStats(host3);
    HostConnectionStats h2Stats = cpMonitor.getHostStats().get(host2);
    Assert.assertEquals(cpMonitor.getOperationFailureCount(), h2Stats.getOperationErrorCount());
}