  @Test
  public void testLostConnectionRetry() throws Exception {

    FakeClient delegate1 = new FakeClient(true, true);
    FakeClient delegate2 = new FakeClient(true, false);

    BackoffFunction backoffFunction = mock(BackoffFunction.class);
    when(backoffFunction.getBackoffTimeMillis(0)).thenReturn(0L);
    when(backoffFunction.getBackoffTimeMillis(1)).thenReturn(123L);

    Connector connector = mock(Connector.class);
    when(connector.connect())
        .thenReturn(CompletableFuture.completedFuture(delegate1))
        .thenReturn(CompletableFutures.exceptionallyCompletedFuture(new RuntimeException()))
        .thenReturn(CompletableFutures.exceptionallyCompletedFuture(new RuntimeException()))
        .thenReturn(CompletableFuture.completedFuture(delegate2));

    ReconnectingClient client =
        new ReconnectingClient(
            backoffFunction,
            scheduledExecutorService,
            connector,
            HostAndPort.fromString("localhost:123"));

    verify(connector, times(4)).connect();
    verify(scheduledExecutorService, times(1))
        .schedule(Mockito.<Runnable>any(), eq(0L), eq(TimeUnit.MILLISECONDS));
    verify(scheduledExecutorService, times(1))
        .schedule(Mockito.<Runnable>any(), eq(123L), eq(TimeUnit.MILLISECONDS));
    verify(backoffFunction, times(1)).getBackoffTimeMillis(0);
    verify(backoffFunction, times(1)).getBackoffTimeMillis(1);

    verifyNoMoreInteractions(connector, scheduledExecutorService, backoffFunction);

    assertTrue(client.isConnected());
  }