Skip to content

Commit ef8f45b

Browse files
committed
Add more unit tests
1 parent 7dcb690 commit ef8f45b

File tree

1 file changed

+93
-6
lines changed

1 file changed

+93
-6
lines changed

server/src/test/java/org/elasticsearch/cluster/routing/allocation/allocator/UndesiredAllocationsTrackerTests.java

Lines changed: 93 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
package org.elasticsearch.cluster.routing.allocation.allocator;
1111

12+
import org.elasticsearch.action.support.replication.ClusterStateCreationUtils;
13+
import org.elasticsearch.cluster.ClusterState;
1214
import org.elasticsearch.cluster.metadata.ProjectId;
1315
import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
1416
import org.elasticsearch.cluster.node.DiscoveryNodes;
@@ -22,6 +24,7 @@
2224
import org.elasticsearch.common.settings.ClusterSettings;
2325
import org.elasticsearch.common.settings.Settings;
2426
import org.elasticsearch.common.time.AdvancingTimeProvider;
27+
import org.elasticsearch.core.Nullable;
2528
import org.elasticsearch.index.Index;
2629
import org.elasticsearch.index.shard.ShardId;
2730
import org.elasticsearch.test.ESTestCase;
@@ -32,6 +35,46 @@
3235

3336
public class UndesiredAllocationsTrackerTests extends ESTestCase {
3437

38+
public void testShardsArePrunedWhenRemovedFromRoutingTable() {
39+
final int primaryShards = randomIntBetween(2, 5);
40+
final int numberOfIndices = randomIntBetween(2, 5);
41+
final int numberOfNodes = randomIntBetween(2, 5);
42+
43+
final var clusterSettings = ClusterSettings.createBuiltInClusterSettings(
44+
Settings.builder()
45+
.put(UndesiredAllocationsTracker.MAX_UNDESIRED_ALLOCATIONS_TO_TRACK.getKey(), numberOfIndices * primaryShards)
46+
.build()
47+
);
48+
final var advancingTimeProvider = new AdvancingTimeProvider();
49+
final var undesiredAllocationsTracker = new UndesiredAllocationsTracker(clusterSettings, advancingTimeProvider);
50+
51+
final var indexNames = IntStream.range(0, numberOfIndices).mapToObj(i -> "index-" + i).toArray(String[]::new);
52+
final var state = ClusterStateCreationUtils.state(numberOfNodes, indexNames, primaryShards);
53+
final var routingNodes = RoutingNodes.immutable(state.globalRoutingTable(), state.nodes());
54+
55+
// Mark all primary shards as undesired
56+
routingNodes.forEach(routingNode -> {
57+
routingNode.forEach(shardRouting -> {
58+
if (shardRouting.primary()) {
59+
undesiredAllocationsTracker.trackUndesiredAllocation(shardRouting);
60+
}
61+
});
62+
});
63+
assertEquals(numberOfIndices * primaryShards, undesiredAllocationsTracker.getUndesiredAllocations().size());
64+
65+
// Simulate an index being deleted
66+
ClusterState stateWithIndexRemoved = removeRandomIndex(state);
67+
68+
// Run cleanup with new RoutingNodes
69+
undesiredAllocationsTracker.cleanup(
70+
RoutingNodes.immutable(stateWithIndexRemoved.globalRoutingTable(), stateWithIndexRemoved.nodes())
71+
);
72+
assertEquals((numberOfIndices - 1) * primaryShards, undesiredAllocationsTracker.getUndesiredAllocations().size());
73+
undesiredAllocationsTracker.getUndesiredAllocations()
74+
.iterator()
75+
.forEachRemaining(olc -> assertNotNull(stateWithIndexRemoved.routingTable(ProjectId.DEFAULT).index(olc.key.index())));
76+
}
77+
3578
public void testNewestRecordsArePurgedWhenLimitIsDecreased() {
3679
final var initialMaximum = randomIntBetween(10, 20);
3780
final var clusterSettings = ClusterSettings.createBuiltInClusterSettings(
@@ -42,17 +85,17 @@ public void testNewestRecordsArePurgedWhenLimitIsDecreased() {
4285
final var indexName = randomIdentifier();
4386
final var index = new Index(indexName, indexName);
4487
final var indexRoutingTableBuilder = IndexRoutingTable.builder(index);
45-
final var discoveryNodesBuilder = DiscoveryNodes.builder();
88+
final var discoveryNodes = randomDiscoveryNodes(randomIntBetween(initialMaximum / 2, initialMaximum));
4689

4790
// The shards with the lowest IDs will have the earliest timestamps
4891
for (int i = 0; i < initialMaximum; i++) {
49-
final var routing = createAssignedRouting(index, i, discoveryNodesBuilder);
92+
final var routing = createAssignedRouting(index, i, discoveryNodes);
5093
indexRoutingTableBuilder.addShard(routing);
5194
undesiredAllocationsTracker.trackUndesiredAllocation(routing);
5295
}
5396
final var routingNodes = RoutingNodes.immutable(
5497
GlobalRoutingTable.builder().put(ProjectId.DEFAULT, RoutingTable.builder().add(indexRoutingTableBuilder).build()).build(),
55-
discoveryNodesBuilder.build()
98+
discoveryNodes
5699
);
57100

58101
// Reduce the maximum
@@ -73,9 +116,45 @@ public void testNewestRecordsArePurgedWhenLimitIsDecreased() {
73116
assertEquals(IntStream.range(0, reducedMaximum).boxed().collect(Collectors.toSet()), remainingShardIds);
74117
}
75118

76-
private ShardRouting createAssignedRouting(Index index, int shardId, DiscoveryNodes.Builder discoveryNodesBuilder) {
77-
final var nodeId = randomAlphaOfLength(10);
78-
discoveryNodesBuilder.add(DiscoveryNodeUtils.create(nodeId));
119+
public void testCannotTrackMoreShardsThanTheLimit() {
120+
final int maxToTrack = randomIntBetween(1, 10);
121+
final var clusterSettings = ClusterSettings.createBuiltInClusterSettings(
122+
Settings.builder().put(UndesiredAllocationsTracker.MAX_UNDESIRED_ALLOCATIONS_TO_TRACK.getKey(), maxToTrack).build()
123+
);
124+
final var advancingTimeProvider = new AdvancingTimeProvider();
125+
final var undesiredAllocationsTracker = new UndesiredAllocationsTracker(clusterSettings, advancingTimeProvider);
126+
final var index = new Index(randomIdentifier(), randomIdentifier());
127+
128+
final int shardsToAdd = randomIntBetween(maxToTrack + 1, maxToTrack * 2);
129+
for (int i = 0; i < shardsToAdd; i++) {
130+
final var routing = createAssignedRouting(index, i);
131+
undesiredAllocationsTracker.trackUndesiredAllocation(routing);
132+
}
133+
134+
// Only the first {maxToTrack} shards should be tracked
135+
assertEquals(maxToTrack, undesiredAllocationsTracker.getUndesiredAllocations().size());
136+
final var trackedShardIds = StreamSupport.stream(undesiredAllocationsTracker.getUndesiredAllocations().spliterator(), false)
137+
.map(olc -> olc.key.shardId().id())
138+
.collect(Collectors.toSet());
139+
assertEquals(IntStream.range(0, maxToTrack).boxed().collect(Collectors.toSet()), trackedShardIds);
140+
}
141+
142+
private ClusterState removeRandomIndex(ClusterState state) {
143+
RoutingTable originalRoutingTable = state.routingTable(ProjectId.DEFAULT);
144+
RoutingTable updatedRoutingTable = RoutingTable.builder(originalRoutingTable)
145+
.remove(randomFrom(originalRoutingTable.indicesRouting().keySet()))
146+
.build();
147+
return ClusterState.builder(state)
148+
.routingTable(GlobalRoutingTable.builder().put(ProjectId.DEFAULT, updatedRoutingTable).build())
149+
.build();
150+
}
151+
152+
private ShardRouting createAssignedRouting(Index index, int shardId) {
153+
return createAssignedRouting(index, shardId, null);
154+
}
155+
156+
private ShardRouting createAssignedRouting(Index index, int shardId, @Nullable DiscoveryNodes discoveryNodes) {
157+
final var nodeId = discoveryNodes == null ? randomAlphaOfLength(10) : randomFrom(discoveryNodes.getNodes().keySet());
79158
return ShardRouting.newUnassigned(
80159
new ShardId(index, shardId),
81160
true,
@@ -84,4 +163,12 @@ private ShardRouting createAssignedRouting(Index index, int shardId, DiscoveryNo
84163
randomFrom(ShardRouting.Role.DEFAULT, ShardRouting.Role.INDEX_ONLY)
85164
).initialize(nodeId, null, randomNonNegativeLong());
86165
}
166+
167+
private DiscoveryNodes randomDiscoveryNodes(int numberOfNodes) {
168+
final var nodes = DiscoveryNodes.builder();
169+
for (int i = 0; i < numberOfNodes; i++) {
170+
nodes.add(DiscoveryNodeUtils.create("node-" + i));
171+
}
172+
return nodes.build();
173+
}
87174
}

0 commit comments

Comments
 (0)