|
11 | 11 | import com.carrotsearch.hppc.IntHashSet;
|
12 | 12 | import com.carrotsearch.hppc.IntSet;
|
13 | 13 | import org.elasticsearch.action.ActionFuture;
|
| 14 | +import org.elasticsearch.action.ActionListener; |
14 | 15 | import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
|
15 | 16 | import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
|
16 | 17 | import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
|
|
20 | 21 | import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusResponse;
|
21 | 22 | import org.elasticsearch.action.admin.indices.stats.ShardStats;
|
22 | 23 | import org.elasticsearch.action.index.IndexRequestBuilder;
|
| 24 | +import org.elasticsearch.action.support.ActionTestUtils; |
23 | 25 | import org.elasticsearch.action.support.ActiveShardCount;
|
24 | 26 | import org.elasticsearch.action.support.PlainActionFuture;
|
25 | 27 | import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
|
35 | 37 | import org.elasticsearch.common.settings.SettingsFilter;
|
36 | 38 | import org.elasticsearch.common.util.set.Sets;
|
37 | 39 | import org.elasticsearch.env.Environment;
|
| 40 | +import org.elasticsearch.index.IndexNotFoundException; |
38 | 41 | import org.elasticsearch.index.seqno.RetentionLeaseActions;
|
39 | 42 | import org.elasticsearch.index.seqno.RetentionLeases;
|
40 | 43 | import org.elasticsearch.index.shard.ShardId;
|
|
75 | 78 | import java.util.List;
|
76 | 79 | import java.util.Locale;
|
77 | 80 | import java.util.concurrent.CountDownLatch;
|
| 81 | +import java.util.concurrent.Future; |
78 | 82 | import java.util.concurrent.TimeUnit;
|
79 | 83 | import java.util.concurrent.atomic.AtomicBoolean;
|
80 | 84 | import java.util.concurrent.atomic.AtomicReference;
|
|
90 | 94 | import static org.hamcrest.Matchers.greaterThan;
|
91 | 95 | import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
92 | 96 | import static org.hamcrest.Matchers.hasSize;
|
| 97 | +import static org.hamcrest.Matchers.instanceOf; |
93 | 98 | import static org.hamcrest.Matchers.is;
|
94 | 99 | import static org.hamcrest.Matchers.lessThan;
|
95 | 100 | import static org.hamcrest.Matchers.not;
|
@@ -1045,6 +1050,65 @@ public void testPartialSnapshotsDoNotRecordDeletedShardFailures() throws Excepti
|
1045 | 1050 | assertThat(snapshotInfo.shardFailures(), empty());
|
1046 | 1051 | }
|
1047 | 1052 |
|
| 1053 | + public void testDeleteIndexDuringSnapshot() throws Exception { |
| 1054 | + final String indexName = "test-idx"; |
| 1055 | + assertAcked(prepareCreate(indexName, 1, indexSettingsNoReplicas(1))); |
| 1056 | + ensureGreen(); |
| 1057 | + indexRandomDocs(indexName, 100); |
| 1058 | + |
| 1059 | + final String repoName = "test-repo"; |
| 1060 | + createRepository(repoName, "fs"); |
| 1061 | + |
| 1062 | + final String firstSnapshotName = "test-snap"; |
| 1063 | + createSnapshot(repoName, firstSnapshotName, Collections.singletonList(indexName)); |
| 1064 | + final int concurrentLoops = randomIntBetween(2, 5); |
| 1065 | + final List<Future<Void>> futures = new ArrayList<>(concurrentLoops); |
| 1066 | + for (int i = 0; i < concurrentLoops; i++) { |
| 1067 | + final PlainActionFuture<Void> future = PlainActionFuture.newFuture(); |
| 1068 | + futures.add(future); |
| 1069 | + startSnapshotDeleteLoop(repoName, indexName, "test-snap-" + i, future); |
| 1070 | + } |
| 1071 | + |
| 1072 | + Thread.sleep(200); |
| 1073 | + |
| 1074 | + logger.info("--> delete index"); |
| 1075 | + assertAcked(admin().indices().prepareDelete(indexName)); |
| 1076 | + |
| 1077 | + for (Future<Void> future : futures) { |
| 1078 | + future.get(); |
| 1079 | + } |
| 1080 | + |
| 1081 | + logger.info("--> restore snapshot 1"); |
| 1082 | + clusterAdmin().prepareRestoreSnapshot(repoName, firstSnapshotName).get(); |
| 1083 | + ensureGreen(indexName); |
| 1084 | + } |
| 1085 | + |
| 1086 | + // create and delete a snapshot of the given name and for the given single index in a loop until the index is removed from the cluster |
| 1087 | + // at which point doneListener is resolved |
| 1088 | + private void startSnapshotDeleteLoop(String repoName, String indexName, String snapshotName, ActionListener<Void> doneListener) { |
| 1089 | + clusterAdmin().prepareCreateSnapshot(repoName, snapshotName) |
| 1090 | + .setWaitForCompletion(true) |
| 1091 | + .setPartial(true) |
| 1092 | + .setIndices(indexName) |
| 1093 | + .execute(new ActionListener<CreateSnapshotResponse>() { |
| 1094 | + @Override |
| 1095 | + public void onResponse(CreateSnapshotResponse createSnapshotResponse) { |
| 1096 | + clusterAdmin().prepareDeleteSnapshot(repoName, snapshotName).execute( |
| 1097 | + ActionTestUtils.assertNoFailureListener(acknowledgedResponse -> { |
| 1098 | + assertAcked(acknowledgedResponse); |
| 1099 | + startSnapshotDeleteLoop(repoName, indexName, snapshotName, doneListener); |
| 1100 | + })); |
| 1101 | + } |
| 1102 | + |
| 1103 | + @Override |
| 1104 | + public void onFailure(Exception e) { |
| 1105 | + assertThat(e, instanceOf(IndexNotFoundException.class)); |
| 1106 | + doneListener.onResponse(null); |
| 1107 | + } |
| 1108 | + }); |
| 1109 | + } |
| 1110 | + |
| 1111 | + |
1048 | 1112 | public void testGetReposWithWildcard() {
|
1049 | 1113 | internalCluster().startMasterOnlyNode();
|
1050 | 1114 | List<RepositoryMetadata> repositoryMetadata = client().admin().cluster().prepareGetRepositories("*").get().repositories();
|
|
0 commit comments