|
207 | 207 | import static org.elasticsearch.action.support.ActionTestUtils.assertNoFailureListener;
|
208 | 208 | import static org.elasticsearch.env.Environment.PATH_HOME_SETTING;
|
209 | 209 | import static org.elasticsearch.node.Node.NODE_NAME_SETTING;
|
| 210 | +import static org.hamcrest.Matchers.contains; |
210 | 211 | import static org.hamcrest.Matchers.containsInAnyOrder;
|
211 | 212 | import static org.hamcrest.Matchers.either;
|
212 | 213 | import static org.hamcrest.Matchers.empty;
|
@@ -517,6 +518,92 @@ public void testConcurrentSnapshotCreateAndDeleteOther() {
|
517 | 518 | }
|
518 | 519 | }
|
519 | 520 |
|
| 521 | + public void testConcurrentSnapshotRestoreAndDeleteOther() { |
| 522 | + setupTestCluster(randomFrom(1, 3, 5), randomIntBetween(2, 10)); |
| 523 | + |
| 524 | + String repoName = "repo"; |
| 525 | + String snapshotName = "snapshot"; |
| 526 | + final String index = "test"; |
| 527 | + final int shards = randomIntBetween(1, 10); |
| 528 | + |
| 529 | + TestClusterNodes.TestClusterNode masterNode = |
| 530 | + testClusterNodes.currentMaster(testClusterNodes.nodes.values().iterator().next().clusterService.state()); |
| 531 | + |
| 532 | + final StepListener<CreateSnapshotResponse> createSnapshotResponseStepListener = new StepListener<>(); |
| 533 | + |
| 534 | + final int documentsFirstSnapshot = randomIntBetween(0, 100); |
| 535 | + |
| 536 | + continueOrDie(createRepoAndIndex(repoName, index, shards), createIndexResponse -> indexNDocuments( |
| 537 | + documentsFirstSnapshot, index, () -> client().admin().cluster() |
| 538 | + .prepareCreateSnapshot(repoName, snapshotName).setWaitForCompletion(true).execute(createSnapshotResponseStepListener))); |
| 539 | + |
| 540 | + final int documentsSecondSnapshot = randomIntBetween(0, 100); |
| 541 | + |
| 542 | + final StepListener<CreateSnapshotResponse> createOtherSnapshotResponseStepListener = new StepListener<>(); |
| 543 | + |
| 544 | + final String secondSnapshotName = "snapshot-2"; |
| 545 | + continueOrDie(createSnapshotResponseStepListener, createSnapshotResponse -> indexNDocuments( |
| 546 | + documentsSecondSnapshot, index, () -> client().admin().cluster().prepareCreateSnapshot(repoName, secondSnapshotName) |
| 547 | + .setWaitForCompletion(true).execute(createOtherSnapshotResponseStepListener))); |
| 548 | + |
| 549 | + final StepListener<AcknowledgedResponse> deleteSnapshotStepListener = new StepListener<>(); |
| 550 | + final StepListener<RestoreSnapshotResponse> restoreSnapshotResponseListener = new StepListener<>(); |
| 551 | + |
| 552 | + continueOrDie(createOtherSnapshotResponseStepListener, |
| 553 | + createSnapshotResponse -> { |
| 554 | + scheduleNow( |
| 555 | + () -> client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).execute(deleteSnapshotStepListener)); |
| 556 | + scheduleNow(() -> client().admin().cluster().restoreSnapshot( |
| 557 | + new RestoreSnapshotRequest(repoName, secondSnapshotName).waitForCompletion(true) |
| 558 | + .renamePattern("(.+)").renameReplacement("restored_$1"), |
| 559 | + restoreSnapshotResponseListener)); |
| 560 | + }); |
| 561 | + |
| 562 | + final StepListener<SearchResponse> searchResponseListener = new StepListener<>(); |
| 563 | + continueOrDie(restoreSnapshotResponseListener, restoreSnapshotResponse -> { |
| 564 | + assertEquals(shards, restoreSnapshotResponse.getRestoreInfo().totalShards()); |
| 565 | + client().search(new SearchRequest("restored_" + index).source(new SearchSourceBuilder().size(0).trackTotalHits(true)), |
| 566 | + searchResponseListener); |
| 567 | + }); |
| 568 | + |
| 569 | + deterministicTaskQueue.runAllRunnableTasks(); |
| 570 | + |
| 571 | + assertEquals(documentsFirstSnapshot + documentsSecondSnapshot, |
| 572 | + Objects.requireNonNull(searchResponseListener.result().getHits().getTotalHits()).value); |
| 573 | + assertThat(deleteSnapshotStepListener.result().isAcknowledged(), is(true)); |
| 574 | + assertThat(restoreSnapshotResponseListener.result().getRestoreInfo().failedShards(), is(0)); |
| 575 | + |
| 576 | + final Repository repository = masterNode.repositoriesService.repository(repoName); |
| 577 | + Collection<SnapshotId> snapshotIds = getRepositoryData(repository).getSnapshotIds(); |
| 578 | + assertThat(snapshotIds, contains(createOtherSnapshotResponseStepListener.result().getSnapshotInfo().snapshotId())); |
| 579 | + |
| 580 | + for (SnapshotId snapshotId : snapshotIds) { |
| 581 | + final SnapshotInfo snapshotInfo = repository.getSnapshotInfo(snapshotId); |
| 582 | + assertEquals(SnapshotState.SUCCESS, snapshotInfo.state()); |
| 583 | + assertThat(snapshotInfo.indices(), containsInAnyOrder(index)); |
| 584 | + assertEquals(shards, snapshotInfo.successfulShards()); |
| 585 | + assertEquals(0, snapshotInfo.failedShards()); |
| 586 | + } |
| 587 | + } |
| 588 | + |
| 589 | + private void indexNDocuments(int documents, String index, Runnable afterIndexing) { |
| 590 | + if (documents == 0) { |
| 591 | + afterIndexing.run(); |
| 592 | + return; |
| 593 | + } |
| 594 | + final BulkRequest bulkRequest = new BulkRequest().setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE); |
| 595 | + for (int i = 0; i < documents; ++i) { |
| 596 | + bulkRequest.add(new IndexRequest(index).source(Collections.singletonMap("foo", "bar" + i))); |
| 597 | + } |
| 598 | + final StepListener<BulkResponse> bulkResponseStepListener = new StepListener<>(); |
| 599 | + client().bulk(bulkRequest, bulkResponseStepListener); |
| 600 | + continueOrDie(bulkResponseStepListener, bulkResponse -> { |
| 601 | + assertFalse("Failures in bulk response: " + bulkResponse.buildFailureMessage(), bulkResponse.hasFailures()); |
| 602 | + assertEquals(documents, bulkResponse.getItems().length); |
| 603 | + afterIndexing.run(); |
| 604 | + }); |
| 605 | + } |
| 606 | + |
520 | 607 | public void testConcurrentSnapshotDeleteAndDeleteIndex() throws IOException {
|
521 | 608 | setupTestCluster(randomFrom(1, 3, 5), randomIntBetween(2, 10));
|
522 | 609 |
|
|
0 commit comments