5353import java .nio .file .Files ;
5454import java .nio .file .Path ;
5555import java .util .ArrayList ;
56+ import java .util .Arrays ;
5657import java .util .Collection ;
5758import java .util .Collections ;
5859import java .util .EnumSet ;
6162import java .util .Map ;
6263import java .util .Objects ;
6364import java .util .Set ;
65+ import java .util .function .Function ;
6466import java .util .function .Predicate ;
6567import java .util .stream .Collectors ;
6668
7072import static org .hamcrest .Matchers .hasSize ;
7173import static org .hamcrest .Matchers .in ;
7274import static org .hamcrest .Matchers .is ;
73- import static org .hamcrest .core .StringContains .containsString ;
7475
7576public class GetSnapshotsIT extends AbstractSnapshotIntegTestCase {
7677
@@ -641,47 +642,55 @@ public void testFilterByState() throws Exception {
641642 createRepository (repoName , "mock" , repoPath );
642643
643644 // Create a successful snapshot
644- String successSnapshot = "snapshot-success" ;
645- createFullSnapshot (repoName , successSnapshot );
645+ createFullSnapshot (repoName , "snapshot-success" );
646+
647+ final Function <EnumSet <SnapshotState >, List <SnapshotInfo >> getSnapshotsForStates = (states ) -> {
648+ return clusterAdmin ().prepareGetSnapshots (TEST_REQUEST_TIMEOUT , repoName ).setStates (states ).get ().getSnapshots ();
649+ };
646650
647651 // Fetch snapshots with state=SUCCESS
648- GetSnapshotsResponse responseSuccess = clusterAdmin ().prepareGetSnapshots (TEST_REQUEST_TIMEOUT , repoName )
649- .setState (EnumSet .of (SnapshotState .SUCCESS ))
650- .get ();
651- assertThat (responseSuccess .getSnapshots (), hasSize (1 ));
652- assertThat (responseSuccess .getSnapshots ().get (0 ).state (), is (SnapshotState .SUCCESS ));
652+ var snapshots = getSnapshotsForStates .apply (EnumSet .of (SnapshotState .SUCCESS ));
653+ assertThat (snapshots , hasSize (1 ));
654+ assertThat (snapshots .getFirst ().state (), is (SnapshotState .SUCCESS ));
653655
654656 // Create a snapshot in progress
655- String inProgressSnapshot = "snapshot-in-progress" ;
656657 blockAllDataNodes (repoName );
657- startFullSnapshot (repoName , inProgressSnapshot );
658+ startFullSnapshot (repoName , "snapshot-in-progress" );
658659 awaitNumberOfSnapshotsInProgress (1 );
659660
660661 // Fetch snapshots with state=IN_PROGRESS
661- GetSnapshotsResponse responseInProgress = clusterAdmin ().prepareGetSnapshots (TEST_REQUEST_TIMEOUT , repoName )
662- .setState (EnumSet .of (SnapshotState .IN_PROGRESS ))
663- .get ();
664- assertThat (responseInProgress .getSnapshots (), hasSize (1 ));
665- assertThat (responseInProgress .getSnapshots ().get (0 ).state (), is (SnapshotState .IN_PROGRESS ));
662+ snapshots = getSnapshotsForStates .apply (EnumSet .of (SnapshotState .IN_PROGRESS ));
663+ assertThat (snapshots , hasSize (1 ));
664+ assertThat (snapshots .getFirst ().state (), is (SnapshotState .IN_PROGRESS ));
666665
667666 // Fetch snapshots with multiple states (SUCCESS, IN_PROGRESS)
668- GetSnapshotsResponse responseMultipleStates = clusterAdmin ().prepareGetSnapshots (TEST_REQUEST_TIMEOUT , repoName )
669- .setState (EnumSet .of (SnapshotState .SUCCESS , SnapshotState .IN_PROGRESS ))
670- .get ();
671- assertThat (responseMultipleStates .getSnapshots (), hasSize (2 ));
672- assertTrue (responseMultipleStates .getSnapshots ().stream ().map (SnapshotInfo ::state ).toList ().contains (SnapshotState .SUCCESS ));
673- assertTrue (responseMultipleStates .getSnapshots ().stream ().map (SnapshotInfo ::state ).toList ().contains (SnapshotState .IN_PROGRESS ));
667+ snapshots = getSnapshotsForStates .apply (EnumSet .of (SnapshotState .SUCCESS , SnapshotState .IN_PROGRESS ));
668+ assertThat (snapshots , hasSize (2 ));
669+ var states = snapshots .stream ().map (SnapshotInfo ::state ).collect (Collectors .toSet ());
670+ assertTrue (states .contains (SnapshotState .SUCCESS ));
671+ assertTrue (states .contains (SnapshotState .IN_PROGRESS ));
674672
675673 // Fetch all snapshots (without state)
676- GetSnapshotsResponse responseAll = clusterAdmin ().prepareGetSnapshots (TEST_REQUEST_TIMEOUT , repoName ).get ();
677- assertThat (responseAll . getSnapshots () , hasSize (2 ));
674+ snapshots = clusterAdmin ().prepareGetSnapshots (TEST_REQUEST_TIMEOUT , repoName ).get (). getSnapshots ();
675+ assertThat (snapshots , hasSize (2 ));
678676
679677 // Fetch snapshots with an invalid state
680678 IllegalArgumentException e = expectThrows (
681679 IllegalArgumentException .class ,
682- () -> clusterAdmin (). prepareGetSnapshots ( TEST_REQUEST_TIMEOUT , repoName ). setState ( EnumSet .of (SnapshotState .of ("FOO" ))). get ( )
680+ () -> getSnapshotsForStates . apply ( EnumSet .of (SnapshotState .valueOf ("FOO" )))
683681 );
684- assertThat (e .getMessage (), containsString ("Unknown state name [FOO]" ));
682+ assertThat (e .getMessage (), is ("No enum constant org.elasticsearch.snapshots.SnapshotState.FOO" ));
683+
684+ // Allow the IN_PROGRESS snapshot to finish, then verify GET using SUCCESS has results and IN_PROGRESS does not.
685+ unblockAllDataNodes (repoName );
686+ awaitNumberOfSnapshotsInProgress (0 );
687+ snapshots = clusterAdmin ().prepareGetSnapshots (TEST_REQUEST_TIMEOUT , repoName ).get ().getSnapshots ();
688+ assertThat (snapshots , hasSize (2 ));
689+ states = snapshots .stream ().map (SnapshotInfo ::state ).collect (Collectors .toSet ());
690+ assertThat (states , hasSize (1 ));
691+ assertTrue (states .contains (SnapshotState .SUCCESS ));
692+ snapshots = getSnapshotsForStates .apply (EnumSet .of (SnapshotState .IN_PROGRESS ));
693+ assertThat (snapshots , hasSize (0 ));
685694 }
686695
687696 // Create a snapshot that is guaranteed to have a unique start time and duration for tests around ordering by either.
@@ -963,15 +972,15 @@ public void testAllFeatures() {
963972 // INDICES and by SHARDS. The actual sorting behaviour for these cases is tested elsewhere, here we're just checking that sorting
964973 // interacts correctly with the other parameters to the API.
965974
966- final EnumSet <SnapshotState > state = EnumSet .of ( randomFrom ( SnapshotState .values ()));
967- // Note: The selected state may not match any existing snapshots.
975+ final EnumSet <SnapshotState > states = EnumSet .copyOf ( randomNonEmptySubsetOf ( Arrays . asList ( SnapshotState .values () )));
976+ // Note: The selected state(s) may not match any existing snapshots.
968977 // The actual filtering behaviour for such cases is tested in the dedicated test.
969- // Here we're just checking that state interacts correctly with the other parameters to the API.
978+ // Here we're just checking that states interacts correctly with the other parameters to the API.
979+ snapshotInfoPredicate = snapshotInfoPredicate .and (si -> states .contains (si .state ()));
970980
971981 // compute the ordered sequence of snapshots which match the repository/snapshot name filters and SLM policy filter
972982 final var selectedSnapshots = snapshotInfos .stream ()
973983 .filter (snapshotInfoPredicate )
974- .filter (s -> state .contains (s .state ()))
975984 .sorted (sortKey .getSnapshotInfoComparator (order ))
976985 .toList ();
977986
@@ -981,7 +990,7 @@ public void testAllFeatures() {
981990 // apply sorting params
982991 .sort (sortKey )
983992 .order (order )
984- .state ( state );
993+ .states ( states );
985994
986995 // sometimes use ?from_sort_value to skip some items; note that snapshots skipped in this way are subtracted from
987996 // GetSnapshotsResponse.totalCount whereas snapshots skipped by ?after and ?offset are not
@@ -1069,7 +1078,7 @@ public void testAllFeatures() {
10691078 .order (order )
10701079 .size (nextSize )
10711080 .after (SnapshotSortKey .decodeAfterQueryParam (nextRequestAfter ))
1072- .state ( state );
1081+ .states ( states );
10731082 final GetSnapshotsResponse nextResponse = safeAwait (l -> client ().execute (TransportGetSnapshotsAction .TYPE , nextRequest , l ));
10741083
10751084 assertEquals (
0 commit comments