瀏覽代碼

Add some utilties to run search queries in parallel in ITs (#115590) (#117330)

We have loads of tests that assert the same thing about a number of
different queries. This introduces some tooling to run some of these
spots in parallel.
I only changed a couple of examples in the tests for now, but in general
this could be used to save thousands of lines of test code and more
importantly, get some coverage on parallel query execution which is
covered very little today.
Armin Braun 11 月之前
父節點
當前提交
e0e96a1a7e

+ 7 - 17
plugins/mapper-size/src/internalClusterTest/java/org/elasticsearch/index/mapper/size/SizeMappingIT.java

@@ -25,6 +25,7 @@ import java.util.Map;
 
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponses;
 import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder;
 import static org.hamcrest.Matchers.hasKey;
 import static org.hamcrest.Matchers.is;
@@ -136,14 +137,11 @@ public class SizeMappingIT extends ESIntegTestCase {
         assertAcked(prepareCreate("test").setMapping("_size", "enabled=false"));
         final String source = "{\"f\":\"" + randomAlphaOfLengthBetween(1, 100) + "\"}";
         indexRandom(true, prepareIndex("test").setId("1").setSource(source, XContentType.JSON));
-        assertResponse(
+        assertResponses(
+            response -> assertNull(response.getHits().getHits()[0].getFields().get("_size")),
             prepareSearch("test").addFetchField("_size"),
-            response -> assertNull(response.getHits().getHits()[0].getFields().get("_size"))
-        );
-
-        assertResponse(
             prepareSearch("test").addFetchField("*"),
-            response -> assertNull(response.getHits().getHits()[0].getFields().get("_size"))
+            prepareSearch("test").addStoredField("*")
         );
 
         assertResponse(
@@ -156,19 +154,11 @@ public class SizeMappingIT extends ESIntegTestCase {
         assertAcked(prepareCreate("test"));
         final String source = "{\"f\":\"" + randomAlphaOfLengthBetween(1, 100) + "\"}";
         indexRandom(true, prepareIndex("test").setId("1").setSource(source, XContentType.JSON));
-        assertResponse(
+        assertResponses(
+            response -> assertNull(response.getHits().getHits()[0].getFields().get("_size")),
             prepareSearch("test").addFetchField("_size"),
-            response -> assertNull(response.getHits().getHits()[0].getFields().get("_size"))
-        );
-
-        assertResponse(
             prepareSearch("test").addFetchField("*"),
-            response -> assertNull(response.getHits().getHits()[0].getFields().get("_size"))
-        );
-
-        assertResponse(
-            prepareSearch("test").addStoredField("*"),
-            response -> assertNull(response.getHits().getHits()[0].getFields().get("_size"))
+            prepareSearch("test").addStoredField("*")
         );
     }
 }

+ 9 - 32
server/src/internalClusterTest/java/org/elasticsearch/search/query/MultiMatchQueryIT.java

@@ -57,6 +57,7 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitC
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailuresAndResponse;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponses;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHitsWithoutFailures;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSecondHit;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasId;
@@ -772,6 +773,7 @@ public class MultiMatchQueryIT extends ESIntegTestCase {
         );
         // counter example
         assertHitCount(
+            0L,
             prepareSearch("test").setQuery(
                 randomizeType(
                     multiMatchQuery("captain america marvel hero", "first_name", "last_name", "category").type(
@@ -779,19 +781,13 @@ public class MultiMatchQueryIT extends ESIntegTestCase {
                     ).operator(Operator.AND)
                 )
             ),
-            0L
-        );
-
-        // counter example
-        assertHitCount(
             prepareSearch("test").setQuery(
                 randomizeType(
                     multiMatchQuery("captain america marvel hero", "first_name", "last_name", "category").type(
                         randomBoolean() ? MultiMatchQueryBuilder.Type.CROSS_FIELDS : MultiMatchQueryBuilder.DEFAULT_TYPE
                     ).operator(Operator.AND)
                 )
-            ),
-            0L
+            )
         );
 
         // test if boosts work
@@ -828,40 +824,21 @@ public class MultiMatchQueryIT extends ESIntegTestCase {
             }
         );
         // Test group based on numeric fields
-        assertResponse(
+        assertResponses(response -> {
+            assertHitCount(response, 1L);
+            assertFirstHit(response, hasId("theone"));
+        },
             prepareSearch("test").setQuery(randomizeType(multiMatchQuery("15", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS))),
-            response -> {
-                assertHitCount(response, 1L);
-                assertFirstHit(response, hasId("theone"));
-            }
-        );
-        assertResponse(
             prepareSearch("test").setQuery(
                 randomizeType(multiMatchQuery("15", "skill", "first_name").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS))
             ),
-            response -> {
-                assertHitCount(response, 1L);
-                assertFirstHit(response, hasId("theone"));
-            }
-        );
-        // Two numeric fields together caused trouble at one point!
-        assertResponse(
+            // Two numeric fields together caused trouble at one point!
             prepareSearch("test").setQuery(
                 randomizeType(multiMatchQuery("15", "int-field", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS))
             ),
-            response -> {
-                assertHitCount(response, 1L);
-                assertFirstHit(response, hasId("theone"));
-            }
-        );
-        assertResponse(
             prepareSearch("test").setQuery(
                 randomizeType(multiMatchQuery("15", "int-field", "first_name", "skill").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS))
-            ),
-            response -> {
-                assertHitCount(response, 1L);
-                assertFirstHit(response, hasId("theone"));
-            }
+            )
         );
         assertResponse(
             prepareSearch("test").setQuery(

+ 92 - 184
server/src/internalClusterTest/java/org/elasticsearch/search/query/SearchQueryIT.java

@@ -108,6 +108,7 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitC
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailuresAndResponse;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponses;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHits;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHitsWithoutFailures;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSecondHit;
@@ -216,21 +217,14 @@ public class SearchQueryIT extends ESIntegTestCase {
                 assertThat(searchHit, hasScore(1.0f));
             }
         });
-        assertResponse(
+        assertResponses(response -> {
+            assertHitCount(response, 2L);
+            assertFirstHit(response, hasScore(response.getHits().getAt(1).getScore()));
+        },
+            prepareSearch("test").setQuery(constantScoreQuery(matchQuery("field1", "quick")).boost(1.0f + random().nextFloat())),
             prepareSearch("test").setQuery(
                 boolQuery().must(matchAllQuery()).must(constantScoreQuery(matchQuery("field1", "quick")).boost(1.0f + random().nextFloat()))
-            ),
-            response -> {
-                assertHitCount(response, 2L);
-                assertFirstHit(response, hasScore(response.getHits().getAt(1).getScore()));
-            }
-        );
-        assertResponse(
-            prepareSearch("test").setQuery(constantScoreQuery(matchQuery("field1", "quick")).boost(1.0f + random().nextFloat())),
-            response -> {
-                assertHitCount(response, 2L);
-                assertFirstHit(response, hasScore(response.getHits().getAt(1).getScore()));
-            }
+            )
         );
         assertResponse(
             prepareSearch("test").setQuery(
@@ -800,20 +794,18 @@ public class SearchQueryIT extends ESIntegTestCase {
         prepareIndex("test").setId("2").setSource("str", "shay", "date", "2012-02-05", "num", 20).get();
         refresh();
 
-        assertResponse(prepareSearch().setQuery(queryStringQuery("num:>19")), response -> {
+        assertResponses(response -> {
             assertHitCount(response, 1L);
             assertFirstHit(response, hasId("2"));
-        });
-        assertHitCount(prepareSearch().setQuery(queryStringQuery("num:>20")), 0L);
+        }, prepareSearch().setQuery(queryStringQuery("num:>19")), prepareSearch().setQuery(queryStringQuery("num:>=20")));
 
-        assertResponse(prepareSearch().setQuery(queryStringQuery("num:>=20")), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("2"));
-        });
-        assertHitCount(prepareSearch().setQuery(queryStringQuery("num:>11")), 2L);
-        assertHitCount(prepareSearch().setQuery(queryStringQuery("num:<20")), 1L);
-        assertHitCount(prepareSearch().setQuery(queryStringQuery("num:<=20")), 2L);
-        assertHitCount(prepareSearch().setQuery(queryStringQuery("+num:>11 +num:<20")), 1L);
+        assertHitCount(prepareSearch().setQuery(queryStringQuery("num:>20")), 0L);
+        assertHitCount(2L, prepareSearch().setQuery(queryStringQuery("num:>11")), prepareSearch().setQuery(queryStringQuery("num:<=20")));
+        assertHitCount(
+            1L,
+            prepareSearch().setQuery(queryStringQuery("num:<20")),
+            prepareSearch().setQuery(queryStringQuery("+num:>11 +num:<20"))
+        );
     }
 
     public void testEmptytermsQuery() throws Exception {
@@ -826,8 +818,11 @@ public class SearchQueryIT extends ESIntegTestCase {
             prepareIndex("test").setId("3").setSource("term", "3"),
             prepareIndex("test").setId("4").setSource("term", "4")
         );
-        assertHitCount(prepareSearch("test").setQuery(constantScoreQuery(termsQuery("term", new String[0]))), 0L);
-        assertHitCount(prepareSearch("test").setQuery(idsQuery()), 0L);
+        assertHitCount(
+            0L,
+            prepareSearch("test").setQuery(constantScoreQuery(termsQuery("term", new String[0]))),
+            prepareSearch("test").setQuery(idsQuery())
+        );
     }
 
     public void testTermsQuery() throws Exception {
@@ -866,9 +861,12 @@ public class SearchQueryIT extends ESIntegTestCase {
         assertSearchHitsWithoutFailures(prepareSearch("test").setQuery(constantScoreQuery(termsQuery("dbl", new double[] { 2, 5 }))), "2");
         assertSearchHitsWithoutFailures(prepareSearch("test").setQuery(constantScoreQuery(termsQuery("lng", new long[] { 2, 5 }))), "2");
         // test valid type, but no matching terms
-        assertHitCount(prepareSearch("test").setQuery(constantScoreQuery(termsQuery("str", "5", "6"))), 0L);
-        assertHitCount(prepareSearch("test").setQuery(constantScoreQuery(termsQuery("dbl", new double[] { 5, 6 }))), 0L);
-        assertHitCount(prepareSearch("test").setQuery(constantScoreQuery(termsQuery("lng", new long[] { 5, 6 }))), 0L);
+        assertHitCount(
+            0L,
+            prepareSearch("test").setQuery(constantScoreQuery(termsQuery("str", "5", "6"))),
+            prepareSearch("test").setQuery(constantScoreQuery(termsQuery("dbl", new double[] { 5, 6 }))),
+            prepareSearch("test").setQuery(constantScoreQuery(termsQuery("lng", new long[] { 5, 6 })))
+        );
     }
 
     public void testTermsLookupFilter() throws Exception {
@@ -1064,106 +1062,35 @@ public class SearchQueryIT extends ESIntegTestCase {
             .get();
         refresh();
 
-        logger.info("--> term query on 1");
-        assertResponse(prepareSearch("test").setQuery(termQuery("num_byte", 1)), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(termQuery("num_short", 1)), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(termQuery("num_integer", 1)), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(termQuery("num_long", 1)), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(termQuery("num_float", 1)), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(termQuery("num_double", 1)), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        logger.info("--> terms query on 1");
-        assertResponse(prepareSearch("test").setQuery(termsQuery("num_byte", new int[] { 1 })), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(termsQuery("num_short", new int[] { 1 })), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(termsQuery("num_integer", new int[] { 1 })), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(termsQuery("num_long", new int[] { 1 })), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(termsQuery("num_float", new double[] { 1 })), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(termsQuery("num_double", new double[] { 1 })), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        logger.info("--> term filter on 1");
-        assertResponse(prepareSearch("test").setQuery(constantScoreQuery(termQuery("num_byte", 1))), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(constantScoreQuery(termQuery("num_short", 1))), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(constantScoreQuery(termQuery("num_integer", 1))), response -> {
+        assertResponses(response -> {
             assertHitCount(response, 1L);
             assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(constantScoreQuery(termQuery("num_long", 1))), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(constantScoreQuery(termQuery("num_float", 1))), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(constantScoreQuery(termQuery("num_double", 1))), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        logger.info("--> terms filter on 1");
-        assertResponse(prepareSearch("test").setQuery(constantScoreQuery(termsQuery("num_byte", new int[] { 1 }))), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(constantScoreQuery(termsQuery("num_short", new int[] { 1 }))), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(constantScoreQuery(termsQuery("num_integer", new int[] { 1 }))), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(constantScoreQuery(termsQuery("num_long", new int[] { 1 }))), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(constantScoreQuery(termsQuery("num_float", new int[] { 1 }))), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
-        assertResponse(prepareSearch("test").setQuery(constantScoreQuery(termsQuery("num_double", new int[] { 1 }))), response -> {
-            assertHitCount(response, 1L);
-            assertFirstHit(response, hasId("1"));
-        });
+        },
+            prepareSearch("test").setQuery(termQuery("num_byte", 1)),
+            prepareSearch("test").setQuery(termQuery("num_short", 1)),
+            prepareSearch("test").setQuery(termQuery("num_integer", 1)),
+            prepareSearch("test").setQuery(termQuery("num_long", 1)),
+            prepareSearch("test").setQuery(termQuery("num_float", 1)),
+            prepareSearch("test").setQuery(termQuery("num_double", 1)),
+            prepareSearch("test").setQuery(termsQuery("num_byte", new int[] { 1 })),
+            prepareSearch("test").setQuery(termsQuery("num_short", new int[] { 1 })),
+            prepareSearch("test").setQuery(termsQuery("num_integer", new int[] { 1 })),
+            prepareSearch("test").setQuery(termsQuery("num_long", new int[] { 1 })),
+            prepareSearch("test").setQuery(termsQuery("num_float", new double[] { 1 })),
+            prepareSearch("test").setQuery(termsQuery("num_double", new double[] { 1 })),
+            prepareSearch("test").setQuery(constantScoreQuery(termQuery("num_byte", 1))),
+            prepareSearch("test").setQuery(constantScoreQuery(termQuery("num_short", 1))),
+            prepareSearch("test").setQuery(constantScoreQuery(termQuery("num_integer", 1))),
+            prepareSearch("test").setQuery(constantScoreQuery(termQuery("num_long", 1))),
+            prepareSearch("test").setQuery(constantScoreQuery(termQuery("num_float", 1))),
+            prepareSearch("test").setQuery(constantScoreQuery(termQuery("num_double", 1))),
+            prepareSearch("test").setQuery(constantScoreQuery(termsQuery("num_byte", new int[] { 1 }))),
+            prepareSearch("test").setQuery(constantScoreQuery(termsQuery("num_short", new int[] { 1 }))),
+            prepareSearch("test").setQuery(constantScoreQuery(termsQuery("num_integer", new int[] { 1 }))),
+            prepareSearch("test").setQuery(constantScoreQuery(termsQuery("num_long", new int[] { 1 }))),
+            prepareSearch("test").setQuery(constantScoreQuery(termsQuery("num_float", new int[] { 1 }))),
+            prepareSearch("test").setQuery(constantScoreQuery(termsQuery("num_double", new int[] { 1 })))
+        );
     }
 
     public void testNumericRangeFilter_2826() throws Exception {
@@ -1301,16 +1228,19 @@ public class SearchQueryIT extends ESIntegTestCase {
         prepareIndex("test").setId("4").setSource("description", "fop", "count", 4).get();
         refresh();
 
-        assertHitCount(prepareSearch("test").setQuery(spanOrQuery(spanMultiTermQueryBuilder(fuzzyQuery("description", "fop")))), 4);
-        assertHitCount(prepareSearch("test").setQuery(spanOrQuery(spanMultiTermQueryBuilder(prefixQuery("description", "fo")))), 4);
-        assertHitCount(prepareSearch("test").setQuery(spanOrQuery(spanMultiTermQueryBuilder(wildcardQuery("description", "oth*")))), 3);
         assertHitCount(
+            4,
+            prepareSearch("test").setQuery(spanOrQuery(spanMultiTermQueryBuilder(fuzzyQuery("description", "fop")))),
+            prepareSearch("test").setQuery(spanOrQuery(spanMultiTermQueryBuilder(prefixQuery("description", "fo"))))
+        );
+        assertHitCount(
+            3,
+            prepareSearch("test").setQuery(spanOrQuery(spanMultiTermQueryBuilder(wildcardQuery("description", "oth*")))),
             prepareSearch("test").setQuery(
                 spanOrQuery(spanMultiTermQueryBuilder(QueryBuilders.rangeQuery("description").from("ffa").to("foo")))
             ),
-            3
+            prepareSearch("test").setQuery(spanOrQuery(spanMultiTermQueryBuilder(regexpQuery("description", "fo{2}"))))
         );
-        assertHitCount(prepareSearch("test").setQuery(spanOrQuery(spanMultiTermQueryBuilder(regexpQuery("description", "fo{2}")))), 3);
     }
 
     public void testSpanNot() throws IOException, ExecutionException, InterruptedException {
@@ -1321,6 +1251,7 @@ public class SearchQueryIT extends ESIntegTestCase {
         refresh();
 
         assertHitCount(
+            1L,
             prepareSearch("test").setQuery(
                 spanNotQuery(
                     spanNearQuery(QueryBuilders.spanTermQuery("description", "quick"), 1).addClause(
@@ -1329,9 +1260,6 @@ public class SearchQueryIT extends ESIntegTestCase {
                     spanTermQuery("description", "brown")
                 )
             ),
-            1L
-        );
-        assertHitCount(
             prepareSearch("test").setQuery(
                 spanNotQuery(
                     spanNearQuery(QueryBuilders.spanTermQuery("description", "quick"), 1).addClause(
@@ -1340,9 +1268,6 @@ public class SearchQueryIT extends ESIntegTestCase {
                     spanTermQuery("description", "sleeping")
                 ).dist(5)
             ),
-            1L
-        );
-        assertHitCount(
             prepareSearch("test").setQuery(
                 spanNotQuery(
                     spanNearQuery(QueryBuilders.spanTermQuery("description", "quick"), 1).addClause(
@@ -1350,8 +1275,7 @@ public class SearchQueryIT extends ESIntegTestCase {
                     ),
                     spanTermQuery("description", "jumped")
                 ).pre(1).post(1)
-            ),
-            1L
+            )
         );
     }
 
@@ -1423,22 +1347,19 @@ public class SearchQueryIT extends ESIntegTestCase {
 
     public void testMultiFieldQueryString() {
         prepareIndex("test").setId("1").setSource("field1", "value1", "field2", "value2").setRefreshPolicy(IMMEDIATE).get();
-
-        logger.info("regular");
-        assertHitCount(prepareSearch("test").setQuery(queryStringQuery("value1").field("field1").field("field2")), 1);
-        assertHitCount(prepareSearch("test").setQuery(queryStringQuery("field\\*:value1")), 1);
-        logger.info("prefix");
-        assertHitCount(prepareSearch("test").setQuery(queryStringQuery("value*").field("field1").field("field2")), 1);
-        assertHitCount(prepareSearch("test").setQuery(queryStringQuery("field\\*:value*")), 1);
-        logger.info("wildcard");
-        assertHitCount(prepareSearch("test").setQuery(queryStringQuery("v?lue*").field("field1").field("field2")), 1);
-        assertHitCount(prepareSearch("test").setQuery(queryStringQuery("field\\*:v?lue*")), 1);
-        logger.info("fuzzy");
-        assertHitCount(prepareSearch("test").setQuery(queryStringQuery("value~").field("field1").field("field2")), 1);
-        assertHitCount(prepareSearch("test").setQuery(queryStringQuery("field\\*:value~")), 1);
-        logger.info("regexp");
-        assertHitCount(prepareSearch("test").setQuery(queryStringQuery("/value[01]/").field("field1").field("field2")), 1);
-        assertHitCount(prepareSearch("test").setQuery(queryStringQuery("field\\*:/value[01]/")), 1);
+        assertHitCount(
+            1,
+            prepareSearch("test").setQuery(queryStringQuery("value1").field("field1").field("field2")),
+            prepareSearch("test").setQuery(queryStringQuery("field\\*:value1")),
+            prepareSearch("test").setQuery(queryStringQuery("value*").field("field1").field("field2")),
+            prepareSearch("test").setQuery(queryStringQuery("field\\*:value*")),
+            prepareSearch("test").setQuery(queryStringQuery("v?lue*").field("field1").field("field2")),
+            prepareSearch("test").setQuery(queryStringQuery("field\\*:v?lue*")),
+            prepareSearch("test").setQuery(queryStringQuery("value~").field("field1").field("field2")),
+            prepareSearch("test").setQuery(queryStringQuery("field\\*:value~")),
+            prepareSearch("test").setQuery(queryStringQuery("/value[01]/").field("field1").field("field2")),
+            prepareSearch("test").setQuery(queryStringQuery("field\\*:/value[01]/"))
+        );
     }
 
     // see #3797
@@ -1448,9 +1369,12 @@ public class SearchQueryIT extends ESIntegTestCase {
         prepareIndex("test").setId("1").setSource("field1", 123, "field2", "value2").get();
         refresh();
 
-        assertHitCount(prepareSearch("test").setQuery(multiMatchQuery("value2", "field2").field("field1", 2).lenient(true)), 1L);
-        assertHitCount(prepareSearch("test").setQuery(multiMatchQuery("value2", "field2").field("field1", 2).lenient(true)), 1L);
-        assertHitCount(prepareSearch("test").setQuery(multiMatchQuery("value2").field("field2", 2).lenient(true)), 1L);
+        assertHitCount(
+            1L,
+            prepareSearch("test").setQuery(multiMatchQuery("value2", "field2").field("field1", 2).lenient(true)),
+            prepareSearch("test").setQuery(multiMatchQuery("value2", "field2").field("field1", 2).lenient(true)),
+            prepareSearch("test").setQuery(multiMatchQuery("value2").field("field2", 2).lenient(true))
+        );
     }
 
     public void testMinScore() throws ExecutionException, InterruptedException {
@@ -1483,24 +1407,15 @@ public class SearchQueryIT extends ESIntegTestCase {
 
         assertHitCount(prepareSearch("test").setQuery(QueryBuilders.queryStringQuery("\"one two\"").defaultField("desc")), 2);
         assertHitCount(
+            1,
             prepareSearch("test").setPostFilter(QueryBuilders.termQuery("type", "customer"))
                 .setQuery(QueryBuilders.queryStringQuery("\"one two\"").field("desc")),
-            1
-        );
-        assertHitCount(
             prepareSearch("test").setPostFilter(QueryBuilders.termQuery("type", "product"))
                 .setQuery(QueryBuilders.queryStringQuery("\"one three\"~5").field("desc")),
-            1
-        );
-        assertHitCount(
             prepareSearch("test").setPostFilter(QueryBuilders.termQuery("type", "customer"))
                 .setQuery(QueryBuilders.queryStringQuery("\"one two\"").defaultField("desc")),
-            1
-        );
-        assertHitCount(
             prepareSearch("test").setPostFilter(QueryBuilders.termQuery("type", "customer"))
-                .setQuery(QueryBuilders.queryStringQuery("\"one two\"").defaultField("desc")),
-            1
+                .setQuery(QueryBuilders.queryStringQuery("\"one two\"").defaultField("desc"))
         );
     }
 
@@ -1602,23 +1517,16 @@ public class SearchQueryIT extends ESIntegTestCase {
                 assertThat(response.getHits().getAt(0).getId(), is("2"));
             }
         );
-        assertResponse(
-            prepareSearch("test").setQuery(
-                QueryBuilders.rangeQuery("date").from("2014-01-01T04:00:00").to("2014-01-01T04:59:00").timeZone("+03:00")
-            ),
-            response -> {
-                assertHitCount(response, 1L);
-                assertThat(response.getHits().getAt(0).getId(), is("3"));
-            }
-        );
-        assertResponse(
+        assertResponses(response -> {
+            assertHitCount(response, 1L);
+            assertThat(response.getHits().getAt(0).getId(), is("3"));
+        },
             prepareSearch("test").setQuery(
                 QueryBuilders.rangeQuery("date").from("2014-01-01").to("2014-01-01T00:59:00").timeZone("-01:00")
             ),
-            response -> {
-                assertHitCount(response, 1L);
-                assertThat(response.getHits().getAt(0).getId(), is("3"));
-            }
+            prepareSearch("test").setQuery(
+                QueryBuilders.rangeQuery("date").from("2014-01-01T04:00:00").to("2014-01-01T04:59:00").timeZone("+03:00")
+            )
         );
         assertResponse(prepareSearch("test").setQuery(QueryBuilders.rangeQuery("date").from("now/d-1d").timeZone("+01:00")), response -> {
             assertHitCount(response, 1L);

+ 11 - 23
server/src/internalClusterTest/java/org/elasticsearch/search/routing/SearchPreferenceIT.java

@@ -33,6 +33,7 @@ import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF
 import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponses;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.greaterThan;
@@ -68,25 +69,20 @@ public class SearchPreferenceIT extends ESIntegTestCase {
             "_prefer_nodes:somenode,server2" };
         for (String pref : preferences) {
             logger.info("--> Testing out preference={}", pref);
-            assertResponse(prepareSearch().setSize(0).setPreference(pref), response -> {
+            assertResponses(response -> {
                 assertThat(RestStatus.OK, equalTo(response.status()));
                 assertThat(pref, response.getFailedShards(), greaterThanOrEqualTo(0));
-            });
-            assertResponse(prepareSearch().setPreference(pref), response -> {
-                assertThat(RestStatus.OK, equalTo(response.status()));
-                assertThat(pref, response.getFailedShards(), greaterThanOrEqualTo(0));
-            });
+            }, prepareSearch().setSize(0).setPreference(pref), prepareSearch().setPreference(pref));
         }
 
         // _only_local is a stricter preference, we need to send the request to a data node
-        assertResponse(dataNodeClient().prepareSearch().setSize(0).setPreference("_only_local"), response -> {
+        assertResponses(response -> {
             assertThat(RestStatus.OK, equalTo(response.status()));
             assertThat("_only_local", response.getFailedShards(), greaterThanOrEqualTo(0));
-        });
-        assertResponse(dataNodeClient().prepareSearch().setPreference("_only_local"), response -> {
-            assertThat(RestStatus.OK, equalTo(response.status()));
-            assertThat("_only_local", response.getFailedShards(), greaterThanOrEqualTo(0));
-        });
+        },
+            dataNodeClient().prepareSearch().setSize(0).setPreference("_only_local"),
+            dataNodeClient().prepareSearch().setPreference("_only_local")
+        );
     }
 
     public void testNoPreferenceRandom() {
@@ -121,19 +117,11 @@ public class SearchPreferenceIT extends ESIntegTestCase {
         prepareIndex("test").setSource("field1", "value1").get();
         refresh();
 
-        assertResponse(
+        assertResponses(
+            response -> assertThat(response.getHits().getTotalHits().value, equalTo(1L)),
             prepareSearch().setQuery(matchAllQuery()),
-            response -> assertThat(response.getHits().getTotalHits().value, equalTo(1L))
-        );
-
-        assertResponse(
             prepareSearch().setQuery(matchAllQuery()).setPreference("_local"),
-            response -> assertThat(response.getHits().getTotalHits().value, equalTo(1L))
-        );
-
-        assertResponse(
-            prepareSearch().setQuery(matchAllQuery()).setPreference("1234"),
-            response -> assertThat(response.getHits().getTotalHits().value, equalTo(1L))
+            prepareSearch().setQuery(matchAllQuery()).setPreference("1234")
         );
     }
 

+ 6 - 13
server/src/internalClusterTest/java/org/elasticsearch/search/suggest/CompletionSuggestSearchIT.java

@@ -61,6 +61,7 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcke
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAllSuccessful;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse;
+import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponses;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasId;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasScore;
 import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder;
@@ -159,21 +160,13 @@ public class CompletionSuggestSearchIT extends ESIntegTestCase {
         }
         indexRandom(true, indexRequestBuilders);
         CompletionSuggestionBuilder noText = SuggestBuilders.completionSuggestion(FIELD);
-        assertResponse(
-            prepareSearch(INDEX).suggest(new SuggestBuilder().addSuggestion("foo", noText).setGlobalText("sugg")),
-            response -> assertSuggestions(response, "foo", "suggestion10", "suggestion9", "suggestion8", "suggestion7", "suggestion6")
-        );
-
         CompletionSuggestionBuilder withText = SuggestBuilders.completionSuggestion(FIELD).text("sugg");
-        assertResponse(
+        assertResponses(
+            response -> assertSuggestions(response, "foo", "suggestion10", "suggestion9", "suggestion8", "suggestion7", "suggestion6"),
+            prepareSearch(INDEX).suggest(new SuggestBuilder().addSuggestion("foo", noText).setGlobalText("sugg")),
             prepareSearch(INDEX).suggest(new SuggestBuilder().addSuggestion("foo", withText)),
-            response -> assertSuggestions(response, "foo", "suggestion10", "suggestion9", "suggestion8", "suggestion7", "suggestion6")
-        );
-
-        // test that suggestion text takes precedence over global text
-        assertResponse(
-            prepareSearch(INDEX).suggest(new SuggestBuilder().addSuggestion("foo", withText).setGlobalText("bogus")),
-            response -> assertSuggestions(response, "foo", "suggestion10", "suggestion9", "suggestion8", "suggestion7", "suggestion6")
+            // test that suggestion text takes precedence over global text
+            prepareSearch(INDEX).suggest(new SuggestBuilder().addSuggestion("foo", withText).setGlobalText("bogus"))
         );
     }
 

+ 36 - 0
test/framework/src/main/java/org/elasticsearch/test/hamcrest/ElasticsearchAssertions.java

@@ -66,6 +66,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
@@ -302,6 +303,10 @@ public class ElasticsearchAssertions {
         assertResponse(searchRequestBuilder, res -> assertHitCount(res, expectedHitCount));
     }
 
+    public static void assertHitCount(long expectedHitCount, SearchRequestBuilder... searchRequestBuilders) {
+        assertResponses(res -> assertHitCount(res, expectedHitCount), searchRequestBuilders);
+    }
+
     public static void assertHitCount(ActionFuture<SearchResponse> responseFuture, long expectedHitCount) {
         try {
             assertResponse(responseFuture, res -> assertHitCount(res, expectedHitCount));
@@ -373,6 +378,37 @@ public class ElasticsearchAssertions {
         }
     }
 
+    /**
+     * Same as {@link #assertResponse(RequestBuilder, Consumer)} but runs the same assertion on multiple requests that are started
+     * concurrently.
+     */
+    @SafeVarargs
+    public static <Q extends ActionRequest, R extends ActionResponse> void assertResponses(
+        Consumer<R> consumer,
+        RequestBuilder<Q, R>... searchRequestBuilder
+    ) {
+        List<Future<R>> futures = new ArrayList<>(searchRequestBuilder.length);
+        for (RequestBuilder<Q, R> builder : searchRequestBuilder) {
+            futures.add(builder.execute());
+        }
+        Throwable tr = null;
+        for (Future<R> f : futures) {
+            try {
+                var res = f.get();
+                try {
+                    consumer.accept(res);
+                } finally {
+                    res.decRef();
+                }
+            } catch (Throwable t) {
+                tr = ExceptionsHelper.useOrSuppress(tr, t);
+            }
+        }
+        if (tr != null) {
+            throw new AssertionError(tr);
+        }
+    }
+
     public static <Q extends ActionRequest, R extends ActionResponse> void assertResponse(
         RequestBuilder<Q, R> searchRequestBuilder,
         Consumer<R> consumer