|
37 | 37 | import org.elasticsearch.core.Releasable;
|
38 | 38 | import org.elasticsearch.core.Tuple;
|
39 | 39 | import org.elasticsearch.gateway.GatewayService;
|
| 40 | +import org.elasticsearch.index.Index; |
40 | 41 | import org.elasticsearch.index.IndexVersion;
|
41 | 42 | import org.elasticsearch.index.shard.ShardId;
|
42 | 43 | import org.elasticsearch.test.MockLog;
|
@@ -1337,6 +1338,66 @@ public void testSkipDiskThresholdMonitorWhenStateNotRecovered() {
|
1337 | 1338 | assertNull(result2.v2());
|
1338 | 1339 | }
|
1339 | 1340 |
|
| 1341 | + private void doTestSkipNodesNotInRoutingTable(boolean sourceNodeInTable, boolean targetNodeInTable) { |
| 1342 | + Metadata.Builder metadataBuilder = Metadata.builder() |
| 1343 | + .put(IndexMetadata.builder("test").settings(settings(IndexVersion.current())).numberOfShards(1).numberOfReplicas(1)) |
| 1344 | + .putCustom( |
| 1345 | + NodesShutdownMetadata.TYPE, |
| 1346 | + new NodesShutdownMetadata( |
| 1347 | + Collections.singletonMap( |
| 1348 | + "node1", |
| 1349 | + SingleNodeShutdownMetadata.builder() |
| 1350 | + .setNodeId("node1") |
| 1351 | + .setNodeEphemeralId("node1") |
| 1352 | + .setReason("testing") |
| 1353 | + .setType(SingleNodeShutdownMetadata.Type.REPLACE) |
| 1354 | + .setTargetNodeName("node3") |
| 1355 | + .setStartedAtMillis(randomNonNegativeLong()) |
| 1356 | + .build() |
| 1357 | + ) |
| 1358 | + ) |
| 1359 | + ); |
| 1360 | + |
| 1361 | + final Metadata metadata = metadataBuilder.build(); |
| 1362 | + final RoutingTable routingTable = RoutingTable.builder(TestShardRoutingRoleStrategies.DEFAULT_ROLE_ONLY) |
| 1363 | + .addAsNew(metadata.index("test")) |
| 1364 | + .build(); |
| 1365 | + DiscoveryNodes.Builder discoveryNodes = DiscoveryNodes.builder().add(newNormalNode("node2", "node2")); |
| 1366 | + // node1 which is replaced by node3 may or may not be in the cluster |
| 1367 | + if (sourceNodeInTable) { |
| 1368 | + discoveryNodes.add(newNormalNode("node1", "node1")); |
| 1369 | + } |
| 1370 | + // node3 which is to replace node1 may or may not be in the cluster |
| 1371 | + if (targetNodeInTable) { |
| 1372 | + discoveryNodes.add(newNormalNode("node3", "node3")); |
| 1373 | + } |
| 1374 | + final ClusterState clusterState = applyStartedShardsUntilNoChange( |
| 1375 | + ClusterState.builder(ClusterName.DEFAULT).metadata(metadata).routingTable(routingTable).nodes(discoveryNodes).build(), |
| 1376 | + createAllocationService(Settings.EMPTY) |
| 1377 | + ); |
| 1378 | + final Index testIndex = routingTable.index("test").getIndex(); |
| 1379 | + |
| 1380 | + Map<String, DiskUsage> diskUsages = new HashMap<>(); |
| 1381 | + diskUsages.put("node1", new DiskUsage("node1", "node1", "/foo/bar", 100, between(0, 4))); |
| 1382 | + diskUsages.put("node2", new DiskUsage("node2", "node2", "/foo/bar", 100, between(0, 4))); |
| 1383 | + final ClusterInfo clusterInfo = clusterInfo(diskUsages); |
| 1384 | + Tuple<Boolean, Set<String>> result = runDiskThresholdMonitor(clusterState, clusterInfo); |
| 1385 | + assertTrue(result.v1()); // reroute on new nodes |
| 1386 | + assertEquals(Set.of("test"), result.v2()); |
| 1387 | + } |
| 1388 | + |
| 1389 | + public void testSkipReplaceSourceNodeNotInRoutingTable() { |
| 1390 | + doTestSkipNodesNotInRoutingTable(false, true); |
| 1391 | + } |
| 1392 | + |
| 1393 | + public void testSkipReplaceTargetNodeNotInRoutingTable() { |
| 1394 | + doTestSkipNodesNotInRoutingTable(true, false); |
| 1395 | + } |
| 1396 | + |
| 1397 | + public void testSkipReplaceSourceAndTargetNodesNotInRoutingTable() { |
| 1398 | + doTestSkipNodesNotInRoutingTable(false, false); |
| 1399 | + } |
| 1400 | + |
1340 | 1401 | // Runs a disk threshold monitor with a given cluster state and cluster info and returns whether a reroute should
|
1341 | 1402 | // happen and any indices that should be marked as read-only.
|
1342 | 1403 | private Tuple<Boolean, Set<String>> runDiskThresholdMonitor(ClusterState clusterState, ClusterInfo clusterInfo) {
|
|
0 commit comments