Skip to content

Commit b756f6c

Browse files
authored
Test the Cluster Shard Allocation Explain API with closed indices (#38631)
This pull request modifies the `ClusterAllocationExplainIT` test suite so that it always runs the tests with opened and closed indices. The only test that was not adapted for closed indices is `testAllocationFilteringOnIndexCreation` because we don't allow to directly create indices in the closed state. Relates to #33888
1 parent 43f555b commit b756f6c

File tree

2 files changed

+101
-26
lines changed

2 files changed

+101
-26
lines changed

rest-api-spec/src/main/resources/rest-api-spec/test/cluster.allocation_explain/10_basic.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,47 @@
5353
- match: { primary: false }
5454
- is_true: cluster_info
5555
- is_true: can_allocate
56+
57+
58+
---
59+
"Cluster shard allocation explanation test with a closed index":
60+
- skip:
61+
version: " - 7.99.99"
62+
reason: closed indices are replicated starting version 8.0.0
63+
64+
- do:
65+
indices.create:
66+
index: test_closed
67+
body: { "settings": { "index.number_of_shards": 1, "index.number_of_replicas": 0 } }
68+
69+
- match: { acknowledged: true }
70+
71+
- do:
72+
cluster.health:
73+
index: test_closed
74+
wait_for_status: green
75+
76+
- do:
77+
indices.close:
78+
index: test_closed
79+
80+
- match: { acknowledged: true }
81+
82+
- do:
83+
cluster.health:
84+
index: test_closed
85+
wait_for_status: green
86+
87+
- do:
88+
cluster.allocation_explain:
89+
body: { "index": "test_closed", "shard": 0, "primary": true }
90+
91+
- match: { current_state: "started" }
92+
- is_true: current_node.id
93+
- match: { index: "test_closed" }
94+
- match: { shard: 0 }
95+
- match: { primary: true }
96+
- is_true: can_remain_on_current_node
97+
- is_true: can_rebalance_cluster
98+
- is_true: can_rebalance_to_other_node
99+
- is_true: rebalance_explanation

server/src/test/java/org/elasticsearch/action/admin/cluster/allocation/ClusterAllocationExplainIT.java

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@
1919

2020
package org.elasticsearch.action.admin.cluster.allocation;
2121

22+
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
2223
import org.elasticsearch.action.support.ActiveShardCount;
2324
import org.elasticsearch.cluster.ClusterInfo;
2425
import org.elasticsearch.cluster.ClusterState;
26+
import org.elasticsearch.cluster.health.ClusterHealthStatus;
27+
import org.elasticsearch.cluster.metadata.IndexMetaData;
2528
import org.elasticsearch.cluster.node.DiscoveryNode;
2629
import org.elasticsearch.cluster.routing.ShardRoutingState;
2730
import org.elasticsearch.cluster.routing.UnassignedInfo;
@@ -32,8 +35,10 @@
3235
import org.elasticsearch.cluster.routing.allocation.MoveDecision;
3336
import org.elasticsearch.cluster.routing.allocation.NodeAllocationResult;
3437
import org.elasticsearch.cluster.routing.allocation.decider.Decision;
38+
import org.elasticsearch.common.Priority;
3539
import org.elasticsearch.common.Strings;
3640
import org.elasticsearch.common.settings.Settings;
41+
import org.elasticsearch.common.unit.TimeValue;
3742
import org.elasticsearch.common.util.set.Sets;
3843
import org.elasticsearch.common.xcontent.ToXContent;
3944
import org.elasticsearch.common.xcontent.XContentBuilder;
@@ -52,6 +57,7 @@
5257
import java.util.Map;
5358
import java.util.Set;
5459

60+
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
5561
import static org.hamcrest.Matchers.containsString;
5662
import static org.hamcrest.Matchers.equalTo;
5763
import static org.hamcrest.Matchers.greaterThan;
@@ -70,8 +76,7 @@ public void testUnassignedPrimaryWithExistingIndex() throws Exception {
7076
logger.info("--> starting 2 nodes");
7177
internalCluster().startNodes(2);
7278

73-
logger.info("--> creating an index with 1 primary, 0 replicas");
74-
createIndexAndIndexData(1, 0);
79+
prepareIndex(1, 0);
7580

7681
logger.info("--> stopping the node with the primary");
7782
internalCluster().stopRandomNode(InternalTestCluster.nameFilter(primaryNodeName()));
@@ -149,8 +154,7 @@ public void testUnassignedReplicaDelayedAllocation() throws Exception {
149154
logger.info("--> starting 3 nodes");
150155
internalCluster().startNodes(3);
151156

152-
logger.info("--> creating an index with 1 primary, 1 replica");
153-
createIndexAndIndexData(1, 1);
157+
prepareIndex(1, 1);
154158
logger.info("--> stopping the node with the replica");
155159
internalCluster().stopRandomNode(InternalTestCluster.nameFilter(replicaNode().getName()));
156160
ensureStableCluster(2);
@@ -268,8 +272,7 @@ public void testUnassignedReplicaWithPriorCopy() throws Exception {
268272
logger.info("--> starting 3 nodes");
269273
List<String> nodes = internalCluster().startNodes(3);
270274

271-
logger.info("--> creating an index with 1 primary and 1 replica");
272-
createIndexAndIndexData(1, 1);
275+
prepareIndex(1, 1);
273276
String primaryNodeName = primaryNodeName();
274277
nodes.remove(primaryNodeName);
275278

@@ -390,7 +393,8 @@ public void testAllocationFilteringOnIndexCreation() throws Exception {
390393
internalCluster().startNodes(2);
391394

392395
logger.info("--> creating an index with 1 primary, 0 replicas, with allocation filtering so the primary can't be assigned");
393-
createIndexAndIndexData(1, 0, Settings.builder().put("index.routing.allocation.include._name", "non_existent_node").build(),
396+
prepareIndex(IndexMetaData.State.OPEN, 1, 0,
397+
Settings.builder().put("index.routing.allocation.include._name", "non_existent_node").build(),
394398
ActiveShardCount.NONE);
395399

396400
boolean includeYesDecisions = randomBoolean();
@@ -481,8 +485,7 @@ public void testAllocationFilteringPreventsShardMove() throws Exception {
481485
logger.info("--> starting 2 nodes");
482486
internalCluster().startNodes(2);
483487

484-
logger.info("--> creating an index with 1 primary and 0 replicas");
485-
createIndexAndIndexData(1, 0);
488+
prepareIndex(1, 0);
486489

487490
logger.info("--> setting up allocation filtering to prevent allocation to both nodes");
488491
client().admin().indices().prepareUpdateSettings("idx").setSettings(
@@ -591,8 +594,7 @@ public void testRebalancingNotAllowed() throws Exception {
591594
internalCluster().startNode();
592595
ensureStableCluster(1);
593596

594-
logger.info("--> creating an index with 5 shards, all allocated to the single node");
595-
createIndexAndIndexData(5, 0);
597+
prepareIndex(5, 0);
596598

597599
logger.info("--> disabling rebalancing on the index");
598600
client().admin().indices().prepareUpdateSettings("idx").setSettings(
@@ -704,8 +706,7 @@ public void testWorseBalance() throws Exception {
704706
internalCluster().startNode();
705707
ensureStableCluster(1);
706708

707-
logger.info("--> creating an index with 5 shards, all allocated to the single node");
708-
createIndexAndIndexData(5, 0);
709+
prepareIndex(5, 0);
709710

710711
logger.info("--> setting balancing threshold really high, so it won't be met");
711712
client().admin().cluster().prepareUpdateSettings().setTransientSettings(
@@ -808,8 +809,7 @@ public void testBetterBalanceButCannotAllocate() throws Exception {
808809
String firstNode = internalCluster().startNode();
809810
ensureStableCluster(1);
810811

811-
logger.info("--> creating an index with 5 shards, all allocated to the single node");
812-
createIndexAndIndexData(5, 0);
812+
prepareIndex(5, 0);
813813

814814
logger.info("--> setting up allocation filtering to only allow allocation to the current node");
815815
client().admin().indices().prepareUpdateSettings("idx").setSettings(
@@ -918,9 +918,9 @@ public void testAssignedReplicaOnSpecificNode() throws Exception {
918918
logger.info("--> starting 3 nodes");
919919
List<String> nodes = internalCluster().startNodes(3);
920920

921-
logger.info("--> creating an index with 1 primary and 2 replicas");
922921
String excludedNode = nodes.get(randomIntBetween(0, 2));
923-
createIndexAndIndexData(1, 2, Settings.builder().put("index.routing.allocation.exclude._name", excludedNode).build(),
922+
prepareIndex(randomIndexState(), 1, 2,
923+
Settings.builder().put("index.routing.allocation.exclude._name", excludedNode).build(),
924924
ActiveShardCount.from(2));
925925

926926
boolean includeYesDecisions = randomBoolean();
@@ -1019,8 +1019,7 @@ public void testCannotAllocateStaleReplicaExplanation() throws Exception {
10191019
final String replicaNode = internalCluster().startNode();
10201020
final String primaryNode = internalCluster().startNode();
10211021

1022-
logger.info("--> creating an index with 1 primary and 1 replica");
1023-
createIndexAndIndexData(1, 1,
1022+
prepareIndex(IndexMetaData.State.OPEN, 1, 1,
10241023
Settings.builder()
10251024
.put("index.routing.allocation.include._name", primaryNode)
10261025
.put("index.routing.allocation.exclude._name", masterNode)
@@ -1037,8 +1036,22 @@ public void testCannotAllocateStaleReplicaExplanation() throws Exception {
10371036
logger.info("--> stop node with the replica shard");
10381037
internalCluster().stopRandomNode(InternalTestCluster.nameFilter(replicaNode));
10391038

1040-
logger.info("--> index more data, now the replica is stale");
1041-
indexData();
1039+
final IndexMetaData.State indexState = randomIndexState();
1040+
if (indexState == IndexMetaData.State.OPEN) {
1041+
logger.info("--> index more data, now the replica is stale");
1042+
indexData();
1043+
} else {
1044+
logger.info("--> close the index, now the replica is stale");
1045+
assertAcked(client().admin().indices().prepareClose("idx"));
1046+
1047+
final ClusterHealthResponse clusterHealthResponse = client().admin().cluster().prepareHealth("idx")
1048+
.setTimeout(TimeValue.timeValueSeconds(30))
1049+
.setWaitForActiveShards(ActiveShardCount.ONE)
1050+
.setWaitForNoInitializingShards(true)
1051+
.setWaitForEvents(Priority.LANGUID)
1052+
.get();
1053+
assertThat(clusterHealthResponse.getStatus().value(), lessThanOrEqualTo(ClusterHealthStatus.YELLOW.value()));
1054+
}
10421055

10431056
logger.info("--> stop the node with the primary");
10441057
internalCluster().stopRandomNode(InternalTestCluster.nameFilter(primaryNode));
@@ -1147,21 +1160,39 @@ private ClusterAllocationExplanation runExplain(boolean primary, String nodeId,
11471160
return explanation;
11481161
}
11491162

1150-
private void createIndexAndIndexData(int numPrimaries, int numReplicas) {
1151-
createIndexAndIndexData(numPrimaries, numReplicas, Settings.EMPTY, ActiveShardCount.ALL);
1163+
private void prepareIndex(final int numPrimaries, final int numReplicas) {
1164+
prepareIndex(randomIndexState(), numPrimaries, numReplicas, Settings.EMPTY, ActiveShardCount.ALL);
11521165
}
11531166

1154-
private void createIndexAndIndexData(int numPrimaries, int numReplicas, Settings settings, ActiveShardCount activeShardCount) {
1155-
client().admin().indices().prepareCreate("idx")
1167+
private void prepareIndex(final IndexMetaData.State state, final int numPrimaries, final int numReplicas,
1168+
final Settings settings, final ActiveShardCount activeShardCount) {
1169+
1170+
logger.info("--> creating a {} index with {} primary, {} replicas", state, numPrimaries, numReplicas);
1171+
assertAcked(client().admin().indices().prepareCreate("idx")
11561172
.setSettings(Settings.builder()
11571173
.put("index.number_of_shards", numPrimaries)
11581174
.put("index.number_of_replicas", numReplicas)
11591175
.put(settings))
11601176
.setWaitForActiveShards(activeShardCount)
1161-
.get();
1177+
.get());
1178+
11621179
if (activeShardCount != ActiveShardCount.NONE) {
11631180
indexData();
11641181
}
1182+
if (state == IndexMetaData.State.CLOSE) {
1183+
assertAcked(client().admin().indices().prepareClose("idx"));
1184+
1185+
final ClusterHealthResponse clusterHealthResponse = client().admin().cluster().prepareHealth("idx")
1186+
.setTimeout(TimeValue.timeValueSeconds(30))
1187+
.setWaitForActiveShards(activeShardCount)
1188+
.setWaitForEvents(Priority.LANGUID)
1189+
.get();
1190+
assertThat(clusterHealthResponse.getStatus().value(), lessThanOrEqualTo(ClusterHealthStatus.YELLOW.value()));
1191+
}
1192+
}
1193+
1194+
private static IndexMetaData.State randomIndexState() {
1195+
return randomFrom(IndexMetaData.State.values());
11651196
}
11661197

11671198
private void indexData() {

0 commit comments

Comments
 (0)