public void testDroppingStatesAtCapacity() { List<ClusterState> states = randomStates(scaledRandomIntBetween(10, 300), "master1", "master2", "master3", "master4"); Collections.shuffle(states, random()); // insert half of the states final int numberOfStateToDrop = states.size() / 2; List<ClusterState> stateToDrop = states.subList(0, numberOfStateToDrop); final int queueSize = states.size() - numberOfStateToDrop; PendingClusterStatesQueue queue = createQueueWithStates(stateToDrop, queueSize); List<ClusterStateContext> committedContexts = randomCommitStates(queue); for (ClusterState state : states.subList(numberOfStateToDrop, states.size())) { queue.addPending(state); } assertThat(queue.pendingClusterStates().length, equalTo(queueSize)); // check all committed states got a failure due to the drop for (ClusterStateContext context : committedContexts) { assertThat(((MockListener) context.listener).failure, notNullValue()); } // all states that should have dropped are indeed dropped. for (ClusterState state : stateToDrop) { assertThat(queue.findState(state.stateUUID()), nullValue()); } }
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()); } } }
PendingClusterStatesQueue createQueueWithStates(List<ClusterState> states, int maxQueueSize) { PendingClusterStatesQueue queue; queue = new PendingClusterStatesQueue(logger, maxQueueSize); for (ClusterState state : states) { queue.addPending(state); } return queue; }
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 testFailedStateCleansSupersededStatesOnly() { List<ClusterState> states = randomStates(scaledRandomIntBetween(10, 50), "master1", "master2", "master3", "master4"); PendingClusterStatesQueue queue = createQueueWithStates(states); List<ClusterStateContext> committedContexts = randomCommitStates(queue); ClusterState toFail = randomFrom(committedContexts).state; queue.markAsFailed(toFail, new ElasticsearchException("boo!")); final Map<String, ClusterStateContext> committedContextsById = new HashMap<>(); for (ClusterStateContext context : committedContexts) { committedContextsById.put(context.stateUUID(), context); } // now check that queue doesn't contain superseded states for (ClusterStateContext context : queue.pendingStates) { if (context.committed()) { assertFalse( "found a committed cluster state, which is superseded by a failed state.\nFound:" + context.state + "\nfailed:" + toFail, toFail.supersedes(context.state)); } } // check no state has been erroneously removed for (ClusterState state : states) { ClusterStateContext pendingContext = queue.findState(state.stateUUID()); if (pendingContext != null) { continue; } if (state.equals(toFail)) { continue; } assertThat( "non-committed states should never be removed", committedContextsById, hasKey(state.stateUUID())); final ClusterStateContext context = committedContextsById.get(state.stateUUID()); assertThat( "removed state is not superseded by failed state. \nRemoved state:" + context + "\nfailed: " + toFail, toFail.supersedes(context.state), equalTo(true)); assertThat( "removed state was failed with wrong exception", ((MockListener) context.listener).failure, notNullValue()); assertThat( "removed state was failed with wrong exception", ((MockListener) context.listener).failure.getMessage(), containsString("boo")); } }
protected List<ClusterStateContext> randomCommitStates(PendingClusterStatesQueue queue) { List<ClusterStateContext> committedContexts = new ArrayList<>(); for (int iter = randomInt(queue.pendingStates.size() - 1); iter >= 0; iter--) { ClusterState state = queue.markAsCommitted(randomFrom(queue.pendingStates).stateUUID(), new MockListener()); if (state != null) { // null cluster state means we committed twice committedContexts.add(queue.findState(state.stateUUID())); } } return committedContexts; }
public void testFailAllAndClear() { List<ClusterState> states = randomStates(scaledRandomIntBetween(10, 50), "master1", "master2", "master3", "master4"); PendingClusterStatesQueue queue = createQueueWithStates(states); List<ClusterStateContext> committedContexts = randomCommitStates(queue); queue.failAllStatesAndClear(new ElasticsearchException("boo!")); assertThat(queue.pendingStates, empty()); assertThat(queue.getNextClusterStateToProcess(), nullValue()); for (ClusterStateContext context : committedContexts) { assertThat( "state was failed with wrong exception", ((MockListener) context.listener).failure, notNullValue()); assertThat( "state was failed with wrong exception", ((MockListener) context.listener).failure.getMessage(), containsString("boo")); } }
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()); }
public void testSelectNextStateToProcess_empty() { PendingClusterStatesQueue queue = new PendingClusterStatesQueue(logger, randomIntBetween(1, 200)); assertThat(queue.getNextClusterStateToProcess(), nullValue()); }