/**
   * Unit test for quorum member add/remove.
   *
   * @throws InterruptedException
   */
  public void test_memberAddRemove() throws InterruptedException {

    final Quorum<?, ?> quorum = quorums[0];
    final QuorumMember<?> client = clients[0];
    final QuorumActor<?, ?> actor = actors[0];
    final UUID serviceId = client.getServiceId();

    // client is not a member.
    assertFalse(client.isMember());
    assertEquals(new UUID[] {}, quorum.getMembers());

    // instruct actor to add client as a member.
    actor.memberAdd();
    fixture.awaitDeque();

    // client is a member.
    assertTrue(client.isMember());
    assertEquals(new UUID[] {serviceId}, quorum.getMembers());

    // instruct actor to remove client as a member.
    actor.memberRemove();
    fixture.awaitDeque();

    // client is not a member.
    assertFalse(client.isMember());
    assertEquals(new UUID[] {}, quorum.getMembers());
  }
  /**
   * Unit test for quorum member add followed by the termination of the quorum client. This checks
   * for proper termination of the client, including the clear down of the quorum's internal state.
   *
   * @throws InterruptedException
   */
  public void test_memberAdd_terminateClient() throws InterruptedException {

    final Quorum<?, ?> quorum = quorums[0];
    final QuorumMember<?> client = clients[0];
    final QuorumActor<?, ?> actor = actors[0];
    final UUID serviceId = client.getServiceId();

    // client is not a member.
    assertFalse(client.isMember());
    assertEquals(new UUID[] {}, quorum.getMembers());

    // instruct actor to add client as a member.
    actor.memberAdd();
    fixture.awaitDeque();

    // client is a member.
    assertTrue(client.isMember());
    assertEquals(new UUID[] {serviceId}, quorum.getMembers());

    /*
     * Verify termination of the quorum for that client.
     */

    assertEquals(client, quorum.getClient());

    quorum.terminate();

    try {
      quorum.getClient();
    } catch (IllegalStateException ex) {
      log.info("Ignoring expected exception: " + ex);
    }

    // State was cleared.
    assertEquals(Quorum.NO_QUORUM, quorum.token());
    assertEquals(Quorum.NO_QUORUM, quorum.lastValidToken());
    assertEquals(new UUID[] {}, quorum.getMembers());
    assertEquals(new UUID[] {}, quorum.getJoined());
    assertEquals(new UUID[] {}, quorum.getPipeline());
    assertEquals(Collections.emptyMap(), quorum.getVotes());

    try {
      // Note: Quorum reference was cleared. Client throws exception.
      assertFalse(client.isMember());
    } catch (IllegalStateException ex) {
      log.info("Ignoring expected exception: " + ex);
    }

    // Double-termination is safe.
    quorum.terminate();
  }