@Test(expected = ResourceExhaustedException.class)
  public void testNoBackends() throws ResourceExhaustedException {
    expect(wrappedStrategy.nextBackend()).andThrow(new ResourceExhaustedException("No backends."));

    control.replay();

    subsetStrategy.nextBackend();
  }
  @Test
  public void testPicksLeastConnected() throws ResourceExhaustedException {
    BackendOfferExpectation backendOfferExpectation = new BackendOfferExpectation();
    control.replay();

    backendOfferExpectation.offerBackends(BACKEND_1, BACKEND_2, BACKEND_3);

    connect(BACKEND_1, 1);
    connect(BACKEND_2, 2);
    connect(BACKEND_3, 3);
    assertThat(leastCon.nextBackend(), is(BACKEND_1));

    connect(BACKEND_1, 2);
    assertThat(leastCon.nextBackend(), is(BACKEND_2));
  }
  @Test
  public void testAccountingSurvivesBackendChange() throws ResourceExhaustedException {
    BackendOfferExpectation offer1 = new BackendOfferExpectation();
    BackendOfferExpectation offer2 = new BackendOfferExpectation();
    control.replay();

    offer1.offerBackends(BACKEND_1, BACKEND_2, BACKEND_3, BACKEND_4);
    connect(BACKEND_1, 10);
    connect(BACKEND_2, 8);
    connect(BACKEND_3, 9);
    assertThat(leastCon.nextBackend(), is(BACKEND_4));

    offer2.offerBackends(BACKEND_1, BACKEND_2, BACKEND_3);
    assertThat(leastCon.nextBackend(), is(BACKEND_2));
  }
  @Test
  public void testForgetsOldBackends() throws ResourceExhaustedException {
    BackendOfferExpectation offer1 = new BackendOfferExpectation();
    BackendOfferExpectation offer2 = new BackendOfferExpectation();
    BackendOfferExpectation offer3 = new BackendOfferExpectation();
    control.replay();

    offer1.offerBackends(BACKEND_1, BACKEND_2);
    connect(BACKEND_2, 10);

    offer2.offerBackends(BACKEND_2, BACKEND_3);
    connect(BACKEND_3, 1);
    assertThat(leastCon.nextBackend(), is(BACKEND_3));

    offer3.offerBackends(BACKEND_2);
    assertThat(leastCon.nextBackend(), is(BACKEND_2));
  }
  @Test(expected = ResourceExhaustedException.class)
  public void testEmptyBackends() throws ResourceExhaustedException {
    BackendOfferExpectation backendOfferExpectation = new BackendOfferExpectation();
    control.replay();

    backendOfferExpectation.offerBackends();

    leastCon.nextBackend();
  }
  @Test
  @SuppressWarnings("unchecked") // Needed because type information lost in vargs.
  public void testHandlesEqualCount() throws ResourceExhaustedException {
    BackendOfferExpectation backendOfferExpectation = new BackendOfferExpectation();
    control.replay();

    backendOfferExpectation.offerBackends(BACKEND_1, BACKEND_2, BACKEND_3);
    connect(BACKEND_1, 5);
    connect(BACKEND_2, 5);
    connect(BACKEND_3, 5);

    assertThat(leastCon.nextBackend(), anyOf(is(BACKEND_1), is(BACKEND_2), is(BACKEND_3)));
  }
  @Test
  public void testReranks() throws ResourceExhaustedException {
    BackendOfferExpectation backendOfferExpectation = new BackendOfferExpectation();
    control.replay();

    backendOfferExpectation.offerBackends(BACKEND_1, BACKEND_2, BACKEND_3);
    connect(BACKEND_1, 10);
    connect(BACKEND_2, 5);
    connect(BACKEND_3, 5);

    disconnect(BACKEND_1, 6);

    assertThat(leastCon.nextBackend(), is(BACKEND_1));
  }
  @Test
  public void testUsesAllBackends() throws ResourceExhaustedException {
    BackendOfferExpectation backendOfferExpectation = new BackendOfferExpectation();
    control.replay();

    Set<String> allBackends = Sets.newHashSet(BACKEND_1, BACKEND_2, BACKEND_3);
    backendOfferExpectation.offerBackends(allBackends);

    Set<String> usedBackends = Sets.newHashSet();
    for (int i = 0; i < allBackends.size(); i++) {
      String backend = leastCon.nextBackend();
      usedBackends.add(backend);
      connect(backend, 1);
      disconnect(backend, 1);
    }

    assertThat(usedBackends, is(allBackends));
  }
 @Override
 public synchronized K nextBackend() throws ResourceExhaustedException {
   return strategy.nextBackend();
 }
  @Test(expected = ResourceExhaustedException.class)
  public void testNoBackends() throws ResourceExhaustedException {
    control.replay();

    leastCon.nextBackend();
  }