Skip to content

Commit 802bd70

Browse files
jxie-1mridula-s109
authored andcommitted
Assert in IndexReshardingState.Split ctor that source shards are not … (elastic#134229)
* Assert in IndexReshardingState.Split ctor that source shards are not all done * Fix reshard unit tests * Remove reshard state inProgress method
1 parent e97cd59 commit 802bd70

File tree

3 files changed

+31
-29
lines changed

3 files changed

+31
-29
lines changed

server/src/main/java/org/elasticsearch/cluster/metadata/IndexReshardingState.java

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@ public static TargetShardState readFrom(StreamInput in) throws IOException {
181181
private final TargetShardState[] targetShards;
182182

183183
Split(SourceShardState[] sourceShards, TargetShardState[] targetShards) {
184+
// The resharding metadata is deleted when the last source shard transitions to done
185+
assert Arrays.stream(sourceShards).allMatch((state) -> state == SourceShardState.DONE) == false;
186+
184187
this.sourceShards = sourceShards;
185188
this.targetShards = targetShards;
186189

@@ -375,20 +378,6 @@ public boolean targetStateAtLeast(int shardNum, TargetShardState targetShardStat
375378
return getTargetShardState(shardNum).ordinal() >= targetShardState.ordinal();
376379
}
377380

378-
/**
379-
* Check whether this metadata represents an incomplete split
380-
* @return true if the split is incomplete (not all source shards are DONE)
381-
*/
382-
public boolean inProgress() {
383-
for (int i = 0; i < oldShardCount; i++) {
384-
if (sourceShards[i] == SourceShardState.SOURCE) {
385-
return true;
386-
}
387-
}
388-
389-
return false;
390-
}
391-
392381
public Stream<TargetShardState> targetStates() {
393382
return Arrays.stream(targetShards);
394383
}

server/src/test/java/org/elasticsearch/cluster/metadata/IndexReshardingMetadataSerializationTests.java

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import org.elasticsearch.xcontent.XContentParser;
1515

1616
import java.io.IOException;
17+
import java.util.Arrays;
18+
import java.util.stream.IntStream;
1719

1820
public class IndexReshardingMetadataSerializationTests extends AbstractXContentSerializingTestCase<IndexReshardingMetadata> {
1921
@Override
@@ -46,6 +48,10 @@ private IndexReshardingState.Split createTestSplit() {
4648
for (int i = 0; i < oldShards; i++) {
4749
sourceShardStates[i] = randomFrom(IndexReshardingState.Split.SourceShardState.values());
4850
}
51+
// All sources done is an invalid state, will fail assert in Split constructor
52+
if (Arrays.stream(sourceShardStates).allMatch(state -> state == IndexReshardingState.Split.SourceShardState.DONE)) {
53+
sourceShardStates[0] = IndexReshardingState.Split.SourceShardState.SOURCE;
54+
}
4955
for (int i = 0; i < targetShardStates.length; i++) {
5056
targetShardStates[i] = randomFrom(IndexReshardingState.Split.TargetShardState.values());
5157
}
@@ -74,16 +80,18 @@ enum Mutation {
7480
var sourceShardStates = split.sourceShards().clone();
7581
var targetShardStates = split.targetShards().clone();
7682

77-
switch (randomFrom(Mutation.values())) {
78-
case SOURCE_SHARD_STATES:
79-
var is = randomInt(sourceShardStates.length - 1);
80-
sourceShardStates[is] = IndexReshardingState.Split.SourceShardState.values()[(sourceShardStates[is].ordinal() + 1)
81-
% IndexReshardingState.Split.SourceShardState.values().length];
82-
break;
83-
case TARGET_SHARD_STATES:
84-
var it = randomInt(targetShardStates.length - 1);
85-
targetShardStates[it] = IndexReshardingState.Split.TargetShardState.values()[(targetShardStates[it].ordinal() + 1)
86-
% IndexReshardingState.Split.TargetShardState.values().length];
83+
var is = randomInt(sourceShardStates.length - 1);
84+
boolean allOtherSourcesDone = IntStream.range(0, sourceShardStates.length)
85+
.filter(i -> i != is)
86+
.allMatch(i -> sourceShardStates[i] == IndexReshardingState.Split.SourceShardState.DONE);
87+
// All sources done is an invalid state, will fail assert in Split constructor
88+
if (allOtherSourcesDone || randomFrom(Mutation.values()) == Mutation.TARGET_SHARD_STATES) {
89+
var it = randomInt(targetShardStates.length - 1);
90+
targetShardStates[it] = IndexReshardingState.Split.TargetShardState.values()[(targetShardStates[it].ordinal() + 1)
91+
% IndexReshardingState.Split.TargetShardState.values().length];
92+
} else {
93+
sourceShardStates[is] = IndexReshardingState.Split.SourceShardState.values()[(sourceShardStates[is].ordinal() + 1)
94+
% IndexReshardingState.Split.SourceShardState.values().length];
8795
}
8896

8997
return new IndexReshardingState.Split(sourceShardStates, targetShardStates);

server/src/test/java/org/elasticsearch/cluster/metadata/IndexReshardingMetadataTests.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public void testSplit() {
3333
}
3434

3535
// advance split state randomly and expect to terminate
36-
while (split.inProgress()) {
36+
while (true) {
3737
var splitBuilder = split.builder();
3838
// pick a shard at random and see if we can advance it
3939
int idx = randomIntBetween(0, numShards * multiple - 1);
@@ -43,6 +43,11 @@ public void testSplit() {
4343
var nextState = randomFrom(IndexReshardingState.Split.SourceShardState.values());
4444
if (nextState.ordinal() == sourceState.ordinal() + 1) {
4545
if (split.targetsDone(idx)) {
46+
long ongoingSourceShards = split.sourceStates()
47+
.filter(state -> state != IndexReshardingState.Split.SourceShardState.DONE)
48+
.count();
49+
// all source shards done is an invalid state, terminate
50+
if (ongoingSourceShards == 1) break;
4651
splitBuilder.setSourceShardState(idx, nextState);
4752
} else {
4853
assertThrows(AssertionError.class, () -> splitBuilder.setSourceShardState(idx, nextState));
@@ -63,10 +68,10 @@ public void testSplit() {
6368
split = splitBuilder.build();
6469
}
6570

66-
for (int i = 0; i < numShards; i++) {
67-
assertSame(IndexReshardingState.Split.SourceShardState.DONE, split.getSourceShardState(i));
68-
assertFalse(split.isTargetShard(i));
69-
}
71+
assertEquals(
72+
split.sourceStates().filter(state -> state == IndexReshardingState.Split.SourceShardState.DONE).count(),
73+
numShards - 1
74+
);
7075
for (int i = numShards; i < numShards * multiple; i++) {
7176
assertSame(IndexReshardingState.Split.TargetShardState.DONE, split.getTargetShardState(i));
7277
assertTrue(split.isTargetShard(i));

0 commit comments

Comments
 (0)