@@ -583,6 +583,109 @@ public void testClusterDetailsAfterCCSWithFailuresOnOneClusterOnly() throws Exce
583
583
}
584
584
}
585
585
586
+ // tests bug fix https://github.com/elastic/elasticsearch/issues/100350
587
+ public void testClusterDetailsAfterCCSWhereRemoteClusterHasNoShardsToSearch () throws Exception {
588
+ Map <String , Object > testClusterInfo = setupTwoClusters ();
589
+ String localIndex = (String ) testClusterInfo .get ("local.index" );
590
+ int localNumShards = (Integer ) testClusterInfo .get ("local.num_shards" );
591
+
592
+ SearchListenerPlugin .blockQueryPhase ();
593
+
594
+ SubmitAsyncSearchRequest request = new SubmitAsyncSearchRequest (localIndex , REMOTE_CLUSTER + ":" + "no_such_index*" );
595
+ request .setCcsMinimizeRoundtrips (true );
596
+ request .setWaitForCompletionTimeout (TimeValue .timeValueMillis (1 ));
597
+ request .setKeepOnCompletion (true );
598
+ request .getSearchRequest ().source (new SearchSourceBuilder ().query (new MatchAllQueryBuilder ()).size (1000 ));
599
+
600
+ AsyncSearchResponse response = submitAsyncSearch (request );
601
+ assertNotNull (response .getSearchResponse ());
602
+ assertTrue (response .isRunning ());
603
+
604
+ {
605
+ SearchResponse .Clusters clusters = response .getSearchResponse ().getClusters ();
606
+ assertThat (clusters .getTotal (), equalTo (2 ));
607
+ assertTrue ("search cluster results should be marked as partial" , clusters .hasPartialResults ());
608
+
609
+ SearchResponse .Cluster localClusterSearchInfo = clusters .getCluster (RemoteClusterAware .LOCAL_CLUSTER_GROUP_KEY ).get ();
610
+ assertNotNull (localClusterSearchInfo );
611
+ assertThat (localClusterSearchInfo .getStatus (), equalTo (SearchResponse .Cluster .Status .RUNNING ));
612
+
613
+ SearchResponse .Cluster remoteClusterSearchInfo = clusters .getCluster (REMOTE_CLUSTER ).get ();
614
+ assertNotNull (remoteClusterSearchInfo );
615
+ assertThat (localClusterSearchInfo .getStatus (), equalTo (SearchResponse .Cluster .Status .RUNNING ));
616
+ }
617
+
618
+ SearchListenerPlugin .waitSearchStarted ();
619
+ SearchListenerPlugin .allowQueryPhase ();
620
+
621
+ assertBusy (() -> {
622
+ AsyncStatusResponse statusResponse = getAsyncStatus (response .getId ());
623
+ assertFalse (statusResponse .isRunning ());
624
+ assertNotNull (statusResponse .getCompletionStatus ());
625
+ });
626
+
627
+ {
628
+ AsyncSearchResponse finishedResponse = getAsyncSearch (response .getId ());
629
+
630
+ SearchResponse .Clusters clusters = finishedResponse .getSearchResponse ().getClusters ();
631
+ assertFalse ("search cluster results should NOT be marked as partial" , clusters .hasPartialResults ());
632
+ assertThat (clusters .getTotal (), equalTo (2 ));
633
+ assertThat (clusters .getSuccessful (), equalTo (2 ));
634
+ assertThat (clusters .getSkipped (), equalTo (0 ));
635
+
636
+ SearchResponse .Cluster localClusterSearchInfo = clusters .getCluster (RemoteClusterAware .LOCAL_CLUSTER_GROUP_KEY ).get ();
637
+ assertNotNull (localClusterSearchInfo );
638
+ assertThat (localClusterSearchInfo .getStatus (), equalTo (SearchResponse .Cluster .Status .SUCCESSFUL ));
639
+ assertThat (localClusterSearchInfo .getTotalShards (), equalTo (localNumShards ));
640
+ assertThat (localClusterSearchInfo .getSuccessfulShards (), equalTo (localNumShards ));
641
+ assertThat (localClusterSearchInfo .getSkippedShards (), equalTo (0 ));
642
+ assertThat (localClusterSearchInfo .getFailedShards (), equalTo (0 ));
643
+ assertThat (localClusterSearchInfo .getFailures ().size (), equalTo (0 ));
644
+ assertThat (localClusterSearchInfo .getTook ().millis (), greaterThan (0L ));
645
+
646
+ SearchResponse .Cluster remoteClusterSearchInfo = clusters .getCluster (REMOTE_CLUSTER ).get ();
647
+ assertNotNull (remoteClusterSearchInfo );
648
+ assertThat (remoteClusterSearchInfo .getStatus (), equalTo (SearchResponse .Cluster .Status .SUCCESSFUL ));
649
+ assertThat (remoteClusterSearchInfo .getTotalShards (), equalTo (0 )); // zero since no shards to search
650
+ assertThat (remoteClusterSearchInfo .getSuccessfulShards (), equalTo (0 )); // zero since no shards to search
651
+ assertThat (remoteClusterSearchInfo .getSkippedShards (), equalTo (0 ));
652
+ assertThat (remoteClusterSearchInfo .getFailedShards (), equalTo (0 ));
653
+ assertThat (remoteClusterSearchInfo .getFailures ().size (), equalTo (0 ));
654
+ assertNotNull (remoteClusterSearchInfo .getTook ());
655
+ }
656
+
657
+ // check that the async_search/status response includes the same cluster details
658
+ {
659
+ AsyncStatusResponse statusResponse = getAsyncStatus (response .getId ());
660
+
661
+ SearchResponse .Clusters clusters = statusResponse .getClusters ();
662
+ assertFalse ("search cluster results should NOT be marked as partial" , clusters .hasPartialResults ());
663
+ assertThat (clusters .getTotal (), equalTo (2 ));
664
+ assertThat (clusters .getSuccessful (), equalTo (2 ));
665
+ assertThat (clusters .getSkipped (), equalTo (0 ));
666
+
667
+ SearchResponse .Cluster localClusterSearchInfo = clusters .getCluster (RemoteClusterAware .LOCAL_CLUSTER_GROUP_KEY ).get ();
668
+ assertNotNull (localClusterSearchInfo );
669
+ assertThat (localClusterSearchInfo .getStatus (), equalTo (SearchResponse .Cluster .Status .SUCCESSFUL ));
670
+ assertThat (localClusterSearchInfo .getTotalShards (), equalTo (localNumShards ));
671
+ assertThat (localClusterSearchInfo .getSuccessfulShards (), equalTo (localNumShards ));
672
+ assertThat (localClusterSearchInfo .getSkippedShards (), equalTo (0 ));
673
+ assertThat (localClusterSearchInfo .getFailedShards (), equalTo (0 ));
674
+ assertThat (localClusterSearchInfo .getFailures ().size (), equalTo (0 ));
675
+ assertThat (localClusterSearchInfo .getTook ().millis (), greaterThan (0L ));
676
+
677
+ SearchResponse .Cluster remoteClusterSearchInfo = clusters .getCluster (REMOTE_CLUSTER ).get ();
678
+ assertNotNull (remoteClusterSearchInfo );
679
+ assertThat (remoteClusterSearchInfo .getStatus (), equalTo (SearchResponse .Cluster .Status .SUCCESSFUL ));
680
+ assertThat (remoteClusterSearchInfo .getTotalShards (), equalTo (0 )); // zero since no shards to search
681
+ assertThat (remoteClusterSearchInfo .getSuccessfulShards (), equalTo (0 )); // zero since no shards to search
682
+ assertThat (remoteClusterSearchInfo .getSkippedShards (), equalTo (0 ));
683
+ assertThat (remoteClusterSearchInfo .getFailedShards (), equalTo (0 ));
684
+ assertThat (remoteClusterSearchInfo .getFailures ().size (), equalTo (0 ));
685
+ assertNotNull (remoteClusterSearchInfo .getTook ());
686
+ }
687
+ }
688
+
586
689
public void testRemoteClusterOnlyCCSSuccessfulResult () throws Exception {
587
690
// for remote-only queries, we can't use the SearchListenerPlugin since that listens for search
588
691
// stage on the local cluster, so we only test final state of the search response
0 commit comments