| 
40 | 40 | import org.elasticsearch.core.Predicates;  | 
41 | 41 | import org.elasticsearch.repositories.RepositoriesService;  | 
42 | 42 | import org.elasticsearch.repositories.RepositoryData;  | 
 | 43 | +import org.elasticsearch.repositories.RepositoryException;  | 
43 | 44 | import org.elasticsearch.repositories.RepositoryMissingException;  | 
 | 45 | +import org.elasticsearch.repositories.blobstore.BlobStoreRepository;  | 
44 | 46 | import org.elasticsearch.repositories.fs.FsRepository;  | 
45 | 47 | import org.elasticsearch.search.sort.SortOrder;  | 
46 | 48 | import org.elasticsearch.test.ESTestCase;  | 
@@ -633,6 +635,48 @@ public void testRetrievingSnapshotsWhenRepositoryIsMissing() throws Exception {  | 
633 | 635 |         expectThrows(RepositoryMissingException.class, multiRepoFuture::actionGet);  | 
634 | 636 |     }  | 
635 | 637 | 
 
  | 
 | 638 | +    public void testRetrievingSnapshotsWhenRepositoryIsUnreadable() throws Exception {  | 
 | 639 | +        final String repoName = randomIdentifier();  | 
 | 640 | +        final Path repoPath = randomRepoPath();  | 
 | 641 | +        createRepository(  | 
 | 642 | +            repoName,  | 
 | 643 | +            "fs",  | 
 | 644 | +            Settings.builder().put("location", repoPath).put(BlobStoreRepository.CACHE_REPOSITORY_DATA.getKey(), false)  | 
 | 645 | +        );  | 
 | 646 | +        createNSnapshots(repoName, randomIntBetween(1, 3));  | 
 | 647 | + | 
 | 648 | +        try {  | 
 | 649 | +            try (var directoryStream = Files.newDirectoryStream(repoPath)) {  | 
 | 650 | +                for (final var directoryEntry : directoryStream) {  | 
 | 651 | +                    if (Files.isRegularFile(directoryEntry) && directoryEntry.getFileName().toString().startsWith("index-")) {  | 
 | 652 | +                        Files.writeString(directoryEntry, "invalid");  | 
 | 653 | +                    }  | 
 | 654 | +                }  | 
 | 655 | +            }  | 
 | 656 | + | 
 | 657 | +            final var repositoryException = safeAwaitAndUnwrapFailure(  | 
 | 658 | +                RepositoryException.class,  | 
 | 659 | +                GetSnapshotsResponse.class,  | 
 | 660 | +                l -> clusterAdmin().prepareGetSnapshots(TEST_REQUEST_TIMEOUT, repoName)  | 
 | 661 | +                    .setSort(SnapshotSortKey.NAME)  | 
 | 662 | +                    .setIgnoreUnavailable(randomBoolean())  | 
 | 663 | +                    .execute(l)  | 
 | 664 | +            );  | 
 | 665 | +            assertEquals(  | 
 | 666 | +                Strings.format("[%s] cannot retrieve snapshots list from this repository", repoName),  | 
 | 667 | +                repositoryException.getMessage()  | 
 | 668 | +            );  | 
 | 669 | +            assertEquals(  | 
 | 670 | +                Strings.format("[%s] Unexpected exception when loading repository data", repoName),  | 
 | 671 | +                repositoryException.getCause().getMessage()  | 
 | 672 | +            );  | 
 | 673 | +        } finally {  | 
 | 674 | +            safeAwait(  | 
 | 675 | +                l -> clusterAdmin().prepareDeleteRepository(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT, repoName).execute(l.map(v -> null))  | 
 | 676 | +            );  | 
 | 677 | +        }  | 
 | 678 | +    }  | 
 | 679 | + | 
636 | 680 |     // Create a snapshot that is guaranteed to have a unique start time and duration for tests around ordering by either.  | 
637 | 681 |     // Don't use this with more than 3 snapshots on platforms with low-resolution clocks as the durations could always collide there  | 
638 | 682 |     // causing an infinite loop  | 
 | 
0 commit comments