summaryrefslogtreecommitdiff
path: root/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java')
-rw-r--r--core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java218
1 files changed, 197 insertions, 21 deletions
diff --git a/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java b/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java
index 2aa55f8b62..01f7e33244 100644
--- a/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java
+++ b/core/src/test/java/org/elasticsearch/search/rescore/QueryRescoreBuilderTests.java
@@ -19,15 +19,37 @@
package org.elasticsearch.search.rescore;
+import org.elasticsearch.ElasticsearchParseException;
+import org.elasticsearch.Version;
+import org.elasticsearch.cluster.metadata.IndexMetaData;
+import org.elasticsearch.common.ParseFieldMatcher;
+import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.common.xcontent.ToXContent;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentHelper;
+import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.index.IndexSettings;
+import org.elasticsearch.index.mapper.ContentPath;
+import org.elasticsearch.index.mapper.MappedFieldType;
+import org.elasticsearch.index.mapper.Mapper;
+import org.elasticsearch.index.mapper.MapperBuilders;
+import org.elasticsearch.index.mapper.core.StringFieldMapper;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.search.rescore.RescoreBuilder.QueryRescorer;
-import org.elasticsearch.search.rescore.RescoreBuilder.Rescorer;
+import org.elasticsearch.index.query.QueryParseContext;
+import org.elasticsearch.index.query.QueryShardContext;
+import org.elasticsearch.indices.query.IndicesQueriesRegistry;
+import org.elasticsearch.search.SearchModule;
+import org.elasticsearch.search.rescore.QueryRescorer.QueryRescoreContext;
import org.elasticsearch.test.ESTestCase;
+import org.elasticsearch.test.IndexSettingsModule;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@@ -40,6 +62,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
private static final int NUMBER_OF_TESTBUILDERS = 20;
private static NamedWriteableRegistry namedWriteableRegistry;
+ private static IndicesQueriesRegistry indicesQueriesRegistry;
/**
* setup for the whole base test class
@@ -47,13 +70,14 @@ public class QueryRescoreBuilderTests extends ESTestCase {
@BeforeClass
public static void init() {
namedWriteableRegistry = new NamedWriteableRegistry();
- namedWriteableRegistry.registerPrototype(Rescorer.class, org.elasticsearch.search.rescore.RescoreBuilder.QueryRescorer.PROTOTYPE);
- namedWriteableRegistry.registerPrototype(QueryBuilder.class, new MatchAllQueryBuilder());
+ namedWriteableRegistry.registerPrototype(RescoreBuilder.class, QueryRescorerBuilder.PROTOTYPE);
+ indicesQueriesRegistry = new SearchModule(Settings.EMPTY, namedWriteableRegistry).buildQueryParserRegistry();
}
@AfterClass
public static void afterClass() throws Exception {
namedWriteableRegistry = null;
+ indicesQueriesRegistry = null;
}
/**
@@ -61,8 +85,8 @@ public class QueryRescoreBuilderTests extends ESTestCase {
*/
public void testSerialization() throws IOException {
for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
- RescoreBuilder original = randomRescoreBuilder();
- RescoreBuilder deserialized = serializedCopy(original);
+ RescoreBuilder<?> original = randomRescoreBuilder();
+ RescoreBuilder<?> deserialized = serializedCopy(original);
assertEquals(deserialized, original);
assertEquals(deserialized.hashCode(), original.hashCode());
assertNotSame(deserialized, original);
@@ -74,7 +98,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
*/
public void testEqualsAndHashcode() throws IOException {
for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
- RescoreBuilder firstBuilder = randomRescoreBuilder();
+ RescoreBuilder<?> firstBuilder = randomRescoreBuilder();
assertFalse("rescore builder is equal to null", firstBuilder.equals(null));
assertFalse("rescore builder is equal to incompatible type", firstBuilder.equals(""));
assertTrue("rescore builder is not equal to self", firstBuilder.equals(firstBuilder));
@@ -82,13 +106,13 @@ public class QueryRescoreBuilderTests extends ESTestCase {
equalTo(firstBuilder.hashCode()));
assertThat("different rescore builder should not be equal", mutate(firstBuilder), not(equalTo(firstBuilder)));
- RescoreBuilder secondBuilder = serializedCopy(firstBuilder);
+ RescoreBuilder<?> secondBuilder = serializedCopy(firstBuilder);
assertTrue("rescore builder is not equal to self", secondBuilder.equals(secondBuilder));
assertTrue("rescore builder is not equal to its copy", firstBuilder.equals(secondBuilder));
assertTrue("equals is not symmetric", secondBuilder.equals(firstBuilder));
assertThat("rescore builder copy's hashcode is different from original hashcode", secondBuilder.hashCode(), equalTo(firstBuilder.hashCode()));
- RescoreBuilder thirdBuilder = serializedCopy(secondBuilder);
+ RescoreBuilder<?> thirdBuilder = serializedCopy(secondBuilder);
assertTrue("rescore builder is not equal to self", thirdBuilder.equals(thirdBuilder));
assertTrue("rescore builder is not equal to its copy", secondBuilder.equals(thirdBuilder));
assertThat("rescore builder copy's hashcode is different from original hashcode", secondBuilder.hashCode(), equalTo(thirdBuilder.hashCode()));
@@ -99,8 +123,161 @@ public class QueryRescoreBuilderTests extends ESTestCase {
}
}
- private RescoreBuilder mutate(RescoreBuilder original) throws IOException {
- RescoreBuilder mutation = serializedCopy(original);
+ /**
+ * creates random rescorer, renders it to xContent and back to new instance that should be equal to original
+ */
+ public void testFromXContent() throws IOException {
+ QueryParseContext context = new QueryParseContext(indicesQueriesRegistry);
+ context.parseFieldMatcher(new ParseFieldMatcher(Settings.EMPTY));
+ for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
+ RescoreBuilder<?> rescoreBuilder = randomRescoreBuilder();
+
+ XContentParser parser = createParser(rescoreBuilder);
+ context.reset(parser);
+ parser.nextToken();
+ RescoreBuilder<?> secondRescoreBuilder = RescoreBuilder.parseFromXContent(context);
+ assertNotSame(rescoreBuilder, secondRescoreBuilder);
+ assertEquals(rescoreBuilder, secondRescoreBuilder);
+ assertEquals(rescoreBuilder.hashCode(), secondRescoreBuilder.hashCode());
+ }
+ }
+
+ private static XContentParser createParser(RescoreBuilder<?> rescoreBuilder) throws IOException {
+ XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
+ if (randomBoolean()) {
+ builder.prettyPrint();
+ }
+ rescoreBuilder.toXContent(builder, ToXContent.EMPTY_PARAMS);
+ return XContentHelper.createParser(builder.bytes());
+ }
+
+ /**
+ * test that build() outputs a {@link RescoreSearchContext} that is similar to the one
+ * we would get when parsing the xContent the test rescore builder is rendering out
+ */
+ public void testBuildRescoreSearchContext() throws ElasticsearchParseException, IOException {
+ Settings indexSettings = Settings.settingsBuilder()
+ .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build();
+ IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(randomAsciiOfLengthBetween(1, 10), indexSettings);
+ // shard context will only need indicesQueriesRegistry for building Query objects nested in query rescorer
+ QueryShardContext mockShardContext = new QueryShardContext(idxSettings, null, null, null, null, null, null, indicesQueriesRegistry) {
+ @Override
+ public MappedFieldType fieldMapper(String name) {
+ StringFieldMapper.Builder builder = MapperBuilders.stringField(name);
+ return builder.build(new Mapper.BuilderContext(idxSettings.getSettings(), new ContentPath(1))).fieldType();
+ }
+ };
+
+ for (int runs = 0; runs < NUMBER_OF_TESTBUILDERS; runs++) {
+ RescoreBuilder<?> rescoreBuilder = randomRescoreBuilder();
+ QueryRescoreContext rescoreContext = (QueryRescoreContext) rescoreBuilder.build(mockShardContext);
+ XContentParser parser = createParser(rescoreBuilder);
+
+ QueryRescoreContext parsedRescoreContext = (QueryRescoreContext) new RescoreParseElement().parseSingleRescoreContext(parser, mockShardContext);
+ assertNotSame(rescoreContext, parsedRescoreContext);
+ assertEquals(rescoreContext.window(), parsedRescoreContext.window());
+ assertEquals(rescoreContext.query(), parsedRescoreContext.query());
+ assertEquals(rescoreContext.queryWeight(), parsedRescoreContext.queryWeight(), Float.MIN_VALUE);
+ assertEquals(rescoreContext.rescoreQueryWeight(), parsedRescoreContext.rescoreQueryWeight(), Float.MIN_VALUE);
+ assertEquals(rescoreContext.scoreMode(), parsedRescoreContext.scoreMode());
+ }
+ }
+
+ /**
+ * test parsing exceptions for incorrect rescorer syntax
+ */
+ public void testUnknownFieldsExpection() throws IOException {
+ QueryParseContext context = new QueryParseContext(indicesQueriesRegistry);
+ context.parseFieldMatcher(new ParseFieldMatcher(Settings.EMPTY));
+
+ String rescoreElement = "{\n" +
+ " \"window_size\" : 20,\n" +
+ " \"bad_rescorer_name\" : { }\n" +
+ "}\n";
+ prepareContext(context, rescoreElement);
+ try {
+ RescoreBuilder.parseFromXContent(context);
+ fail("expected a parsing exception");
+ } catch (ParsingException e) {
+ assertEquals("rescore doesn't support rescorer with name [bad_rescorer_name]", e.getMessage());
+ }
+
+ rescoreElement = "{\n" +
+ " \"bad_fieldName\" : 20\n" +
+ "}\n";
+ prepareContext(context, rescoreElement);
+ try {
+ RescoreBuilder.parseFromXContent(context);
+ fail("expected a parsing exception");
+ } catch (ParsingException e) {
+ assertEquals("rescore doesn't support [bad_fieldName]", e.getMessage());
+ }
+
+ rescoreElement = "{\n" +
+ " \"window_size\" : 20,\n" +
+ " \"query\" : [ ]\n" +
+ "}\n";
+ prepareContext(context, rescoreElement);
+ try {
+ RescoreBuilder.parseFromXContent(context);
+ fail("expected a parsing exception");
+ } catch (ParsingException e) {
+ assertEquals("unexpected token [START_ARRAY] after [query]", e.getMessage());
+ }
+
+ rescoreElement = "{ }";
+ prepareContext(context, rescoreElement);
+ try {
+ RescoreBuilder.parseFromXContent(context);
+ fail("expected a parsing exception");
+ } catch (ParsingException e) {
+ assertEquals("missing rescore type", e.getMessage());
+ }
+
+ rescoreElement = "{\n" +
+ " \"window_size\" : 20,\n" +
+ " \"query\" : { \"bad_fieldname\" : 1.0 } \n" +
+ "}\n";
+ prepareContext(context, rescoreElement);
+ try {
+ RescoreBuilder.parseFromXContent(context);
+ fail("expected a parsing exception");
+ } catch (IllegalArgumentException e) {
+ assertEquals("[query] unknown field [bad_fieldname], parser not found", e.getMessage());
+ }
+
+ rescoreElement = "{\n" +
+ " \"window_size\" : 20,\n" +
+ " \"query\" : { \"rescore_query\" : { \"unknown_queryname\" : { } } } \n" +
+ "}\n";
+ prepareContext(context, rescoreElement);
+ try {
+ RescoreBuilder.parseFromXContent(context);
+ fail("expected a parsing exception");
+ } catch (ParsingException e) {
+ assertEquals("[query] failed to parse field [rescore_query]", e.getMessage());
+ }
+
+ rescoreElement = "{\n" +
+ " \"window_size\" : 20,\n" +
+ " \"query\" : { \"rescore_query\" : { \"match_all\" : { } } } \n"
+ + "}\n";
+ prepareContext(context, rescoreElement);
+ RescoreBuilder.parseFromXContent(context);
+ }
+
+ /**
+ * create a new parser from the rescorer string representation and reset context with it
+ */
+ private static void prepareContext(QueryParseContext context, String rescoreElement) throws IOException {
+ XContentParser parser = XContentFactory.xContent(rescoreElement).createParser(rescoreElement);
+ context.reset(parser);
+ // move to first token, this is where the internal fromXContent
+ assertTrue(parser.nextToken() == XContentParser.Token.START_OBJECT);
+ }
+
+ private static RescoreBuilder<?> mutate(RescoreBuilder<?> original) throws IOException {
+ RescoreBuilder<?> mutation = serializedCopy(original);
if (randomBoolean()) {
Integer windowSize = original.windowSize();
if (windowSize != null) {
@@ -109,7 +286,7 @@ public class QueryRescoreBuilderTests extends ESTestCase {
mutation.windowSize(randomIntBetween(0, 100));
}
} else {
- QueryRescorer queryRescorer = (QueryRescorer) mutation.rescorer();
+ QueryRescorerBuilder queryRescorer = (QueryRescorerBuilder) mutation;
switch (randomIntBetween(0, 3)) {
case 0:
queryRescorer.setQueryWeight(queryRescorer.getQueryWeight() + 0.1f);
@@ -138,10 +315,10 @@ public class QueryRescoreBuilderTests extends ESTestCase {
/**
* create random shape that is put under test
*/
- private static RescoreBuilder randomRescoreBuilder() {
+ public static org.elasticsearch.search.rescore.QueryRescorerBuilder randomRescoreBuilder() {
QueryBuilder<MatchAllQueryBuilder> queryBuilder = new MatchAllQueryBuilder().boost(randomFloat()).queryName(randomAsciiOfLength(20));
- org.elasticsearch.search.rescore.RescoreBuilder.QueryRescorer rescorer = new
- org.elasticsearch.search.rescore.RescoreBuilder.QueryRescorer(queryBuilder);
+ org.elasticsearch.search.rescore.QueryRescorerBuilder rescorer = new
+ org.elasticsearch.search.rescore.QueryRescorerBuilder(queryBuilder);
if (randomBoolean()) {
rescorer.setQueryWeight(randomFloat());
}
@@ -151,18 +328,17 @@ public class QueryRescoreBuilderTests extends ESTestCase {
if (randomBoolean()) {
rescorer.setScoreMode(randomFrom(QueryRescoreMode.values()));
}
- RescoreBuilder builder = new RescoreBuilder(rescorer);
if (randomBoolean()) {
- builder.windowSize(randomIntBetween(0, 100));
+ rescorer.windowSize(randomIntBetween(0, 100));
}
- return builder;
+ return rescorer;
}
- private static RescoreBuilder serializedCopy(RescoreBuilder original) throws IOException {
+ private static RescoreBuilder<?> serializedCopy(RescoreBuilder<?> original) throws IOException {
try (BytesStreamOutput output = new BytesStreamOutput()) {
- original.writeTo(output);
+ output.writeRescorer(original);
try (StreamInput in = new NamedWriteableAwareStreamInput(StreamInput.wrap(output.bytes()), namedWriteableRegistry)) {
- return RescoreBuilder.PROTOYPE.readFrom(in);
+ return in.readRescorer();
}
}
}