Skip to content

Commit 4c69044

Browse files
Update equals and hashcode methods for SnapshotsInProgress.Entry (elastic#64027)
* Include missing class fields in equals/hashcode * Update unit tests to vary added fields in inequality checks
1 parent 4043b18 commit 4c69044

File tree

2 files changed

+93
-5
lines changed

2 files changed

+93
-5
lines changed

server/src/main/java/org/elasticsearch/cluster/SnapshotsInProgress.java

+6
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,13 @@ public boolean equals(Object o) {
399399
if (partial != entry.partial) return false;
400400
if (startTime != entry.startTime) return false;
401401
if (!indices.equals(entry.indices)) return false;
402+
if (!dataStreams.equals(entry.dataStreams)) return false;
402403
if (!shards.equals(entry.shards)) return false;
403404
if (!snapshot.equals(entry.snapshot)) return false;
404405
if (state != entry.state) return false;
405406
if (repositoryStateId != entry.repositoryStateId) return false;
407+
if (Objects.equals(failure, ((Entry) o).failure) == false) return false;
408+
if (Objects.equals(userMetadata, ((Entry) o).userMetadata) == false) return false;
406409
if (version.equals(entry.version) == false) return false;
407410
if (Objects.equals(source, ((Entry) o).source) == false) return false;
408411
if (clones.equals(((Entry) o).clones) == false) return false;
@@ -418,8 +421,11 @@ public int hashCode() {
418421
result = 31 * result + (partial ? 1 : 0);
419422
result = 31 * result + shards.hashCode();
420423
result = 31 * result + indices.hashCode();
424+
result = 31 * result + dataStreams.hashCode();
421425
result = 31 * result + Long.hashCode(startTime);
422426
result = 31 * result + Long.hashCode(repositoryStateId);
427+
result = 31 * result + (failure == null ? 0 : failure.hashCode());
428+
result = 31 * result + (userMetadata == null ? 0 : userMetadata.hashCode());
423429
result = 31 * result + version.hashCode();
424430
result = 31 * result + (source == null ? 0 : source.hashCode());
425431
result = 31 * result + clones.hashCode();

server/src/test/java/org/elasticsearch/snapshots/SnapshotsInProgressSerializationTests.java

+87-5
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,16 @@
3333
import org.elasticsearch.index.shard.ShardId;
3434
import org.elasticsearch.repositories.IndexId;
3535
import org.elasticsearch.test.AbstractDiffableWireSerializationTestCase;
36+
import org.elasticsearch.test.ESTestCase;
3637
import org.elasticsearch.test.VersionUtils;
3738

3839
import java.util.ArrayList;
3940
import java.util.Arrays;
41+
import java.util.HashMap;
4042
import java.util.List;
43+
import java.util.Map;
4144
import java.util.stream.Collectors;
45+
import java.util.stream.Stream;
4246

4347
public class SnapshotsInProgressSerializationTests extends AbstractDiffableWireSerializationTestCase<Custom> {
4448

@@ -110,7 +114,7 @@ protected Custom makeTestChanges(Custom testInstance) {
110114
for (int i = 0; i < entries.size(); i++) {
111115
if (randomBoolean()) {
112116
final Entry entry = entries.get(i);
113-
entries.set(i, entry.fail(entry.shards(), randomState(entry.shards()), entry.failure()));
117+
entries.set(i, mutateEntry(entry));
114118
}
115119
}
116120
}
@@ -130,15 +134,93 @@ protected NamedWriteableRegistry getNamedWriteableRegistry() {
130134
@Override
131135
protected Custom mutateInstance(Custom instance) {
132136
List<Entry> entries = new ArrayList<>(((SnapshotsInProgress) instance).entries());
133-
boolean addEntry = entries.isEmpty() ? true : randomBoolean();
134-
if (addEntry) {
135-
entries.add(randomSnapshot());
137+
if (false || entries.isEmpty()) {
138+
// add or remove an entry
139+
boolean addEntry = entries.isEmpty() ? true : randomBoolean();
140+
if (addEntry) {
141+
entries.add(randomSnapshot());
142+
} else {
143+
entries.remove(randomIntBetween(0, entries.size() - 1));
144+
}
136145
} else {
137-
entries.remove(randomIntBetween(0, entries.size() - 1));
146+
// mutate an entry
147+
int index = randomIntBetween(0, entries.size() - 1);
148+
Entry entry = entries.get(index);
149+
entries.set(index, mutateEntry(entry));
138150
}
139151
return SnapshotsInProgress.of(entries);
140152
}
141153

154+
private Entry mutateEntry(Entry entry) {
155+
switch (randomInt(7)) {
156+
case 0:
157+
boolean includeGlobalState = !entry.includeGlobalState();
158+
return new Entry(entry.snapshot(), includeGlobalState, entry.partial(), entry.state(), entry.indices(), entry.dataStreams(),
159+
entry.startTime(), entry.repositoryStateId(), entry.shards(), entry.failure(), entry.userMetadata(), entry.version());
160+
case 1:
161+
boolean partial = !entry.partial();
162+
return new Entry(entry.snapshot(), entry.includeGlobalState(), partial, entry.state(), entry.indices(), entry.dataStreams(),
163+
entry.startTime(), entry.repositoryStateId(), entry.shards(), entry.failure(), entry.userMetadata(), entry.version());
164+
case 2:
165+
List<String> dataStreams = Stream.concat(
166+
entry.dataStreams().stream(),
167+
Stream.of(randomAlphaOfLength(10)))
168+
.collect(Collectors.toList());
169+
return new Entry(entry.snapshot(), entry.includeGlobalState(), entry.partial(), entry.state(), entry.indices(),
170+
dataStreams, entry.startTime(), entry.repositoryStateId(), entry.shards(), entry.failure(), entry.userMetadata(),
171+
entry.version());
172+
case 3:
173+
long startTime = randomValueOtherThan(entry.startTime(), ESTestCase::randomLong);
174+
return new Entry(entry.snapshot(), entry.includeGlobalState(), entry.partial(), entry.state(), entry.indices(),
175+
entry.dataStreams(), startTime, entry.repositoryStateId(), entry.shards(), entry.failure(), entry.userMetadata(),
176+
entry.version());
177+
case 4:
178+
long repositoryStateId = randomValueOtherThan(entry.startTime(), ESTestCase::randomLong);
179+
return new Entry(entry.snapshot(), entry.includeGlobalState(), entry.partial(), entry.state(), entry.indices(),
180+
entry.dataStreams(), entry.startTime(), repositoryStateId, entry.shards(), entry.failure(), entry.userMetadata(),
181+
entry.version());
182+
case 5:
183+
String failure = randomValueOtherThan(entry.failure(), () -> randomAlphaOfLengthBetween(2, 10));
184+
return new Entry(entry.snapshot(), entry.includeGlobalState(), entry.partial(), entry.state(), entry.indices(),
185+
entry.dataStreams(), entry.startTime(), entry.repositoryStateId(), entry.shards(), failure, entry.userMetadata(),
186+
entry.version());
187+
case 6:
188+
List<IndexId> indices = entry.indices();
189+
ImmutableOpenMap<ShardId, SnapshotsInProgress.ShardSnapshotStatus> shards = entry.shards();
190+
IndexId indexId = new IndexId(randomAlphaOfLength(10), randomAlphaOfLength(10));
191+
indices.add(indexId);
192+
ImmutableOpenMap.Builder<ShardId, SnapshotsInProgress.ShardSnapshotStatus> builder = ImmutableOpenMap.builder(shards);
193+
Index index = new Index(indexId.getName(), randomAlphaOfLength(10));
194+
int shardsCount = randomIntBetween(1, 10);
195+
for (int j = 0; j < shardsCount; j++) {
196+
ShardId shardId = new ShardId(index, j);
197+
String nodeId = randomAlphaOfLength(10);
198+
ShardState shardState = randomFrom(ShardState.values());
199+
builder.put(shardId,
200+
shardState == ShardState.QUEUED ? SnapshotsInProgress.ShardSnapshotStatus.UNASSIGNED_QUEUED :
201+
new SnapshotsInProgress.ShardSnapshotStatus(nodeId, shardState,
202+
shardState.failed() ? randomAlphaOfLength(10) : null, "1"));
203+
}
204+
shards = builder.build();
205+
return new Entry(entry.snapshot(), entry.includeGlobalState(), entry.partial(), randomState(shards), indices,
206+
entry.dataStreams(), entry.startTime(), entry.repositoryStateId(), shards, entry.failure(), entry.userMetadata(),
207+
entry.version());
208+
case 7:
209+
Map<String, Object> userMetadata = entry.userMetadata() != null ? new HashMap<>(entry.userMetadata()) : new HashMap<>();
210+
String key = randomAlphaOfLengthBetween(2, 10);
211+
if (userMetadata.containsKey(key)) {
212+
userMetadata.remove(key);
213+
} else {
214+
userMetadata.put(key, randomAlphaOfLengthBetween(2, 10));
215+
}
216+
return new Entry(entry.snapshot(), entry.includeGlobalState(), entry.partial(), entry.state(), entry.indices(),
217+
entry.dataStreams(), entry.startTime(), entry.repositoryStateId(), entry.shards(), entry.failure(), userMetadata,
218+
entry.version());
219+
default:
220+
throw new IllegalArgumentException("invalid randomization case");
221+
}
222+
}
223+
142224
public static State randomState(ImmutableOpenMap<ShardId, SnapshotsInProgress.ShardSnapshotStatus> shards) {
143225
return SnapshotsInProgress.completed(shards.values())
144226
? randomFrom(State.SUCCESS, State.FAILED) : randomFrom(State.STARTED, State.INIT, State.ABORTED);

0 commit comments

Comments
 (0)