3131import org .elasticsearch .repositories .RepositoryException ;
3232import org .elasticsearch .repositories .ShardGeneration ;
3333import org .elasticsearch .repositories .ShardGenerations ;
34- import org .elasticsearch .repositories .blobstore .BlobStoreCorruptionUtils ;
3534import org .elasticsearch .repositories .blobstore .BlobStoreRepository ;
3635import org .elasticsearch .repositories .fs .FsRepository ;
3736import org .elasticsearch .xcontent .XContentFactory ;
@@ -734,7 +733,7 @@ public void testDeleteSnapshotWithCorruptedGlobalState() throws Exception {
734733 createFullSnapshot ("test-repo" , "test-snap" );
735734 }
736735
737- public void testSnapshotWithCorruptShardLevelIndexFile () throws Exception {
736+ public void testSnapshotWithMissingShardLevelIndexFile () throws Exception {
738737 disableRepoConsistencyCheck ("This test uses a purposely broken repository so it would fail consistency checks" );
739738
740739 Path repo = randomRepoPath ();
@@ -750,7 +749,7 @@ public void testSnapshotWithCorruptShardLevelIndexFile() throws Exception {
750749 .setIndices ("test-idx-*" )
751750 .get ();
752751
753- logger .info ("--> corrupting shard level index file" );
752+ logger .info ("--> deleting shard level index file" );
754753 final Path indicesPath = repo .resolve ("indices" );
755754 for (IndexId indexId : getRepositoryData ("test-repo" ).getIndices ().values ()) {
756755 final Path shardGen ;
@@ -759,33 +758,64 @@ public void testSnapshotWithCorruptShardLevelIndexFile() throws Exception {
759758 .findFirst ()
760759 .orElseThrow (() -> new AssertionError ("Failed to find shard index blob" ));
761760 }
762- BlobStoreCorruptionUtils . corruptFileContents (shardGen );
761+ Files . delete (shardGen );
763762 }
764763
765- logger .info ("--> creating another snapshot" );
764+ if (randomBoolean ()) {
765+ logger .info (
766+ "--> restoring the snapshot, the repository should not have lost any shard data despite deleting index-N, "
767+ + "because it uses snap-*.data files and not the index-N to determine what files to restore"
768+ );
769+ indicesAdmin ().prepareDelete ("test-idx-1" , "test-idx-2" ).get ();
770+ RestoreSnapshotResponse restoreSnapshotResponse = clusterAdmin ().prepareRestoreSnapshot (
771+ TEST_REQUEST_TIMEOUT ,
772+ "test-repo" ,
773+ "test-snap-1"
774+ ).setWaitForCompletion (true ).get ();
775+ assertEquals (0 , restoreSnapshotResponse .getRestoreInfo ().failedShards ());
776+ ensureGreen ("test-idx-1" , "test-idx-2" );
777+ }
778+
779+ logger .info ("--> creating another snapshot, which should re-create the missing file" );
766780 try (var ignored = new BlobStoreIndexShardSnapshotsIntegritySuppressor ()) {
767781 CreateSnapshotResponse createSnapshotResponse = clusterAdmin ().prepareCreateSnapshot (
768782 TEST_REQUEST_TIMEOUT ,
769783 "test-repo" ,
770784 "test-snap-2"
771785 ).setWaitForCompletion (true ).setIndices ("test-idx-1" ).get ();
772786 assertEquals (
773- createSnapshotResponse .getSnapshotInfo ().totalShards () - 1 ,
787+ createSnapshotResponse .getSnapshotInfo ().totalShards (),
774788 createSnapshotResponse .getSnapshotInfo ().successfulShards ()
775789 );
776790 }
777791
778- logger .info (
779- "--> restoring the first snapshot, the repository should not have lost any shard data despite corrupting index-N, "
780- + "because it uses snap-*.data files and not the index-N to determine what files to restore"
781- );
782- indicesAdmin ().prepareDelete ("test-idx-1" , "test-idx-2" ).get ();
783- RestoreSnapshotResponse restoreSnapshotResponse = clusterAdmin ().prepareRestoreSnapshot (
792+ if (randomBoolean ()) {
793+ indicesAdmin ().prepareDelete ("test-idx-1" ).get ();
794+ RestoreSnapshotResponse restoreSnapshotResponse2 = clusterAdmin ().prepareRestoreSnapshot (
795+ TEST_REQUEST_TIMEOUT ,
796+ "test-repo" ,
797+ randomFrom ("test-snap-1" , "test-snap-2" )
798+ ).setIndices ("test-idx-1" ).setWaitForCompletion (true ).get ();
799+ assertEquals (0 , restoreSnapshotResponse2 .getRestoreInfo ().failedShards ());
800+ ensureGreen ("test-idx-1" , "test-idx-2" );
801+ }
802+
803+ logger .info ("--> creating another snapshot, which should succeed since the shard gen file now exists again" );
804+ CreateSnapshotResponse createSnapshotResponse = clusterAdmin ().prepareCreateSnapshot (
805+ TEST_REQUEST_TIMEOUT ,
806+ "test-repo" ,
807+ "test-snap-3"
808+ ).setWaitForCompletion (true ).setIndices ("test-idx-1" ).get ();
809+ assertEquals (createSnapshotResponse .getSnapshotInfo ().totalShards (), createSnapshotResponse .getSnapshotInfo ().successfulShards ());
810+
811+ indicesAdmin ().prepareDelete ("test-idx-1" ).get ();
812+ RestoreSnapshotResponse restoreSnapshotResponse3 = clusterAdmin ().prepareRestoreSnapshot (
784813 TEST_REQUEST_TIMEOUT ,
785814 "test-repo" ,
786- "test-snap-1"
787- ).setWaitForCompletion (true ).get ();
788- assertEquals (0 , restoreSnapshotResponse .getRestoreInfo ().failedShards ());
815+ randomFrom ("test-snap-1" , "test-snap-2" , "test-snap-3" )
816+ ).setIndices ("test-idx-1" ).setWaitForCompletion (true ).get ();
817+ assertEquals (0 , restoreSnapshotResponse3 .getRestoreInfo ().failedShards ());
818+ ensureGreen ("test-idx-1" , "test-idx-2" );
789819 }
790820
791821 public void testDeletesWithUnexpectedIndexBlob () throws Exception {
0 commit comments