|
7 | 7 | package org.elasticsearch.xpack.searchablesnapshots;
|
8 | 8 |
|
9 | 9 | import org.elasticsearch.cluster.ClusterState;
|
| 10 | +import org.elasticsearch.cluster.metadata.IndexMetadata; |
10 | 11 | import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider;
|
11 | 12 | import org.elasticsearch.common.settings.Settings;
|
12 | 13 | import org.elasticsearch.common.unit.ByteSizeUnit;
|
13 | 14 | import org.elasticsearch.common.unit.ByteSizeValue;
|
| 15 | +import org.elasticsearch.common.util.set.Sets; |
14 | 16 | import org.elasticsearch.test.ESIntegTestCase;
|
15 | 17 | import org.elasticsearch.xpack.searchablesnapshots.cache.CacheService;
|
16 | 18 |
|
17 | 19 | import java.util.Collections;
|
| 20 | +import java.util.Set; |
18 | 21 |
|
19 | 22 | import static org.elasticsearch.index.IndexSettings.INDEX_SOFT_DELETES_SETTING;
|
20 | 23 | import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
| 24 | +import static org.hamcrest.Matchers.in; |
| 25 | +import static org.hamcrest.Matchers.is; |
21 | 26 |
|
22 | 27 | @ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0)
|
23 | 28 | public class SearchableSnapshotAllocationIntegTests extends BaseSearchableSnapshotsIntegTestCase {
|
@@ -62,6 +67,46 @@ public void testAllocatesToBestAvailableNodeOnRestart() throws Exception {
|
62 | 67 | );
|
63 | 68 | }
|
64 | 69 |
|
| 70 | + public void testAllocatesReplicaToBestAvailableNodeOnRestart() throws Exception { |
| 71 | + internalCluster().startMasterOnlyNode(); |
| 72 | + final String firstDataNode = internalCluster().startDataOnlyNode(); |
| 73 | + final String secondDataNode = internalCluster().startDataOnlyNode(); |
| 74 | + final String index = "test-idx"; |
| 75 | + createIndexWithContent(index, indexSettingsNoReplicas(1).put(INDEX_SOFT_DELETES_SETTING.getKey(), true).build()); |
| 76 | + final String repoName = "test-repo"; |
| 77 | + createRepository(repoName, "fs"); |
| 78 | + final String snapshotName = "test-snapshot"; |
| 79 | + createSnapshot(repoName, snapshotName, Collections.singletonList(index)); |
| 80 | + assertAcked(client().admin().indices().prepareDelete(index)); |
| 81 | + final String restoredIndex = mountSnapshot( |
| 82 | + repoName, |
| 83 | + snapshotName, |
| 84 | + index, |
| 85 | + Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 1).build() |
| 86 | + ); |
| 87 | + ensureGreen(restoredIndex); |
| 88 | + internalCluster().startDataOnlyNodes(randomIntBetween(1, 4)); |
| 89 | + |
| 90 | + setAllocation(EnableAllocationDecider.Allocation.NONE); |
| 91 | + |
| 92 | + internalCluster().getInstance(CacheService.class, firstDataNode).synchronizeCache(); |
| 93 | + internalCluster().getInstance(CacheService.class, secondDataNode).synchronizeCache(); |
| 94 | + internalCluster().restartNode(firstDataNode); |
| 95 | + internalCluster().restartNode(secondDataNode); |
| 96 | + ensureStableCluster(internalCluster().numDataAndMasterNodes()); |
| 97 | + |
| 98 | + setAllocation(EnableAllocationDecider.Allocation.ALL); |
| 99 | + ensureGreen(restoredIndex); |
| 100 | + |
| 101 | + final ClusterState state = client().admin().cluster().prepareState().get().getState(); |
| 102 | + final Set<String> nodesWithCache = Sets.newHashSet( |
| 103 | + state.nodes().resolveNode(firstDataNode).getId(), |
| 104 | + state.nodes().resolveNode(secondDataNode).getId() |
| 105 | + ); |
| 106 | + assertThat(state.routingTable().index(restoredIndex).shard(0).primaryShard().currentNodeId(), is(in(nodesWithCache))); |
| 107 | + assertThat(state.routingTable().index(restoredIndex).shard(0).replicaShards().get(0).currentNodeId(), is(in(nodesWithCache))); |
| 108 | + } |
| 109 | + |
65 | 110 | private void setAllocation(EnableAllocationDecider.Allocation allocation) {
|
66 | 111 | logger.info("--> setting allocation to [{}]", allocation);
|
67 | 112 | assertAcked(
|
|
0 commit comments