diff --git a/server/src/test/java/org/elasticsearch/cluster/coordination/NodeJoinTests.java b/server/src/test/java/org/elasticsearch/cluster/coordination/NodeJoinTests.java index e89fad4e5860c..5d201598004db 100644 --- a/server/src/test/java/org/elasticsearch/cluster/coordination/NodeJoinTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/coordination/NodeJoinTests.java @@ -204,44 +204,58 @@ private void joinNodeAndRun(final JoinRequest joinRequest) { public void testJoinWithHigherTermElectsLeader() { DiscoveryNode node0 = newNode(0, true); DiscoveryNode node1 = newNode(1, true); - setupFakeMasterServiceAndCoordinator(1, initialState(false, node0, 1, 1, + long initialTerm = randomLongBetween(1, 10); + long initialVersion = randomLongBetween(1, 10); + setupFakeMasterServiceAndCoordinator(initialTerm, initialState(false, node0, initialTerm, initialVersion, new VotingConfiguration(Collections.singleton(randomFrom(node0, node1).getId())))); assertFalse(isLocalNodeElectedMaster()); - joinNodeAndRun(new JoinRequest(node1, Optional.of(new Join(node1, node0, 2, 1, 1)))); + long newTerm = initialTerm + randomLongBetween(1, 10); + joinNodeAndRun(new JoinRequest(node1, Optional.of(new Join(node1, node0, newTerm, initialTerm, initialVersion)))); assertTrue(isLocalNodeElectedMaster()); } public void testJoinWithHigherTermButBetterStateGetsRejected() { DiscoveryNode node0 = newNode(0, true); DiscoveryNode node1 = newNode(1, true); - setupFakeMasterServiceAndCoordinator(1, initialState(false, node0, 1, 1, + long initialTerm = randomLongBetween(1, 10); + long initialVersion = randomLongBetween(1, 10); + setupFakeMasterServiceAndCoordinator(initialTerm, initialState(false, node0, initialTerm, initialVersion, new VotingConfiguration(Collections.singleton(node1.getId())))); assertFalse(isLocalNodeElectedMaster()); + long newTerm = initialTerm + randomLongBetween(1, 10); + long higherVersion = initialVersion + randomLongBetween(1, 10); expectThrows(CoordinationStateRejectedException.class, - () -> joinNodeAndRun(new JoinRequest(node1, Optional.of(new Join(node1, node0, 2, 2, 2))))); + () -> joinNodeAndRun(new JoinRequest(node1, Optional.of(new Join(node1, node0, newTerm, initialTerm, higherVersion))))); assertFalse(isLocalNodeElectedMaster()); } public void testJoinWithHigherTermButBetterStateStillElectsMasterThroughSelfJoin() { DiscoveryNode node0 = newNode(0, true); DiscoveryNode node1 = newNode(1, true); - setupFakeMasterServiceAndCoordinator(1, initialState(false, node0, 1, 1, + long initialTerm = randomLongBetween(1, 10); + long initialVersion = randomLongBetween(1, 10); + setupFakeMasterServiceAndCoordinator(initialTerm, initialState(false, node0, initialTerm, initialVersion, new VotingConfiguration(Collections.singleton(node0.getId())))); assertFalse(isLocalNodeElectedMaster()); - joinNodeAndRun(new JoinRequest(node1, Optional.of(new Join(node1, node0, 2, 2, 2)))); + long newTerm = initialTerm + randomLongBetween(1, 10); + long higherVersion = initialVersion + randomLongBetween(1, 10); + joinNodeAndRun(new JoinRequest(node1, Optional.of(new Join(node1, node0, newTerm, initialTerm, higherVersion)))); assertTrue(isLocalNodeElectedMaster()); } public void testJoinElectedLeader() { DiscoveryNode node0 = newNode(0, true); DiscoveryNode node1 = newNode(1, true); - setupFakeMasterServiceAndCoordinator(1, initialState(false, node0, 1, 1, + long initialTerm = randomLongBetween(1, 10); + long initialVersion = randomLongBetween(1, 10); + setupFakeMasterServiceAndCoordinator(initialTerm, initialState(false, node0, initialTerm, initialVersion, new VotingConfiguration(Collections.singleton(node0.getId())))); assertFalse(isLocalNodeElectedMaster()); - joinNodeAndRun(new JoinRequest(node0, Optional.of(new Join(node0, node0, 2, 1, 1)))); + long newTerm = initialTerm + randomLongBetween(1, 10); + joinNodeAndRun(new JoinRequest(node0, Optional.of(new Join(node0, node0, newTerm, initialTerm, initialVersion)))); assertTrue(isLocalNodeElectedMaster()); assertFalse(clusterStateHasNode(node1)); - joinNodeAndRun(new JoinRequest(node1, Optional.of(new Join(node1, node0, 2, 1, 1)))); + joinNodeAndRun(new JoinRequest(node1, Optional.of(new Join(node1, node0, newTerm, initialTerm, initialVersion)))); assertTrue(isLocalNodeElectedMaster()); assertTrue(clusterStateHasNode(node1)); } @@ -249,14 +263,17 @@ public void testJoinElectedLeader() { public void testJoinAccumulation() { DiscoveryNode node0 = newNode(0, true); DiscoveryNode node1 = newNode(1, true); - setupFakeMasterServiceAndCoordinator(1, initialState(false, node0, 1, 1, + long initialTerm = randomLongBetween(1, 10); + long initialVersion = randomLongBetween(1, 10); + setupFakeMasterServiceAndCoordinator(initialTerm, initialState(false, node0, initialTerm, initialVersion, new VotingConfiguration(Collections.singleton(node1.getId())))); assertFalse(isLocalNodeElectedMaster()); - SimpleFuture fut = joinNodeAsync(new JoinRequest(node0, Optional.of(new Join(node0, node0, 2, 1, 1)))); + long newTerm = initialTerm + randomLongBetween(1, 10); + SimpleFuture fut = joinNodeAsync(new JoinRequest(node0, Optional.of(new Join(node0, node0, newTerm, initialTerm, initialVersion)))); deterministicTaskQueue.runAllTasks(random()); assertFalse(fut.isDone()); assertFalse(isLocalNodeElectedMaster()); - joinNodeAndRun(new JoinRequest(node1, Optional.of(new Join(node1, node0, 2, 1, 1)))); + joinNodeAndRun(new JoinRequest(node1, Optional.of(new Join(node1, node0, newTerm, initialTerm, initialVersion)))); assertTrue(isLocalNodeElectedMaster()); assertTrue(clusterStateHasNode(node1)); FutureUtils.get(fut); @@ -265,15 +282,19 @@ public void testJoinAccumulation() { public void testJoinFollowerFails() { DiscoveryNode node0 = newNode(0, true); DiscoveryNode node1 = newNode(1, true); - setupFakeMasterServiceAndCoordinator(1, initialState(false, node0, 1, 1, + long initialTerm = randomLongBetween(1, 10); + long initialVersion = randomLongBetween(1, 10); + setupFakeMasterServiceAndCoordinator(initialTerm, initialState(false, node0, initialTerm, initialVersion, new VotingConfiguration(Collections.singleton(node0.getId())))); - coordinator.coordinationState.get().handleStartJoin(new StartJoinRequest(node1, 2)); + long newTerm = initialTerm + randomLongBetween(1, 10); + coordinator.coordinationState.get().handleStartJoin(new StartJoinRequest(node1, newTerm)); synchronized (coordinator.mutex) { coordinator.becomeFollower("test", node1); } assertFalse(isLocalNodeElectedMaster()); assertThat(expectThrows(CoordinationStateRejectedException.class, - () -> joinNodeAndRun(new JoinRequest(node1, Optional.of(new Join(node1, node0, 2, 1, 1))))).getMessage(), + () -> joinNodeAndRun(new JoinRequest(node1, + Optional.of(new Join(node1, node0, newTerm, initialTerm, initialVersion))))).getMessage(), containsString("join target is a follower")); assertFalse(isLocalNodeElectedMaster()); } @@ -281,9 +302,12 @@ public void testJoinFollowerFails() { public void testBecomeFollowerFailsPendingJoin() { DiscoveryNode node0 = newNode(0, true); DiscoveryNode node1 = newNode(1, true); - setupFakeMasterServiceAndCoordinator(1, initialState(false, node0, 1, 1, + long initialTerm = randomLongBetween(1, 10); + long initialVersion = randomLongBetween(1, 10); + setupFakeMasterServiceAndCoordinator(initialTerm, initialState(false, node0, initialTerm, initialVersion, new VotingConfiguration(Collections.singleton(node1.getId())))); - SimpleFuture fut = joinNodeAsync(new JoinRequest(node0, Optional.of(new Join(node0, node0, 2, 1, 1)))); + long newTerm = initialTerm + randomLongBetween(1, 10); + SimpleFuture fut = joinNodeAsync(new JoinRequest(node0, Optional.of(new Join(node0, node0, newTerm, initialTerm, initialVersion)))); deterministicTaskQueue.runAllTasks(random()); assertFalse(fut.isDone()); assertFalse(isLocalNodeElectedMaster()); @@ -307,7 +331,10 @@ public void testConcurrentJoining() { logger.info("Voting configuration: {}", votingConfiguration); DiscoveryNode localNode = nodes.get(0); - setupRealMasterServiceAndCoordinator(1, initialState(false, localNode, 1, 1, votingConfiguration)); + long initialTerm = randomLongBetween(1, 10); + long initialVersion = randomLongBetween(1, 10); + setupRealMasterServiceAndCoordinator(initialTerm, initialState(false, localNode, initialTerm, initialVersion, votingConfiguration)); + long newTerm = initialTerm + randomLongBetween(1, 10); // we need at least a quorum of voting nodes with a correct term and worse state List successfulNodes; @@ -319,7 +346,8 @@ public void testConcurrentJoining() { logger.info("Successful voting nodes: {}", successfulNodes); List correctJoinRequests = successfulNodes.stream().map( - node -> new JoinRequest(node, Optional.of(new Join(node, localNode, 2, 1, 1)))).collect(Collectors.toList()); + node -> new JoinRequest(node, Optional.of(new Join(node, localNode, newTerm, initialTerm, initialVersion)))) + .collect(Collectors.toList()); List possiblyUnsuccessfulNodes = new ArrayList<>(nodes); possiblyUnsuccessfulNodes.removeAll(successfulNodes); @@ -329,13 +357,16 @@ public void testConcurrentJoining() { List possiblyFailingJoinRequests = possiblyUnsuccessfulNodes.stream().map(node -> { if (randomBoolean()) { // a correct request - return new JoinRequest(node, Optional.of(new Join(node, localNode, 2, 1, 1))); + return new JoinRequest(node, Optional.of(new Join(node, localNode, + newTerm, initialTerm, initialVersion))); } else if (randomBoolean()) { // term too low - return new JoinRequest(node, Optional.of(new Join(node, localNode, 1, 1, 1))); + return new JoinRequest(node, Optional.of(new Join(node, localNode, + randomLongBetween(0, initialTerm), initialTerm, initialVersion))); } else { // better state - return new JoinRequest(node, Optional.of(new Join(node, localNode, 2, 2, 2))); + return new JoinRequest(node, Optional.of(new Join(node, localNode, + newTerm, initialTerm, initialVersion + randomLongBetween(1, 10)))); } }).collect(Collectors.toList());