1010import com .carrotsearch .randomizedtesting .annotations .ThreadLeakFilters ;
1111
1212import org .apache .http .HttpHost ;
13+ import org .elasticsearch .Version ;
1314import org .elasticsearch .client .Request ;
1415import org .elasticsearch .client .RestClient ;
1516import org .elasticsearch .common .Strings ;
2930import java .io .IOException ;
3031import java .util .List ;
3132import java .util .Map ;
32- import java .util .Optional ;
3333import java .util .Set ;
3434import java .util .stream .Collectors ;
3535import java .util .stream .IntStream ;
@@ -127,10 +127,12 @@ void indexDocs(RestClient client, String index, List<Doc> docs) throws IOExcepti
127127 }
128128
129129 private Map <String , Object > run (String query , boolean includeCCSMetadata ) throws IOException {
130- Map <String , Object > resp = runEsql (
131- new RestEsqlTestCase .RequestObjectBuilder ().query (query ).includeCCSMetadata (includeCCSMetadata ).build ()
132- );
133- logger .info ("--> query {} response {}" , query , resp );
130+ var queryBuilder = new RestEsqlTestCase .RequestObjectBuilder ().query (query );
131+ if (includeCCSMetadata ) {
132+ queryBuilder .includeCCSMetadata (true );
133+ }
134+ Map <String , Object > resp = runEsql (queryBuilder .build ());
135+ logger .info ("--> query {} response {}" , queryBuilder , resp );
134136 return resp ;
135137 }
136138
@@ -156,7 +158,7 @@ private Map<String, Object> runEsql(RestEsqlTestCase.RequestObjectBuilder reques
156158
157159 public void testCount () throws Exception {
158160 {
159- boolean includeCCSMetadata = randomBoolean ();
161+ boolean includeCCSMetadata = includeCCSMetadata ();
160162 Map <String , Object > result = run ("FROM test-local-index,*:test-remote-index | STATS c = COUNT(*)" , includeCCSMetadata );
161163 var columns = List .of (Map .of ("name" , "c" , "type" , "long" ));
162164 var values = List .of (List .of (localDocs .size () + remoteDocs .size ()));
@@ -165,13 +167,16 @@ public void testCount() throws Exception {
165167 if (includeCCSMetadata ) {
166168 mapMatcher = mapMatcher .entry ("_clusters" , any (Map .class ));
167169 }
168- assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ).entry ("took" , greaterThanOrEqualTo (0 )));
170+ if (ccsMetadataAvailable ()) {
171+ mapMatcher = mapMatcher .entry ("took" , greaterThanOrEqualTo (0 ));
172+ }
173+ assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ));
169174 if (includeCCSMetadata ) {
170175 assertClusterDetailsMap (result , false );
171176 }
172177 }
173178 {
174- boolean includeCCSMetadata = randomBoolean ();
179+ boolean includeCCSMetadata = includeCCSMetadata ();
175180 Map <String , Object > result = run ("FROM *:test-remote-index | STATS c = COUNT(*)" , includeCCSMetadata );
176181 var columns = List .of (Map .of ("name" , "c" , "type" , "long" ));
177182 var values = List .of (List .of (remoteDocs .size ()));
@@ -180,7 +185,10 @@ public void testCount() throws Exception {
180185 if (includeCCSMetadata ) {
181186 mapMatcher = mapMatcher .entry ("_clusters" , any (Map .class ));
182187 }
183- assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ).entry ("took" , greaterThanOrEqualTo (0 )));
188+ if (ccsMetadataAvailable ()) {
189+ mapMatcher = mapMatcher .entry ("took" , greaterThanOrEqualTo (0 ));
190+ }
191+ assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ));
184192 if (includeCCSMetadata ) {
185193 assertClusterDetailsMap (result , true );
186194 }
@@ -189,7 +197,7 @@ public void testCount() throws Exception {
189197
190198 public void testUngroupedAggs () throws Exception {
191199 {
192- boolean includeCCSMetadata = randomBoolean ();
200+ boolean includeCCSMetadata = includeCCSMetadata ();
193201 Map <String , Object > result = run ("FROM test-local-index,*:test-remote-index | STATS total = SUM(data)" , includeCCSMetadata );
194202 var columns = List .of (Map .of ("name" , "total" , "type" , "long" ));
195203 long sum = Stream .concat (localDocs .stream (), remoteDocs .stream ()).mapToLong (d -> d .data ).sum ();
@@ -200,13 +208,16 @@ public void testUngroupedAggs() throws Exception {
200208 if (includeCCSMetadata ) {
201209 mapMatcher = mapMatcher .entry ("_clusters" , any (Map .class ));
202210 }
203- assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ).entry ("took" , greaterThanOrEqualTo (0 )));
211+ if (ccsMetadataAvailable ()) {
212+ mapMatcher = mapMatcher .entry ("took" , greaterThanOrEqualTo (0 ));
213+ }
214+ assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ));
204215 if (includeCCSMetadata ) {
205216 assertClusterDetailsMap (result , false );
206217 }
207218 }
208219 {
209- boolean includeCCSMetadata = randomBoolean ();
220+ boolean includeCCSMetadata = includeCCSMetadata ();
210221 Map <String , Object > result = run ("FROM *:test-remote-index | STATS total = SUM(data)" , includeCCSMetadata );
211222 var columns = List .of (Map .of ("name" , "total" , "type" , "long" ));
212223 long sum = remoteDocs .stream ().mapToLong (d -> d .data ).sum ();
@@ -216,12 +227,16 @@ public void testUngroupedAggs() throws Exception {
216227 if (includeCCSMetadata ) {
217228 mapMatcher = mapMatcher .entry ("_clusters" , any (Map .class ));
218229 }
219- assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ).entry ("took" , greaterThanOrEqualTo (0 )));
230+ if (ccsMetadataAvailable ()) {
231+ mapMatcher = mapMatcher .entry ("took" , greaterThanOrEqualTo (0 ));
232+ }
233+ assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ));
220234 if (includeCCSMetadata ) {
221235 assertClusterDetailsMap (result , true );
222236 }
223237 }
224238 {
239+ assumeTrue ("requires ccs metadata" , ccsMetadataAvailable ());
225240 Map <String , Object > result = runWithColumnarAndIncludeCCSMetadata ("FROM *:test-remote-index | STATS total = SUM(data)" );
226241 var columns = List .of (Map .of ("name" , "total" , "type" , "long" ));
227242 long sum = remoteDocs .stream ().mapToLong (d -> d .data ).sum ();
@@ -293,7 +308,7 @@ private void assertClusterDetailsMap(Map<String, Object> result, boolean remoteO
293308
294309 public void testGroupedAggs () throws Exception {
295310 {
296- boolean includeCCSMetadata = randomBoolean ();
311+ boolean includeCCSMetadata = includeCCSMetadata ();
297312 Map <String , Object > result = run (
298313 "FROM test-local-index,*:test-remote-index | STATS total = SUM(data) BY color | SORT color" ,
299314 includeCCSMetadata
@@ -311,13 +326,16 @@ public void testGroupedAggs() throws Exception {
311326 if (includeCCSMetadata ) {
312327 mapMatcher = mapMatcher .entry ("_clusters" , any (Map .class ));
313328 }
314- assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ).entry ("took" , greaterThanOrEqualTo (0 )));
329+ if (ccsMetadataAvailable ()) {
330+ mapMatcher = mapMatcher .entry ("took" , greaterThanOrEqualTo (0 ));
331+ }
332+ assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ));
315333 if (includeCCSMetadata ) {
316334 assertClusterDetailsMap (result , false );
317335 }
318336 }
319337 {
320- boolean includeCCSMetadata = randomBoolean ();
338+ boolean includeCCSMetadata = includeCCSMetadata ();
321339 Map <String , Object > result = run (
322340 "FROM *:test-remote-index | STATS total = SUM(data) by color | SORT color" ,
323341 includeCCSMetadata
@@ -336,29 +354,57 @@ public void testGroupedAggs() throws Exception {
336354 if (includeCCSMetadata ) {
337355 mapMatcher = mapMatcher .entry ("_clusters" , any (Map .class ));
338356 }
339- assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ).entry ("took" , greaterThanOrEqualTo (0 )));
357+ if (ccsMetadataAvailable ()) {
358+ mapMatcher = mapMatcher .entry ("took" , greaterThanOrEqualTo (0 ));
359+ }
360+ assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ));
340361 if (includeCCSMetadata ) {
341362 assertClusterDetailsMap (result , true );
342363 }
343364 }
344365 }
345366
367+ public void testIndexPattern () throws Exception {
368+ {
369+ String indexPattern = randomFrom (
370+ "test-local-index,*:test-remote-index" ,
371+ "test-local-index,*:test-remote-*" ,
372+ "test-local-index,*:test-*" ,
373+ "test-*,*:test-remote-index"
374+ );
375+ Map <String , Object > result = run ("FROM " + indexPattern + " | STATS c = COUNT(*)" , false );
376+ var columns = List .of (Map .of ("name" , "c" , "type" , "long" ));
377+ var values = List .of (List .of (localDocs .size () + remoteDocs .size ()));
378+ MapMatcher mapMatcher = matchesMap ();
379+ if (ccsMetadataAvailable ()) {
380+ mapMatcher = mapMatcher .entry ("took" , greaterThanOrEqualTo (0 ));
381+ }
382+ assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ));
383+ }
384+ {
385+ String indexPattern = randomFrom ("*:test-remote-index" , "*:test-remote-*" , "*:test-*" );
386+ Map <String , Object > result = run ("FROM " + indexPattern + " | STATS c = COUNT(*)" , false );
387+ var columns = List .of (Map .of ("name" , "c" , "type" , "long" ));
388+ var values = List .of (List .of (remoteDocs .size ()));
389+
390+ MapMatcher mapMatcher = matchesMap ();
391+ if (ccsMetadataAvailable ()) {
392+ mapMatcher = mapMatcher .entry ("took" , greaterThanOrEqualTo (0 ));
393+ }
394+ assertMap (result , mapMatcher .entry ("columns" , columns ).entry ("values" , values ));
395+ }
396+ }
397+
346398 private RestClient remoteClusterClient () throws IOException {
347399 var clusterHosts = parseClusterHosts (remoteCluster .getHttpAddresses ());
348400 return buildClient (restClientSettings (), clusterHosts .toArray (new HttpHost [0 ]));
349401 }
350402
351- private TestFeatureService remoteFeaturesService () throws IOException {
352- if (remoteFeaturesService == null ) {
353- try (RestClient remoteClient = remoteClusterClient ()) {
354- var remoteNodeVersions = readVersionsFromNodesInfo (remoteClient );
355- var semanticNodeVersions = remoteNodeVersions .stream ()
356- .map (ESRestTestCase ::parseLegacyVersion )
357- .flatMap (Optional ::stream )
358- .collect (Collectors .toSet ());
359- remoteFeaturesService = createTestFeatureService (getClusterStateFeatures (remoteClient ), semanticNodeVersions );
360- }
361- }
362- return remoteFeaturesService ;
403+ private static boolean ccsMetadataAvailable () {
404+ return Clusters .localClusterVersion ().onOrAfter (Version .V_8_16_0 );
405+ }
406+
407+ private static boolean includeCCSMetadata () {
408+ return ccsMetadataAvailable () && randomBoolean ();
363409 }
364410}
0 commit comments