public void testQueueStats() {
    List<ClusterState> states = randomStates(scaledRandomIntBetween(10, 100), "master");
    PendingClusterStatesQueue queue = createQueueWithStates(states);
    assertThat(queue.stats().getTotal(), equalTo(states.size()));
    assertThat(queue.stats().getPending(), equalTo(states.size()));
    assertThat(queue.stats().getCommitted(), equalTo(0));

    List<ClusterStateContext> committedContexts = randomCommitStates(queue);
    assertThat(queue.stats().getTotal(), equalTo(states.size()));
    assertThat(queue.stats().getPending(), equalTo(states.size() - committedContexts.size()));
    assertThat(queue.stats().getCommitted(), equalTo(committedContexts.size()));

    ClusterState highestCommitted = null;
    for (ClusterStateContext context : committedContexts) {
      if (highestCommitted == null || context.state.supersedes(highestCommitted)) {
        highestCommitted = context.state;
      }
    }
    assert highestCommitted != null;

    queue.markAsProcessed(highestCommitted);
    assertThat(
        (long) queue.stats().getTotal(), equalTo(states.size() - (1 + highestCommitted.version())));
    assertThat(
        (long) queue.stats().getPending(),
        equalTo(states.size() - (1 + highestCommitted.version())));
    assertThat(queue.stats().getCommitted(), equalTo(0));
  }
  public void testProcessedStateCleansStatesFromOtherMasters() {
    List<ClusterState> states =
        randomStates(scaledRandomIntBetween(10, 300), "master1", "master2", "master3", "master4");
    PendingClusterStatesQueue queue = createQueueWithStates(states);
    List<ClusterStateContext> committedContexts = randomCommitStates(queue);
    ClusterState randomCommitted = randomFrom(committedContexts).state;
    queue.markAsProcessed(randomCommitted);
    final String processedMaster = randomCommitted.nodes().getMasterNodeId();

    // now check that queue doesn't contain anything pending from another master
    for (ClusterStateContext context : queue.pendingStates) {
      final String pendingMaster = context.state.nodes().getMasterNodeId();
      assertThat(
          "found a cluster state from ["
              + pendingMaster
              + "], after a state from ["
              + processedMaster
              + "] was processed",
          pendingMaster,
          equalTo(processedMaster));
    }
    // and check all committed contexts from another master were failed
    for (ClusterStateContext context : committedContexts) {
      if (context.state.nodes().getMasterNodeId().equals(processedMaster) == false) {
        assertThat(((MockListener) context.listener).failure, notNullValue());
      }
    }
  }
  public void testSimpleQueueSameMaster() {
    final int numUpdates = scaledRandomIntBetween(50, 100);
    List<ClusterState> states = randomStates(numUpdates, "master");
    Collections.shuffle(states, random());
    PendingClusterStatesQueue queue;
    queue = createQueueWithStates(states);

    // no state is committed yet
    assertThat(queue.getNextClusterStateToProcess(), nullValue());

    ClusterState highestCommitted = null;
    for (ClusterStateContext context : randomCommitStates(queue)) {
      if (highestCommitted == null || context.state.supersedes(highestCommitted)) {
        highestCommitted = context.state;
      }
    }

    assertThat(queue.getNextClusterStateToProcess(), sameInstance(highestCommitted));

    queue.markAsProcessed(highestCommitted);

    // now there is nothing more to process
    assertThat(queue.getNextClusterStateToProcess(), nullValue());
  }