Merge pull request #14286 from cbuescher/add-loop-querytests

Tests: run base query tests for more than one random query
This commit is contained in:
Christoph Büscher 2015-10-28 15:40:21 +01:00
commit e7294322af
2 changed files with 85 additions and 68 deletions

View File

@ -57,7 +57,6 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.env.EnvironmentModule; import org.elasticsearch.env.EnvironmentModule;
import org.elasticsearch.index.Index; import org.elasticsearch.index.Index;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.analysis.AnalysisModule; import org.elasticsearch.index.analysis.AnalysisModule;
import org.elasticsearch.index.cache.IndexCache; import org.elasticsearch.index.cache.IndexCache;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache; import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
@ -115,6 +114,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
BOOLEAN_FIELD_NAME, DATE_FIELD_NAME, OBJECT_FIELD_NAME, GEO_POINT_FIELD_NAME, GEO_SHAPE_FIELD_NAME }; BOOLEAN_FIELD_NAME, DATE_FIELD_NAME, OBJECT_FIELD_NAME, GEO_POINT_FIELD_NAME, GEO_SHAPE_FIELD_NAME };
protected static final String[] MAPPED_LEAF_FIELD_NAMES = new String[] { STRING_FIELD_NAME, INT_FIELD_NAME, DOUBLE_FIELD_NAME, protected static final String[] MAPPED_LEAF_FIELD_NAMES = new String[] { STRING_FIELD_NAME, INT_FIELD_NAME, DOUBLE_FIELD_NAME,
BOOLEAN_FIELD_NAME, DATE_FIELD_NAME, GEO_POINT_FIELD_NAME }; BOOLEAN_FIELD_NAME, DATE_FIELD_NAME, GEO_POINT_FIELD_NAME };
private static final int NUMBER_OF_TESTQUERIES = 20;
private static Injector injector; private static Injector injector;
private static IndexQueryParserService queryParserService; private static IndexQueryParserService queryParserService;
@ -305,12 +305,14 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
* and asserts equality on the two queries. * and asserts equality on the two queries.
*/ */
public void testFromXContent() throws IOException { public void testFromXContent() throws IOException {
for (int runs = 0; runs < NUMBER_OF_TESTQUERIES; runs++) {
QB testQuery = createTestQueryBuilder(); QB testQuery = createTestQueryBuilder();
assertParsedQuery(testQuery.toString(), testQuery); assertParsedQuery(testQuery.toString(), testQuery);
for (Map.Entry<String, QB> alternateVersion : getAlternateVersions().entrySet()) { for (Map.Entry<String, QB> alternateVersion : getAlternateVersions().entrySet()) {
assertParsedQuery(alternateVersion.getKey(), alternateVersion.getValue()); assertParsedQuery(alternateVersion.getKey(), alternateVersion.getValue());
} }
} }
}
/** /**
* Returns alternate string representation of the query that need to be tested as they are never used as output * Returns alternate string representation of the query that need to be tested as they are never used as output
@ -360,42 +362,45 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
* assertions being made on the result to the implementing subclass. * assertions being made on the result to the implementing subclass.
*/ */
public void testToQuery() throws IOException { public void testToQuery() throws IOException {
for (int runs = 0; runs < NUMBER_OF_TESTQUERIES; runs++) {
QueryShardContext context = createShardContext(); QueryShardContext context = createShardContext();
context.setAllowUnmappedFields(true); context.setAllowUnmappedFields(true);
QB firstQuery = createTestQueryBuilder(); QB firstQuery = createTestQueryBuilder();
QB controlQuery = copyQuery(firstQuery); QB controlQuery = copyQuery(firstQuery);
setSearchContext(randomTypes); // only set search context for toQuery to be more realistic setSearchContext(randomTypes); // only set search context for toQuery to be more realistic
Query firstLuceneQuery = firstQuery.toQuery(context); Query firstLuceneQuery = firstQuery.toQuery(context);
assertLuceneQuery(firstQuery, firstLuceneQuery, context); assertLuceneQuery(firstQuery, firstLuceneQuery, context);
SearchContext.removeCurrent(); // remove after assertLuceneQuery since the assertLuceneQuery impl might access the context as well SearchContext.removeCurrent(); // remove after assertLuceneQuery since the assertLuceneQuery impl might access the context as well
assertTrue("query is not equal to its copy after calling toQuery, firstQuery: " + firstQuery + ", secondQuery: " + controlQuery, assertTrue(
"query is not equal to its copy after calling toQuery, firstQuery: " + firstQuery + ", secondQuery: " + controlQuery,
firstQuery.equals(controlQuery)); firstQuery.equals(controlQuery));
assertTrue("equals is not symmetric after calling toQuery, firstQuery: " + firstQuery + ", secondQuery: " + controlQuery, assertTrue("equals is not symmetric after calling toQuery, firstQuery: " + firstQuery + ", secondQuery: " + controlQuery,
controlQuery.equals(firstQuery)); controlQuery.equals(firstQuery));
assertThat("query copy's hashcode is different from original hashcode after calling toQuery, firstQuery: " + firstQuery assertThat("query copy's hashcode is different from original hashcode after calling toQuery, firstQuery: " + firstQuery
+ ", secondQuery: " + controlQuery, controlQuery.hashCode(), equalTo(firstQuery.hashCode())); + ", secondQuery: " + controlQuery, controlQuery.hashCode(), equalTo(firstQuery.hashCode()));
QB secondQuery = copyQuery(firstQuery); QB secondQuery = copyQuery(firstQuery);
// query _name never should affect the result of toQuery, we randomly set it to make sure // query _name never should affect the result of toQuery, we randomly set it to make sure
if (randomBoolean()) { if (randomBoolean()) {
secondQuery.queryName(secondQuery.queryName() == null ? randomAsciiOfLengthBetween(1, 30) : secondQuery.queryName() + randomAsciiOfLengthBetween(1, 10)); secondQuery.queryName(secondQuery.queryName() == null ? randomAsciiOfLengthBetween(1, 30) : secondQuery.queryName()
+ randomAsciiOfLengthBetween(1, 10));
} }
setSearchContext(randomTypes); // only set search context for toQuery to be more realistic setSearchContext(randomTypes);
Query secondLuceneQuery = secondQuery.toQuery(context); Query secondLuceneQuery = secondQuery.toQuery(context);
assertLuceneQuery(secondQuery, secondLuceneQuery, context); assertLuceneQuery(secondQuery, secondLuceneQuery, context);
SearchContext.removeCurrent(); // remove after assertLuceneQuery since the assertLuceneQuery impl might access the context as well SearchContext.removeCurrent();
assertThat("two equivalent query builders lead to different lucene queries", secondLuceneQuery, equalTo(firstLuceneQuery)); assertThat("two equivalent query builders lead to different lucene queries", secondLuceneQuery, equalTo(firstLuceneQuery));
// if the initial lucene query is null, changing its boost won't have any effect, we shouldn't test that // if the initial lucene query is null, changing its boost won't have any effect, we shouldn't test that
if (firstLuceneQuery != null && supportsBoostAndQueryName()) { if (firstLuceneQuery != null && supportsBoostAndQueryName()) {
secondQuery.boost(firstQuery.boost() + 1f + randomFloat()); secondQuery.boost(firstQuery.boost() + 1f + randomFloat());
setSearchContext(randomTypes); // only set search context for toQuery to be more realistic setSearchContext(randomTypes);
Query thirdLuceneQuery = secondQuery.toQuery(context); Query thirdLuceneQuery = secondQuery.toQuery(context);
SearchContext.removeCurrent(); SearchContext.removeCurrent();
assertThat("modifying the boost doesn't affect the corresponding lucene query", firstLuceneQuery, not(equalTo(thirdLuceneQuery))); assertThat("modifying the boost doesn't affect the corresponding lucene query", firstLuceneQuery,
not(equalTo(thirdLuceneQuery)));
}
} }
} }
@ -443,9 +448,11 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
* Test serialization and deserialization of the test query. * Test serialization and deserialization of the test query.
*/ */
public void testSerialization() throws IOException { public void testSerialization() throws IOException {
for (int runs = 0; runs < NUMBER_OF_TESTQUERIES; runs++) {
QB testQuery = createTestQueryBuilder(); QB testQuery = createTestQueryBuilder();
assertSerialization(testQuery); assertSerialization(testQuery);
} }
}
/** /**
* Serialize the given query builder and asserts that both are equal * Serialize the given query builder and asserts that both are equal
@ -466,11 +473,13 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
} }
public void testEqualsAndHashcode() throws IOException { public void testEqualsAndHashcode() throws IOException {
for (int runs = 0; runs < NUMBER_OF_TESTQUERIES; runs++) {
QB firstQuery = createTestQueryBuilder(); QB firstQuery = createTestQueryBuilder();
assertFalse("query is equal to null", firstQuery.equals(null)); assertFalse("query is equal to null", firstQuery.equals(null));
assertFalse("query is equal to incompatible type", firstQuery.equals("")); assertFalse("query is equal to incompatible type", firstQuery.equals(""));
assertTrue("query is not equal to self", firstQuery.equals(firstQuery)); assertTrue("query is not equal to self", firstQuery.equals(firstQuery));
assertThat("same query's hashcode returns different values if called multiple times", firstQuery.hashCode(), equalTo(firstQuery.hashCode())); assertThat("same query's hashcode returns different values if called multiple times", firstQuery.hashCode(),
equalTo(firstQuery.hashCode()));
QB secondQuery = copyQuery(firstQuery); QB secondQuery = copyQuery(firstQuery);
assertTrue("query is not equal to self", secondQuery.equals(secondQuery)); assertTrue("query is not equal to self", secondQuery.equals(secondQuery));
@ -496,6 +505,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
assertThat("different queries should not be equal", secondQuery, not(equalTo(firstQuery))); assertThat("different queries should not be equal", secondQuery, not(equalTo(firstQuery)));
assertThat("different queries should have different hashcode", secondQuery.hashCode(), not(equalTo(firstQuery.hashCode()))); assertThat("different queries should have different hashcode", secondQuery.hashCode(), not(equalTo(firstQuery.hashCode())));
} }
}
private QueryParser<?> queryParser(String queryId) { private QueryParser<?> queryParser(String queryId) {
return queryParserService.indicesQueriesRegistry().queryParsers().get(queryId); return queryParserService.indicesQueriesRegistry().queryParsers().get(queryId);

View File

@ -35,6 +35,7 @@ import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.get.GetResult;
import org.elasticsearch.test.geo.RandomShapeGenerator; import org.elasticsearch.test.geo.RandomShapeGenerator;
import org.elasticsearch.test.geo.RandomShapeGenerator.ShapeType;
import org.junit.After; import org.junit.After;
import java.io.IOException; import java.io.IOException;
@ -55,8 +56,10 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
@Override @Override
protected GeoShapeQueryBuilder doCreateTestQueryBuilder() { protected GeoShapeQueryBuilder doCreateTestQueryBuilder() {
ShapeBuilder shape = RandomShapeGenerator.createShapeWithin(getRandom(), null); ShapeType shapeType = ShapeType.randomType(getRandom());
ShapeBuilder shape = RandomShapeGenerator.createShapeWithin(getRandom(), null, shapeType);
GeoShapeQueryBuilder builder; GeoShapeQueryBuilder builder;
clearShapeFields();
if (randomBoolean()) { if (randomBoolean()) {
try { try {
builder = new GeoShapeQueryBuilder(GEO_SHAPE_FIELD_NAME, shape); builder = new GeoShapeQueryBuilder(GEO_SHAPE_FIELD_NAME, shape);
@ -79,6 +82,11 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
} }
if (randomBoolean()) { if (randomBoolean()) {
SpatialStrategy strategy = randomFrom(SpatialStrategy.values()); SpatialStrategy strategy = randomFrom(SpatialStrategy.values());
// ShapeType.MULTILINESTRING + SpatialStrategy.TERM can lead to large queries and will slow down tests, so
// we try to avoid that combination
while (shapeType == ShapeType.MULTILINESTRING && strategy == SpatialStrategy.TERM) {
strategy = randomFrom(SpatialStrategy.values());
}
builder.strategy(strategy); builder.strategy(strategy);
if (strategy != SpatialStrategy.TERM) { if (strategy != SpatialStrategy.TERM) {
builder.relation(randomFrom(ShapeRelation.values())); builder.relation(randomFrom(ShapeRelation.values()));
@ -135,7 +143,6 @@ public class GeoShapeQueryBuilderTests extends AbstractQueryTestCase<GeoShapeQue
*/ */
@Override @Override
public void testToQuery() throws IOException { public void testToQuery() throws IOException {
//TODO figure out why this test might take up to 10 seconds once in a while
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0); assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
super.testToQuery(); super.testToQuery();
} }