Test: MockScoreScript can be cacheable. (#55499)

Backport: 0ed1eb5
This commit is contained in:
Stuart Tettemer 2020-04-20 17:09:58 -06:00 committed by GitHub
parent ff55d761f9
commit 93a2e9b0f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 22 deletions

View File

@ -94,7 +94,7 @@ public class ScriptScoreQueryBuilderTests extends AbstractQueryTestCase<ScriptSc
}
/**
* Check that this query is generally not cacheable
* Check that this query is cacheable
*/
@Override
public void testCacheability() throws IOException {
@ -105,7 +105,7 @@ public class ScriptScoreQueryBuilderTests extends AbstractQueryTestCase<ScriptSc
QueryShardContext context = createShardContext();
QueryBuilder rewriteQuery = rewriteQuery(queryBuilder, new QueryShardContext(context));
assertNotNull(rewriteQuery.toQuery(context));
assertFalse("query should not be cacheable: " + queryBuilder.toString(), context.isCacheable());
assertTrue("query should be cacheable: " + queryBuilder.toString(), context.isCacheable());
}
@Override

View File

@ -837,29 +837,28 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase<Functi
assertEquals("query should " + (isCacheable ? "" : "not") + " be cacheable: " + queryBuilder.toString(), isCacheable,
context.isCacheable());
// check the two non-cacheable cases explicitly
ScoreFunctionBuilder<?> scriptScoreFunction = new ScriptScoreFunctionBuilder(
new Script(ScriptType.INLINE, MockScriptEngine.NAME, "1", Collections.emptyMap()));
queryBuilder = new FunctionScoreQueryBuilder(new FilterFunctionBuilder[] {
new FilterFunctionBuilder(RandomQueryBuilder.createQuery(random()), scriptScoreFunction) });
context = createShardContext();
rewriteQuery = rewriteQuery(queryBuilder, new QueryShardContext(context));
assertNotNull(rewriteQuery.toQuery(context));
assertTrue("function script query should be cacheable" + queryBuilder.toString(), context.isCacheable());
RandomScoreFunctionBuilder randomScoreFunctionBuilder = new RandomScoreFunctionBuilderWithFixedSeed();
for (ScoreFunctionBuilder<?> scoreFunction : Arrays.asList(scriptScoreFunction, randomScoreFunctionBuilder)) {
FilterFunctionBuilder[] functions = new FilterFunctionBuilder[] {
new FilterFunctionBuilder(RandomQueryBuilder.createQuery(random()), scoreFunction) };
queryBuilder = new FunctionScoreQueryBuilder(functions);
context = createShardContext();
rewriteQuery = rewriteQuery(queryBuilder, new QueryShardContext(context));
assertNotNull(rewriteQuery.toQuery(context));
assertFalse("query should not be cacheable: " + queryBuilder.toString(), context.isCacheable());
}
queryBuilder = new FunctionScoreQueryBuilder(new FilterFunctionBuilder[] {
new FilterFunctionBuilder(RandomQueryBuilder.createQuery(random()), randomScoreFunctionBuilder) });
context = createShardContext();
rewriteQuery = rewriteQuery(queryBuilder, new QueryShardContext(context));
assertNotNull(rewriteQuery.toQuery(context));
assertFalse("function random query should not be cacheable: " + queryBuilder.toString(), context.isCacheable());
}
private boolean isCacheable(FunctionScoreQueryBuilder queryBuilder) {
FilterFunctionBuilder[] filterFunctionBuilders = queryBuilder.filterFunctionBuilders();
for (FilterFunctionBuilder builder : filterFunctionBuilders) {
if (builder.getScoreFunction() instanceof ScriptScoreFunctionBuilder) {
return false;
} else if (builder.getScoreFunction() instanceof RandomScoreFunctionBuilder
if (builder.getScoreFunction() instanceof RandomScoreFunctionBuilder
&& ((RandomScoreFunctionBuilder) builder.getScoreFunction()).getSeed() == null) {
return false;
}

View File

@ -227,7 +227,7 @@ public class MockScriptEngine implements ScriptEngine {
};
return context.factoryClazz.cast(factory);
} else if (context.instanceClazz.equals(ScoreScript.class)) {
ScoreScript.Factory factory = new MockScoreScript(script::apply);
ScoreScript.Factory factory = new MockScoreScript(script);
return context.factoryClazz.cast(factory);
} else if (context.instanceClazz.equals(ScriptedMetricAggContexts.InitScript.class)) {
ScriptedMetricAggContexts.InitScript.Factory factory = new MockMetricAggInitScriptFactory(script);
@ -547,9 +547,9 @@ public class MockScriptEngine implements ScriptEngine {
public class MockScoreScript implements ScoreScript.Factory {
private final Function<Map<String, Object>, Object> script;
private final MockDeterministicScript script;
public MockScoreScript(Function<Map<String, Object>, Object> script) {
public MockScoreScript(MockDeterministicScript script) {
this.script = script;
}
@ -583,6 +583,11 @@ public class MockScriptEngine implements ScriptEngine {
}
};
}
@Override
public boolean isResultDeterministic() {
return script.isResultDeterministic();
}
}
class MockAggregationScript implements AggregationScript.Factory {

View File

@ -6,6 +6,7 @@
package org.elasticsearch.xpack.core.monitoring.test;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.script.MockDeterministicScript;
import org.elasticsearch.script.MockScriptEngine;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.ScoreScript;
@ -44,7 +45,7 @@ public class MockPainlessScriptEngine extends MockScriptEngine {
@Override
public <T> T compile(String name, String script, ScriptContext<T> context, Map<String, String> options) {
if (context.instanceClazz.equals(ScoreScript.class)) {
return context.factoryClazz.cast(new MockScoreScript(p -> 0.0));
return context.factoryClazz.cast(new MockScoreScript(MockDeterministicScript.asDeterministic(p -> 0.0)));
}
throw new IllegalArgumentException("mock painless does not know how to handle context [" + context.name + "]");
}

View File

@ -23,6 +23,7 @@ import org.elasticsearch.persistent.PersistentTaskParams;
import org.elasticsearch.persistent.PersistentTaskState;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.IngestScript;
import org.elasticsearch.script.MockDeterministicScript;
import org.elasticsearch.script.MockScriptEngine;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.ScoreScript;
@ -283,7 +284,7 @@ abstract class MlNativeIntegTestCase extends ESIntegTestCase {
@Override
public <T> T compile(String name, String script, ScriptContext<T> context, Map<String, String> options) {
if (context.instanceClazz.equals(ScoreScript.class)) {
return context.factoryClazz.cast(new MockScoreScript(p -> 0.0));
return context.factoryClazz.cast(new MockScoreScript(MockDeterministicScript.asDeterministic(p -> 0.0)));
}
if (context.name.equals("ingest")) {
IngestScript.Factory factory = vars -> new IngestScript(vars) {