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

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.
This commit is contained in:
Armin Braun 2024-11-13 19:03:34 +01:00 committed by GitHub
parent 15930cdbdf
commit adf73285d4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 161 additions and 269 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -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.assertAllSuccessful;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; 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.hasId;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasScore; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasScore;
import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder;
@ -159,21 +160,13 @@ public class CompletionSuggestSearchIT extends ESIntegTestCase {
} }
indexRandom(true, indexRequestBuilders); indexRandom(true, indexRequestBuilders);
CompletionSuggestionBuilder noText = SuggestBuilders.completionSuggestion(FIELD); 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"); 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)), 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
); prepareSearch(INDEX).suggest(new SuggestBuilder().addSuggestion("foo", withText).setGlobalText("bogus"))
// 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")
); );
} }

View file

@ -68,6 +68,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -304,6 +305,10 @@ public class ElasticsearchAssertions {
assertResponse(searchRequestBuilder, res -> assertHitCount(res, expectedHitCount)); 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) { public static void assertHitCount(ActionFuture<SearchResponse> responseFuture, long expectedHitCount) {
try { try {
assertResponse(responseFuture, res -> assertHitCount(res, expectedHitCount)); assertResponse(responseFuture, res -> assertHitCount(res, expectedHitCount));
@ -375,6 +380,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( public static <Q extends ActionRequest, R extends ActionResponse> void assertResponse(
RequestBuilder<Q, R> searchRequestBuilder, RequestBuilder<Q, R> searchRequestBuilder,
Consumer<R> consumer Consumer<R> consumer