|
36 | 36 | import org.elasticsearch.cluster.block.ClusterBlocks; |
37 | 37 | import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; |
38 | 38 | import org.elasticsearch.cluster.node.DiscoveryNode; |
| 39 | +import org.elasticsearch.cluster.node.DiscoveryNodes; |
39 | 40 | import org.elasticsearch.cluster.service.ClusterService; |
40 | 41 | import org.elasticsearch.common.settings.Settings; |
41 | 42 | import org.elasticsearch.common.transport.LocalTransportAddress; |
@@ -299,21 +300,57 @@ public void testDelegateToMaster() throws ExecutionException, InterruptedExcepti |
299 | 300 | } |
300 | 301 |
|
301 | 302 | public void testDelegateToFailingMaster() throws ExecutionException, InterruptedException { |
302 | | - boolean failsWithConnectTransportException = randomBoolean(); |
| 303 | + final boolean failsWithConnectTransportException = randomBoolean(); |
| 304 | + final boolean rejoinSameMaster = failsWithConnectTransportException && randomBoolean(); |
303 | 305 | Request request = new Request().masterNodeTimeout(TimeValue.timeValueSeconds(failsWithConnectTransportException ? 60 : 0)); |
304 | | - setState(clusterService, ClusterStateCreationUtils.state(localNode, remoteNode, allNodes)); |
| 306 | + DiscoveryNode masterNode = this.remoteNode; |
| 307 | + setState(clusterService, ClusterState.builder(ClusterStateCreationUtils.state(localNode, masterNode, allNodes)) |
| 308 | + .version(randomIntBetween(0, 10))); // use a random base version so it can go down when simulating a restart. |
305 | 309 |
|
306 | 310 | PlainActionFuture<Response> listener = new PlainActionFuture<>(); |
307 | 311 | new Action(Settings.EMPTY, "testAction", transportService, clusterService, threadPool).execute(request, listener); |
308 | 312 |
|
309 | | - assertThat(transport.capturedRequests().length, equalTo(1)); |
310 | | - CapturingTransport.CapturedRequest capturedRequest = transport.capturedRequests()[0]; |
| 313 | + CapturingTransport.CapturedRequest[] capturedRequests = transport.getCapturedRequestsAndClear(); |
| 314 | + assertThat(capturedRequests.length, equalTo(1)); |
| 315 | + CapturingTransport.CapturedRequest capturedRequest = capturedRequests[0]; |
311 | 316 | assertTrue(capturedRequest.node.isMasterNode()); |
312 | 317 | assertThat(capturedRequest.request, equalTo(request)); |
313 | 318 | assertThat(capturedRequest.action, equalTo("testAction")); |
314 | 319 |
|
315 | | - if (failsWithConnectTransportException) { |
316 | | - transport.handleRemoteError(capturedRequest.requestId, new ConnectTransportException(remoteNode, "Fake error")); |
| 320 | + if (rejoinSameMaster) { |
| 321 | + transport.handleRemoteError(capturedRequest.requestId, new ConnectTransportException(masterNode, "Fake error")); |
| 322 | + assertFalse(listener.isDone()); |
| 323 | + if (randomBoolean()) { |
| 324 | + // simulate master node removal |
| 325 | + final DiscoveryNodes.Builder nodesBuilder = DiscoveryNodes.builder(clusterService.state().nodes()); |
| 326 | + nodesBuilder.masterNodeId(null); |
| 327 | + setState(clusterService, ClusterState.builder(clusterService.state()).nodes(nodesBuilder)); |
| 328 | + } |
| 329 | + if (randomBoolean()) { |
| 330 | + // reset the same state to increment a version simulating a join of an existing node |
| 331 | + // simulating use being disconnected |
| 332 | + final DiscoveryNodes.Builder nodesBuilder = DiscoveryNodes.builder(clusterService.state().nodes()); |
| 333 | + nodesBuilder.masterNodeId(masterNode.getId()); |
| 334 | + setState(clusterService, ClusterState.builder(clusterService.state()).nodes(nodesBuilder)); |
| 335 | + } else { |
| 336 | + // simulate master restart followed by a state recovery - this will reset the cluster state version |
| 337 | + final DiscoveryNodes.Builder nodesBuilder = DiscoveryNodes.builder(clusterService.state().nodes()); |
| 338 | + nodesBuilder.remove(masterNode); |
| 339 | + masterNode = new DiscoveryNode(masterNode.getId(), masterNode.getAddress(), masterNode.getVersion()); |
| 340 | + nodesBuilder.add(masterNode); |
| 341 | + nodesBuilder.masterNodeId(masterNode.getId()); |
| 342 | + final ClusterState.Builder builder = ClusterState.builder(clusterService.state()).nodes(nodesBuilder); |
| 343 | + setState(clusterService, builder.version(0)); |
| 344 | + } |
| 345 | + assertFalse(listener.isDone()); |
| 346 | + capturedRequests = transport.getCapturedRequestsAndClear(); |
| 347 | + assertThat(capturedRequests.length, equalTo(1)); |
| 348 | + capturedRequest = capturedRequests[0]; |
| 349 | + assertTrue(capturedRequest.node.isMasterNode()); |
| 350 | + assertThat(capturedRequest.request, equalTo(request)); |
| 351 | + assertThat(capturedRequest.action, equalTo("testAction")); |
| 352 | + } else if (failsWithConnectTransportException) { |
| 353 | + transport.handleRemoteError(capturedRequest.requestId, new ConnectTransportException(masterNode, "Fake error")); |
317 | 354 | assertFalse(listener.isDone()); |
318 | 355 | setState(clusterService, ClusterStateCreationUtils.state(localNode, localNode, allNodes)); |
319 | 356 | assertTrue(listener.isDone()); |
|
0 commit comments