Browse Source

Test: Convert test script engine impls to use MockScriptEngine (#24854)

This commit cleans up tests which currently use custom script engine
implementations, converting them to use a MockScriptEngine with script
functions provided by the tests. It also creates a common set of metric
scripts which were copied across a couple metric agg tests.
Ryan Ernst 8 years ago
parent
commit
bf49d37ab3

+ 13 - 49
core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java

@@ -23,6 +23,7 @@ import java.nio.file.Path;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.function.Function;
 
 import org.elasticsearch.ResourceNotFoundException;
 import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
@@ -46,7 +47,6 @@ import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.sameInstance;
 
-//TODO: this needs to be a base test class, and all scripting engines extend it
 public class ScriptServiceTests extends ESTestCase {
 
     private ScriptEngine scriptEngine;
@@ -63,15 +63,18 @@ public class ScriptServiceTests extends ESTestCase {
                 .put(Environment.PATH_CONF_SETTING.getKey(), genericConfigFolder)
                 .put(ScriptService.SCRIPT_MAX_COMPILATIONS_PER_MINUTE.getKey(), 10000)
                 .build();
-        scriptEngine = new TestEngine();
-        TestEngine defaultScriptServiceEngine = new TestEngine(Script.DEFAULT_SCRIPT_LANG) {};
-        //randomly register custom script contexts
-        int randomInt = randomIntBetween(0, 3);
+        Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
+        for (int i = 0; i < 20; ++i) {
+            scripts.put(i + "+" + i, p -> null); // only care about compilation, not execution
+        }
+        scripts.put("script", p -> null);
+        scriptEngine = new MockScriptEngine(Script.DEFAULT_SCRIPT_LANG, scripts);
+
         //prevent duplicates using map
         contexts = new HashMap<>(ScriptContext.BUILTINS);
         engines = new HashMap<>();
         engines.put(scriptEngine.getType(), scriptEngine);
-        engines.put(defaultScriptServiceEngine.getType(), defaultScriptServiceEngine);
+        engines.put("test", new MockScriptEngine("test", scripts));
         logger.info("--> setup script service");
     }
 
@@ -81,7 +84,7 @@ public class ScriptServiceTests extends ESTestCase {
             @Override
             StoredScriptSource getScriptFromClusterState(String id, String lang) {
                 //mock the script that gets retrieved from an index
-                return new StoredScriptSource(lang, "100", Collections.emptyMap());
+                return new StoredScriptSource(lang, "1+1", Collections.emptyMap());
             }
         };
     }
@@ -215,10 +218,10 @@ public class ScriptServiceTests extends ESTestCase {
 
     public void testMultipleCompilationsCountedInCompilationStats() throws IOException {
         buildScriptService(Settings.EMPTY);
-        int numberOfCompilations = randomIntBetween(1, 1024);
+        int numberOfCompilations = randomIntBetween(1, 20);
         for (int i = 0; i < numberOfCompilations; i++) {
             scriptService
-                    .compile(new Script(ScriptType.INLINE, "test", i + " + " + i, Collections.emptyMap()), randomFrom(contexts.values()));
+                    .compile(new Script(ScriptType.INLINE, "test", i + "+" + i, Collections.emptyMap()), randomFrom(contexts.values()));
         }
         assertEquals(numberOfCompilations, scriptService.stats().getCompilations());
     }
@@ -253,7 +256,7 @@ public class ScriptServiceTests extends ESTestCase {
         Settings.Builder builder = Settings.builder();
         buildScriptService(builder.build());
         CompiledScript script = scriptService.compile(
-            new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, "1 + 1", Collections.emptyMap()), randomFrom(contexts.values()));
+            new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, "1+1", Collections.emptyMap()), randomFrom(contexts.values()));
         assertEquals(script.lang(), Script.DEFAULT_SCRIPT_LANG);
     }
 
@@ -314,43 +317,4 @@ public class ScriptServiceTests extends ESTestCase {
         );
     }
 
-    public static class TestEngine implements ScriptEngine {
-
-        public static final String NAME = "test";
-
-        private final String name;
-
-        public TestEngine() {
-            this(NAME);
-        }
-
-        public TestEngine(String name) {
-            this.name = name;
-        }
-
-        @Override
-        public String getType() {
-            return name;
-        }
-
-        @Override
-        public Object compile(String scriptName, String scriptText, Map<String, String> params) {
-            return "compiled_" + scriptText;
-        }
-
-        @Override
-        public ExecutableScript executable(final CompiledScript compiledScript, @Nullable Map<String, Object> vars) {
-            return null;
-        }
-
-        @Override
-        public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) {
-            return null;
-        }
-
-        @Override
-        public void close() {
-
-        }
-    }
 }

+ 28 - 232
core/src/test/java/org/elasticsearch/search/aggregations/metrics/AvgIT.java

@@ -18,37 +18,24 @@
  */
 package org.elasticsearch.search.aggregations.metrics;
 
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.Scorer;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.plugins.Plugin;
-import org.elasticsearch.plugins.ScriptPlugin;
-import org.elasticsearch.script.CompiledScript;
-import org.elasticsearch.script.ExecutableScript;
-import org.elasticsearch.script.LeafSearchScript;
 import org.elasticsearch.script.Script;
-import org.elasticsearch.script.ScriptEngine;
 import org.elasticsearch.script.ScriptType;
-import org.elasticsearch.script.SearchScript;
+import org.elasticsearch.search.aggregations.BucketOrder;
 import org.elasticsearch.search.aggregations.InternalAggregation;
 import org.elasticsearch.search.aggregations.bucket.filter.Filter;
 import org.elasticsearch.search.aggregations.bucket.global.Global;
 import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
 import org.elasticsearch.search.aggregations.bucket.terms.Terms;
 import org.elasticsearch.search.aggregations.metrics.avg.Avg;
-import org.elasticsearch.search.aggregations.BucketOrder;
-import org.elasticsearch.search.lookup.LeafSearchLookup;
-import org.elasticsearch.search.lookup.SearchLookup;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
 import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
 import static org.elasticsearch.index.query.QueryBuilders.termQuery;
@@ -57,6 +44,11 @@ import static org.elasticsearch.search.aggregations.AggregationBuilders.filter;
 import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
 import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
 import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.METRIC_SCRIPT_ENGINE;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.VALUE_FIELD_SCRIPT;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.SUM_FIELD_PARAMS_SCRIPT;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.SUM_VALUES_FIELD_SCRIPT;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.VALUE_SCRIPT;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
@@ -68,9 +60,7 @@ public class AvgIT extends AbstractNumericTestCase {
 
     @Override
     protected Collection<Class<? extends Plugin>> nodePlugins() {
-        return Arrays.asList(
-                ExtractFieldScriptPlugin.class,
-                FieldValueScriptPlugin.class);
+        return Collections.singleton(MetricAggScriptPlugin.class);
     }
 
     @Override
@@ -168,7 +158,7 @@ public class AvgIT extends AbstractNumericTestCase {
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(avg("avg").field("value")
-                        .script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", Collections.emptyMap())))
+                        .script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, Collections.emptyMap())))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -185,7 +175,7 @@ public class AvgIT extends AbstractNumericTestCase {
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(avg("avg").field("value")
-                        .script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", params)))
+                        .script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, params)))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -229,7 +219,7 @@ public class AvgIT extends AbstractNumericTestCase {
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(avg("avg").field("values")
-                        .script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", Collections.emptyMap())))
+                        .script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, Collections.emptyMap())))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -246,7 +236,7 @@ public class AvgIT extends AbstractNumericTestCase {
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(avg("avg").field("values")
-                        .script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", params)))
+                        .script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, params)))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -262,7 +252,7 @@ public class AvgIT extends AbstractNumericTestCase {
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(avg("avg")
-                        .script(new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "value", Collections.emptyMap())))
+                        .script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_FIELD_SCRIPT, Collections.emptyMap())))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -275,11 +265,13 @@ public class AvgIT extends AbstractNumericTestCase {
 
     @Override
     public void testScriptSingleValuedWithParams() throws Exception {
-        Map<String, Object> params = Collections.singletonMap("inc", 1);
+        Map<String, Object> params = new HashMap<>();
+        params.put("inc", 1);
+        params.put("field", "value");
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(avg("avg")
-                        .script(new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "value", params)))
+                        .script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_FIELD_PARAMS_SCRIPT, params)))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -295,7 +287,7 @@ public class AvgIT extends AbstractNumericTestCase {
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(avg("avg")
-                        .script(new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "values", Collections.emptyMap())))
+                        .script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_VALUES_FIELD_SCRIPT, Collections.emptyMap())))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -308,11 +300,13 @@ public class AvgIT extends AbstractNumericTestCase {
 
     @Override
     public void testScriptMultiValuedWithParams() throws Exception {
-        Map<String, Object> params = Collections.singletonMap("inc", 1);
+        Map<String, Object> params = new HashMap<>();
+        params.put("inc", 1);
+        params.put("field", "values");
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(avg("avg")
-                        .script(new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "values", params)))
+                        .script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_FIELD_PARAMS_SCRIPT, params)))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -373,7 +367,7 @@ public class AvgIT extends AbstractNumericTestCase {
         // Test that a request using a script does not get cached
         SearchResponse r = client().prepareSearch("cache_test_idx").setSize(0)
                 .addAggregation(avg("foo").field("d").script(
-                    new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", Collections.emptyMap()))).get();
+                    new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_FIELD_SCRIPT, Collections.emptyMap()))).get();
         assertSearchResponse(r);
 
         assertThat(client().admin().indices().prepareStats("cache_test_idx").setRequestCache(true).get().getTotal().getRequestCache()
@@ -391,202 +385,4 @@ public class AvgIT extends AbstractNumericTestCase {
         assertThat(client().admin().indices().prepareStats("cache_test_idx").setRequestCache(true).get().getTotal().getRequestCache()
                 .getMissCount(), equalTo(1L));
     }
-
-    /**
-     * Mock plugin for the {@link ExtractFieldScriptEngine}
-     */
-    public static class ExtractFieldScriptPlugin extends Plugin implements ScriptPlugin {
-        @Override
-        public ScriptEngine getScriptEngine(Settings settings) {
-            return new ExtractFieldScriptEngine();
-        }
-    }
-
-    /**
-     * This mock script returns the field that is specified by name in the script body
-     */
-    public static class ExtractFieldScriptEngine implements ScriptEngine {
-
-        public static final String NAME = "extract_field";
-
-        @Override
-        public void close() throws IOException {
-        }
-
-        @Override
-        public String getType() {
-            return NAME;
-        }
-
-        @Override
-        public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
-            return scriptSource;
-        }
-
-        @Override
-        public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
-            throw new UnsupportedOperationException();
-        }
-        @Override
-        public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
-            final long inc;
-            if (vars == null || vars.containsKey("inc") == false) {
-                inc = 0;
-            } else {
-                inc = ((Number) vars.get("inc")).longValue();
-            }
-            return new SearchScript() {
-
-                @Override
-                public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
-
-                    final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
-
-                    return new LeafSearchScript() {
-                        @Override
-                        public void setNextVar(String name, Object value) {
-                        }
-
-                        @Override
-                        public Object run() {
-                            String fieldName = (String) compiledScript.compiled();
-                            List<Long> values = new ArrayList<>();
-                            for (Object v : (List<?>) leafLookup.doc().get(fieldName)) {
-                                values.add(((Number) v).longValue() + inc);
-                            }
-                            return values;
-                        }
-
-                        @Override
-                        public void setScorer(Scorer scorer) {
-                        }
-
-                        @Override
-                        public void setSource(Map<String, Object> source) {
-                        }
-
-                        @Override
-                        public void setDocument(int doc) {
-                            if (leafLookup != null) {
-                                leafLookup.setDocument(doc);
-                            }
-                        }
-
-                        @Override
-                        public long runAsLong() {
-                            throw new UnsupportedOperationException();
-                        }
-
-                        @Override
-                        public double runAsDouble() {
-                            throw new UnsupportedOperationException();
-                        }
-                    };
-                }
-
-                @Override
-                public boolean needsScores() {
-                    return false;
-                }
-            };
-        }
-    }
-
-    /**
-     * Mock plugin for the {@link FieldValueScriptEngine}
-     */
-    public static class FieldValueScriptPlugin extends Plugin implements ScriptPlugin {
-        @Override
-        public ScriptEngine getScriptEngine(Settings settings) {
-            return new FieldValueScriptEngine();
-        }
-    }
-
-    /**
-     * This mock script returns the field value and adds one month to the returned date
-     */
-    public static class FieldValueScriptEngine implements ScriptEngine {
-
-        public static final String NAME = "field_value";
-
-        @Override
-        public void close() throws IOException {
-        }
-
-        @Override
-        public String getType() {
-            return NAME;
-        }
-
-        @Override
-        public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
-            return scriptSource;
-        }
-
-        @Override
-        public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
-            throw new UnsupportedOperationException();
-        }
-        @Override
-        public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
-            final long inc;
-            if (vars == null || vars.containsKey("inc") == false) {
-                inc = 0;
-            } else {
-                inc = ((Number) vars.get("inc")).longValue();
-            }
-            return new SearchScript() {
-
-                private Map<String, Object> vars = new HashMap<>(2);
-
-                @Override
-                public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
-
-                    final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
-
-                    return new LeafSearchScript() {
-                        @Override
-                        public void setNextVar(String name, Object value) {
-                            vars.put(name, value);
-                        }
-
-                        @Override
-                        public Object run() {
-                            throw new UnsupportedOperationException();
-                        }
-
-                        @Override
-                        public void setScorer(Scorer scorer) {
-                        }
-
-                        @Override
-                        public void setSource(Map<String, Object> source) {
-                        }
-
-                        @Override
-                        public void setDocument(int doc) {
-                            if (leafLookup != null) {
-                                leafLookup.setDocument(doc);
-                            }
-                        }
-
-                        @Override
-                        public long runAsLong() {
-                            return ((Number) vars.get("_value")).longValue() + inc;
-                        }
-
-                        @Override
-                        public double runAsDouble() {
-                            return ((Number) vars.get("_value")).doubleValue() + inc;
-                        }
-                    };
-                }
-
-                @Override
-                public boolean needsScores() {
-                    return false;
-                }
-            };
-        }
-    }
 }

+ 91 - 0
core/src/test/java/org/elasticsearch/search/aggregations/metrics/MetricAggScriptPlugin.java

@@ -0,0 +1,91 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.search.aggregations.metrics;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import org.elasticsearch.script.MockScriptPlugin;
+import org.elasticsearch.search.lookup.LeafDocLookup;
+
+/**
+ * Provides a number of dummy scripts for tests.
+ *
+ * Each script provided allows for an {@code inc} parameter which will
+ * be added to each value read from a document.
+ */
+public class MetricAggScriptPlugin extends MockScriptPlugin {
+
+    /** The name of the script engine type this plugin provides. */
+    public static final String METRIC_SCRIPT_ENGINE = "metric_scripts";
+
+    /** Script to take a field name in params and sum the values of the field. */
+    public static final String SUM_FIELD_PARAMS_SCRIPT = "sum_field_params";
+
+    /** Script to sum the values of a field named {@code values}. */
+    public static final String SUM_VALUES_FIELD_SCRIPT = "sum_values_field";
+
+    /** Script to return the value of a field named {@code value}. */
+    public static final String VALUE_FIELD_SCRIPT = "value_field";
+
+    /** Script to return the {@code _value} provided by aggs framework. */
+    public static final String VALUE_SCRIPT = "_value";
+
+    @Override
+    public String pluginScriptLang() {
+        return METRIC_SCRIPT_ENGINE;
+    }
+
+    @Override
+    protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
+        Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
+        Function<Map<String, Object>, Integer> getInc = vars -> {
+            if (vars == null || vars.containsKey("inc") == false) {
+                return 0;
+            } else {
+                return ((Number) vars.get("inc")).intValue();
+            }
+        };
+        BiFunction<Map<String, Object>, String, Object> sum = (vars, fieldname) -> {
+            int inc = getInc.apply(vars);
+            LeafDocLookup docLookup = (LeafDocLookup) vars.get("doc");
+            List<Long> values = new ArrayList<>();
+            for (Object v : docLookup.get(fieldname)) {
+                values.add(((Number) v).longValue() + inc);
+            }
+            return values;
+        };
+        scripts.put(SUM_FIELD_PARAMS_SCRIPT, vars -> {
+            String fieldname = (String) vars.get("field");
+            return sum.apply(vars, fieldname);
+        });
+        scripts.put(SUM_VALUES_FIELD_SCRIPT, vars -> sum.apply(vars, "values"));
+        scripts.put(VALUE_FIELD_SCRIPT, vars -> sum.apply(vars, "value"));
+        scripts.put(VALUE_SCRIPT, vars -> {
+            int inc = getInc.apply(vars);
+            return ((Number) vars.get("_value")).doubleValue() + inc;
+        });
+        return scripts;
+    }
+}

+ 22 - 233
core/src/test/java/org/elasticsearch/search/aggregations/metrics/SumIT.java

@@ -18,37 +18,24 @@
  */
 package org.elasticsearch.search.aggregations.metrics;
 
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.Scorer;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.plugins.Plugin;
-import org.elasticsearch.plugins.ScriptPlugin;
-import org.elasticsearch.script.CompiledScript;
-import org.elasticsearch.script.ExecutableScript;
-import org.elasticsearch.script.LeafSearchScript;
 import org.elasticsearch.script.Script;
-import org.elasticsearch.script.ScriptEngine;
 import org.elasticsearch.script.ScriptType;
-import org.elasticsearch.script.SearchScript;
+import org.elasticsearch.search.aggregations.BucketOrder;
 import org.elasticsearch.search.aggregations.InternalAggregation;
 import org.elasticsearch.search.aggregations.bucket.filter.Filter;
 import org.elasticsearch.search.aggregations.bucket.global.Global;
 import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
 import org.elasticsearch.search.aggregations.bucket.terms.Terms;
 import org.elasticsearch.search.aggregations.metrics.sum.Sum;
-import org.elasticsearch.search.aggregations.BucketOrder;
-import org.elasticsearch.search.lookup.LeafSearchLookup;
-import org.elasticsearch.search.lookup.SearchLookup;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
 import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
 import static org.elasticsearch.index.query.QueryBuilders.termQuery;
@@ -57,6 +44,10 @@ import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
 import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
 import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
 import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.METRIC_SCRIPT_ENGINE;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.SUM_VALUES_FIELD_SCRIPT;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.VALUE_FIELD_SCRIPT;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.VALUE_SCRIPT;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
@@ -67,7 +58,7 @@ public class SumIT extends AbstractNumericTestCase {
 
     @Override
     protected Collection<Class<? extends Plugin>> nodePlugins() {
-        return Arrays.asList(ExtractFieldScriptPlugin.class, FieldValueScriptPlugin.class);
+        return Collections.singleton(MetricAggScriptPlugin.class);
     }
 
     @Override
@@ -178,7 +169,7 @@ public class SumIT extends AbstractNumericTestCase {
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(sum("sum").field("value").script(
-                    new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", Collections.emptyMap())))
+                    new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, Collections.emptyMap())))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -195,7 +186,7 @@ public class SumIT extends AbstractNumericTestCase {
         params.put("increment", 1);
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
-                .addAggregation(sum("sum").field("value").script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", params)))
+                .addAggregation(sum("sum").field("value").script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, params)))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -211,7 +202,7 @@ public class SumIT extends AbstractNumericTestCase {
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(sum("sum").script(
-                    new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "value", Collections.emptyMap())))
+                    new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_FIELD_SCRIPT, Collections.singletonMap("field", "value"))))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -228,7 +219,7 @@ public class SumIT extends AbstractNumericTestCase {
         params.put("inc", 1);
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
-                .addAggregation(sum("sum").script(new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "value", params)))
+                .addAggregation(sum("sum").script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_FIELD_SCRIPT, params)))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -244,7 +235,7 @@ public class SumIT extends AbstractNumericTestCase {
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(sum("sum").script(
-                    new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "values", Collections.emptyMap())))
+                    new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_VALUES_FIELD_SCRIPT, Collections.emptyMap())))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -262,7 +253,7 @@ public class SumIT extends AbstractNumericTestCase {
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(
-                        sum("sum").script(new Script(ScriptType.INLINE, ExtractFieldScriptEngine.NAME, "values", params)))
+                        sum("sum").script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_VALUES_FIELD_SCRIPT, params)))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -295,7 +286,7 @@ public class SumIT extends AbstractNumericTestCase {
         SearchResponse searchResponse = client().prepareSearch("idx")
                 .setQuery(matchAllQuery())
                 .addAggregation(sum("sum").field("values").script(
-                    new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", Collections.emptyMap())))
+                    new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, Collections.emptyMap())))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -311,7 +302,8 @@ public class SumIT extends AbstractNumericTestCase {
         Map<String, Object> params = new HashMap<>();
         params.put("increment", 1);
         SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
-                .addAggregation(sum("sum").field("values").script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", params)))
+                .addAggregation(sum("sum").field("values")
+                    .script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, params)))
                 .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
@@ -372,7 +364,7 @@ public class SumIT extends AbstractNumericTestCase {
         // Test that a request using a script does not get cached
         SearchResponse r = client().prepareSearch("cache_test_idx").setSize(0)
                 .addAggregation(sum("foo").field("d").script(
-                    new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", Collections.emptyMap()))).get();
+                    new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_SCRIPT, Collections.emptyMap()))).get();
         assertSearchResponse(r);
 
         assertThat(client().admin().indices().prepareStats("cache_test_idx").setRequestCache(true).get().getTotal().getRequestCache()
@@ -390,207 +382,4 @@ public class SumIT extends AbstractNumericTestCase {
         assertThat(client().admin().indices().prepareStats("cache_test_idx").setRequestCache(true).get().getTotal().getRequestCache()
                 .getMissCount(), equalTo(1L));
     }
-
-    /**
-     * Mock plugin for the {@link ExtractFieldScriptEngine}
-     */
-    public static class ExtractFieldScriptPlugin extends Plugin implements ScriptPlugin {
-        @Override
-        public ScriptEngine getScriptEngine(Settings settings) {
-            return new ExtractFieldScriptEngine();
-        }
-    }
-
-    /**
-     * This mock script returns the field that is specified by name in the
-     * script body
-     */
-    public static class ExtractFieldScriptEngine implements ScriptEngine {
-
-        public static final String NAME = "extract_field";
-
-        @Override
-        public void close() throws IOException {
-        }
-
-        @Override
-        public String getType() {
-            return NAME;
-        }
-
-        @Override
-        public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
-            return scriptSource;
-        }
-
-        @Override
-        public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
-            final long inc;
-            if (vars == null || vars.containsKey("inc") == false) {
-                inc = 0;
-            } else {
-                inc = ((Number) vars.get("inc")).longValue();
-            }
-            return new SearchScript() {
-
-                @Override
-                public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
-
-                    final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
-
-                    return new LeafSearchScript() {
-                        @Override
-                        public void setNextVar(String name, Object value) {
-                        }
-
-                        @Override
-                        public Object run() {
-                            String fieldName = (String) compiledScript.compiled();
-                            List<Long> values = new ArrayList<>();
-                            for (Object v : (List<?>) leafLookup.doc().get(fieldName)) {
-                                values.add(((Number) v).longValue() + inc);
-                            }
-                            return values;
-                        }
-
-                        @Override
-                        public void setScorer(Scorer scorer) {
-                        }
-
-                        @Override
-                        public void setSource(Map<String, Object> source) {
-                        }
-
-                        @Override
-                        public void setDocument(int doc) {
-                            if (leafLookup != null) {
-                                leafLookup.setDocument(doc);
-                            }
-                        }
-
-                        @Override
-                        public long runAsLong() {
-                            throw new UnsupportedOperationException();
-                        }
-
-                        @Override
-                        public double runAsDouble() {
-                            throw new UnsupportedOperationException();
-                        }
-                    };
-                }
-
-                @Override
-                public boolean needsScores() {
-                    return false;
-                }
-            };
-        }
-    }
-
-    /**
-     * Mock plugin for the {@link FieldValueScriptEngine}
-     */
-    public static class FieldValueScriptPlugin extends Plugin implements ScriptPlugin {
-        @Override
-        public ScriptEngine getScriptEngine(Settings settings) {
-            return new FieldValueScriptEngine();
-        }
-    }
-
-    /**
-     * This mock script returns the field value and adds one to the returned
-     * value
-     */
-    public static class FieldValueScriptEngine implements ScriptEngine {
-
-        public static final String NAME = "field_value";
-
-        @Override
-        public void close() throws IOException {
-        }
-
-        @Override
-        public String getType() {
-            return NAME;
-        }
-
-        @Override
-        public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
-            return scriptSource;
-        }
-
-        @Override
-        public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
-            final long inc;
-            if (vars == null || vars.containsKey("inc") == false) {
-                inc = 0;
-            } else {
-                inc = ((Number) vars.get("inc")).longValue();
-            }
-            return new SearchScript() {
-
-                private Map<String, Object> vars = new HashMap<>(2);
-
-                @Override
-                public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
-
-                    final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
-
-                    return new LeafSearchScript() {
-
-                        @Override
-                        public void setNextVar(String name, Object value) {
-                            vars.put(name, value);
-                        }
-
-                        @Override
-                        public Object run() {
-                            throw new UnsupportedOperationException();
-                        }
-
-                        @Override
-                        public void setScorer(Scorer scorer) {
-                        }
-
-                        @Override
-                        public void setSource(Map<String, Object> source) {
-                        }
-
-                        @Override
-                        public void setDocument(int doc) {
-                            if (leafLookup != null) {
-                                leafLookup.setDocument(doc);
-                            }
-                        }
-
-                        @Override
-                        public long runAsLong() {
-                            return ((Number) vars.get("_value")).longValue() + inc;
-                        }
-
-                        @Override
-                        public double runAsDouble() {
-                            return ((Number) vars.get("_value")).doubleValue() + inc;
-                        }
-                    };
-                }
-
-                @Override
-                public boolean needsScores() {
-                    return false;
-                }
-            };
-        }
-    }
 }

+ 22 - 124
core/src/test/java/org/elasticsearch/search/aggregations/metrics/ValueCountIT.java

@@ -18,36 +18,28 @@
  */
 package org.elasticsearch.search.aggregations.metrics;
 
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.Scorer;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
 import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.plugins.Plugin;
-import org.elasticsearch.plugins.ScriptPlugin;
-import org.elasticsearch.script.CompiledScript;
-import org.elasticsearch.script.ExecutableScript;
-import org.elasticsearch.script.LeafSearchScript;
 import org.elasticsearch.script.Script;
-import org.elasticsearch.script.ScriptEngine;
 import org.elasticsearch.script.ScriptType;
-import org.elasticsearch.script.SearchScript;
 import org.elasticsearch.search.aggregations.InternalAggregation;
 import org.elasticsearch.search.aggregations.bucket.global.Global;
 import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount;
-import org.elasticsearch.search.lookup.LeafSearchLookup;
-import org.elasticsearch.search.lookup.SearchLookup;
 import org.elasticsearch.test.ESIntegTestCase;
 
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
 import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
 import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
 import static org.elasticsearch.search.aggregations.AggregationBuilders.count;
 import static org.elasticsearch.search.aggregations.AggregationBuilders.global;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.METRIC_SCRIPT_ENGINE;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.SUM_FIELD_PARAMS_SCRIPT;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.SUM_VALUES_FIELD_SCRIPT;
+import static org.elasticsearch.search.aggregations.metrics.MetricAggScriptPlugin.VALUE_FIELD_SCRIPT;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
@@ -75,7 +67,7 @@ public class ValueCountIT extends ESIntegTestCase {
 
     @Override
     protected Collection<Class<? extends Plugin>> nodePlugins() {
-        return Collections.singletonList(FieldValueScriptPlugin.class);
+        return Collections.singletonList(MetricAggScriptPlugin.class);
     }
 
     public void testUnmapped() throws Exception {
@@ -158,7 +150,9 @@ public class ValueCountIT extends ESIntegTestCase {
 
     public void testSingleValuedScript() throws Exception {
         SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
-                .addAggregation(count("count").script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "value", Collections.emptyMap()))).execute().actionGet();
+            .addAggregation(count("count").script(
+                new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_FIELD_SCRIPT, Collections.emptyMap())))
+            .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
 
@@ -170,7 +164,9 @@ public class ValueCountIT extends ESIntegTestCase {
 
     public void testMultiValuedScript() throws Exception {
         SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
-                .addAggregation(count("count").script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "values", Collections.emptyMap()))).execute().actionGet();
+            .addAggregation(count("count").script(
+                new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_VALUES_FIELD_SCRIPT, Collections.emptyMap())))
+            .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
 
@@ -181,9 +177,10 @@ public class ValueCountIT extends ESIntegTestCase {
     }
 
     public void testSingleValuedScriptWithParams() throws Exception {
-        Map<String, Object> params = Collections.singletonMap("s", "value");
+        Map<String, Object> params = Collections.singletonMap("field", "value");
         SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
-                .addAggregation(count("count").script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", params))).execute().actionGet();
+            .addAggregation(count("count").script(new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_FIELD_PARAMS_SCRIPT, params)))
+            .execute().actionGet();
 
         assertHitCount(searchResponse, 10);
 
@@ -194,9 +191,10 @@ public class ValueCountIT extends ESIntegTestCase {
     }
 
     public void testMultiValuedScriptWithParams() throws Exception {
-        Map<String, Object> params = Collections.singletonMap("s", "values");
+        Map<String, Object> params = Collections.singletonMap("field", "values");
         SearchResponse searchResponse = client().prepareSearch("idx").setQuery(matchAllQuery())
-                .addAggregation(count("count").script(new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "", params))).execute().actionGet();
+                .addAggregation(count("count").script(
+                    new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, SUM_FIELD_PARAMS_SCRIPT, params))).execute().actionGet();
 
         assertHitCount(searchResponse, 10);
 
@@ -226,7 +224,7 @@ public class ValueCountIT extends ESIntegTestCase {
         // Test that a request using a script does not get cached
         SearchResponse r = client().prepareSearch("cache_test_idx").setSize(0)
                 .addAggregation(count("foo").field("d").script(
-                    new Script(ScriptType.INLINE, FieldValueScriptEngine.NAME, "value", Collections.emptyMap())))
+                    new Script(ScriptType.INLINE, METRIC_SCRIPT_ENGINE, VALUE_FIELD_SCRIPT, Collections.emptyMap())))
                 .get();
         assertSearchResponse(r);
 
@@ -245,104 +243,4 @@ public class ValueCountIT extends ESIntegTestCase {
         assertThat(client().admin().indices().prepareStats("cache_test_idx").setRequestCache(true).get().getTotal().getRequestCache()
                 .getMissCount(), equalTo(1L));
     }
-
-    /**
-     * Mock plugin for the {@link FieldValueScriptEngine}
-     */
-    public static class FieldValueScriptPlugin extends Plugin implements ScriptPlugin {
-        @Override
-        public ScriptEngine getScriptEngine(Settings settings) {
-            return new FieldValueScriptEngine();
-        }
-    }
-
-    /**
-     * This mock script returns the field value. If the parameter map contains a parameter "s", the corresponding is used as field name.
-     */
-    public static class FieldValueScriptEngine implements ScriptEngine {
-
-        public static final String NAME = "field_value";
-
-        @Override
-        public void close() throws IOException {
-        }
-
-        @Override
-        public String getType() {
-            return NAME;
-        }
-
-        @Override
-        public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
-            return scriptSource;
-        }
-
-        @Override
-        public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
-            throw new UnsupportedOperationException();
-        }
-        @Override
-        public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
-            final String fieldNameParam;
-            if (vars == null || vars.containsKey("s") == false) {
-                fieldNameParam = null;
-            } else {
-                fieldNameParam = (String) vars.get("s");
-            }
-
-            return new SearchScript() {
-                private Map<String, Object> vars = new HashMap<>(2);
-
-                @Override
-                public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
-
-                    final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
-
-                    return new LeafSearchScript() {
-
-                        @Override
-                        public void setNextVar(String name, Object value) {
-                            vars.put(name, value);
-                        }
-
-                        @Override
-                        public Object run() {
-                            String fieldName = (fieldNameParam != null) ? fieldNameParam : (String) compiledScript.compiled();
-                            return leafLookup.doc().get(fieldName);
-                        }
-
-                        @Override
-                        public void setScorer(Scorer scorer) {
-                        }
-
-                        @Override
-                        public void setSource(Map<String, Object> source) {
-                        }
-
-                        @Override
-                        public void setDocument(int doc) {
-                            if (leafLookup != null) {
-                                leafLookup.setDocument(doc);
-                            }
-                        }
-
-                        @Override
-                        public long runAsLong() {
-                            throw new UnsupportedOperationException();
-                        }
-
-                        @Override
-                        public double runAsDouble() {
-                            throw new UnsupportedOperationException();
-                        }
-                    };
-                }
-
-                @Override
-                public boolean needsScores() {
-                    return false;
-                }
-            };
-        }
-    }
 }

+ 6 - 11
core/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java

@@ -50,13 +50,10 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.index.query.TermQueryBuilder;
 import org.elasticsearch.index.shard.ShardId;
 import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
-import org.elasticsearch.script.CompiledScript;
-import org.elasticsearch.script.Script;
+import org.elasticsearch.script.MockScriptEngine;
 import org.elasticsearch.script.ScriptContext;
 import org.elasticsearch.script.ScriptEngine;
 import org.elasticsearch.script.ScriptService;
-import org.elasticsearch.script.ScriptServiceTests.TestEngine;
-import org.elasticsearch.script.ScriptType;
 import org.elasticsearch.search.DocValueFormat;
 import org.elasticsearch.search.SearchModule;
 import org.elasticsearch.test.ESTestCase;
@@ -67,6 +64,8 @@ import org.junit.BeforeClass;
 import java.io.IOException;
 import java.nio.file.Path;
 import java.util.Collections;
+import java.util.Map;
+import java.util.function.Function;
 
 import static java.util.Collections.emptyList;
 import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
@@ -86,13 +85,9 @@ public abstract class AbstractSortTestCase<T extends SortBuilder<T>> extends EST
                 .put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toString())
                 .put(Environment.PATH_CONF_SETTING.getKey(), genericConfigFolder)
                 .build();
-        ScriptEngine engine = new TestEngine();
-        scriptService = new ScriptService(baseSettings, Collections.singletonMap(engine.getType(), engine), ScriptContext.BUILTINS) {
-            @Override
-            public CompiledScript compile(Script script, ScriptContext scriptContext) {
-                return new CompiledScript(ScriptType.INLINE, "mockName", "test", script);
-            }
-        };
+        Map<String, Function<Map<String, Object>, Object>> scripts = Collections.singletonMap("dummy", p -> null);
+        ScriptEngine engine = new MockScriptEngine(MockScriptEngine.NAME, scripts);
+        scriptService = new ScriptService(baseSettings, Collections.singletonMap(engine.getType(), engine), ScriptContext.BUILTINS);
 
         SearchModule searchModule = new SearchModule(Settings.EMPTY, false, emptyList());
         namedWriteableRegistry = new NamedWriteableRegistry(searchModule.getNamedWriteables());

+ 1 - 1
core/src/test/java/org/elasticsearch/search/sort/ScriptSortBuilderTests.java

@@ -43,7 +43,7 @@ public class ScriptSortBuilderTests extends AbstractSortTestCase<ScriptSortBuild
 
     public static ScriptSortBuilder randomScriptSortBuilder() {
         ScriptSortType type = randomBoolean() ? ScriptSortType.NUMBER : ScriptSortType.STRING;
-        ScriptSortBuilder builder = new ScriptSortBuilder(mockScript(randomAlphaOfLengthBetween(5, 10)),
+        ScriptSortBuilder builder = new ScriptSortBuilder(mockScript("dummy"),
                 type);
         if (randomBoolean()) {
                 builder.order(randomFrom(SortOrder.values()));

+ 104 - 272
core/src/test/java/org/elasticsearch/update/UpdateIT.java

@@ -19,6 +19,19 @@
 
 package org.elasticsearch.update;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+
 import org.elasticsearch.ElasticsearchTimeoutException;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.ActionRequestValidationException;
@@ -37,30 +50,12 @@ import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.index.MergePolicyConfig;
 import org.elasticsearch.index.engine.DocumentMissingException;
 import org.elasticsearch.plugins.Plugin;
-import org.elasticsearch.plugins.ScriptPlugin;
-import org.elasticsearch.script.CompiledScript;
-import org.elasticsearch.script.ExecutableScript;
+import org.elasticsearch.script.MockScriptPlugin;
 import org.elasticsearch.script.Script;
-import org.elasticsearch.script.ScriptEngine;
 import org.elasticsearch.script.ScriptType;
-import org.elasticsearch.script.SearchScript;
-import org.elasticsearch.search.lookup.SearchLookup;
 import org.elasticsearch.test.ESIntegTestCase;
 import org.elasticsearch.test.InternalSettingsPlugin;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
 import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
 import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertThrows;
@@ -71,247 +66,76 @@ import static org.hamcrest.Matchers.nullValue;
 
 public class UpdateIT extends ESIntegTestCase {
 
-    public static class PutFieldValuesScriptPlugin extends Plugin implements ScriptPlugin {
-        @Override
-        public ScriptEngine getScriptEngine(Settings settings) {
-            return new PutFieldValuesScriptEngine();
-        }
-    }
-
-    public static class PutFieldValuesScriptEngine implements ScriptEngine {
-
-        public static final String NAME = "put_values";
-
-        @Override
-        public void close() throws IOException {
-        }
-
-        @Override
-        public String getType() {
-            return NAME;
-        }
-
-        @Override
-        public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
-            return new Object(); // unused
-        }
-
-        @Override
-        public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> originalParams) {
-            return new ExecutableScript() {
-
-                Map<String, Object> vars = new HashMap<>();
-
-                @Override
-                public void setNextVar(String name, Object value) {
-                    vars.put(name, value);
-                }
-
-                @Override
-                public Object run() {
-                    Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
-                    assertNotNull(ctx);
-
-                    Map<String, Object> params = new HashMap<>(originalParams);
-
-                    Map<String, Object> newCtx = (Map<String, Object>) params.remove("_ctx");
-                    if (newCtx != null) {
-                        assertFalse(newCtx.containsKey("_source"));
-                        ctx.putAll(newCtx);
-                    }
-
-                    Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
-                    source.putAll(params);
-
-                    return ctx;
-                }
-            };
-        }
-
-        @Override
-        public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    public static class FieldIncrementScriptPlugin extends Plugin implements ScriptPlugin {
-        @Override
-        public ScriptEngine getScriptEngine(Settings settings) {
-            return new FieldIncrementScriptEngine();
-        }
-    }
-
-    public static class FieldIncrementScriptEngine implements ScriptEngine {
-
-        public static final String NAME = "field_inc";
-
-        @Override
-        public void close() throws IOException {
-        }
-
-        @Override
-        public String getType() {
-            return NAME;
-        }
-
-        @Override
-        public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
-            return scriptSource;
-        }
-
-        @Override
-        public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
-            final String field = (String) compiledScript.compiled();
-            return new ExecutableScript() {
-
-                Map<String, Object> vars = new HashMap<>();
-
-                @Override
-                public void setNextVar(String name, Object value) {
-                    vars.put(name, value);
-                }
-
-                @Override
-                public Object run() {
-                    Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
-                    assertNotNull(ctx);
-                    Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
-                    Number currentValue = (Number) source.get(field);
-                    Number inc = params == null ? 1L : (Number) params.getOrDefault("inc", 1);
-                    source.put(field, currentValue.longValue() + inc.longValue());
-                    return ctx;
-                }
-            };
-        }
-
-        @Override
-        public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    public static class ScriptedUpsertScriptPlugin extends Plugin implements ScriptPlugin {
-        @Override
-        public ScriptEngine getScriptEngine(Settings settings) {
-            return new ScriptedUpsertScriptEngine();
-        }
-    }
-
-    public static class ScriptedUpsertScriptEngine implements ScriptEngine {
-
-        public static final String NAME = "scripted_upsert";
-
-        @Override
-        public void close() throws IOException {
-        }
-
-        @Override
-        public String getType() {
-            return NAME;
-        }
-
-        @Override
-        public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
-            return new Object(); // unused
-        }
-
-        @Override
-        public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
-            return new ExecutableScript() {
-
-                Map<String, Object> vars = new HashMap<>();
-
-                @Override
-                public void setNextVar(String name, Object value) {
-                    vars.put(name, value);
-                }
-
-                @Override
-                public Object run() {
-                    Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
-                    assertNotNull(ctx);
-                    Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
-                    Number payment = (Number) params.get("payment");
-                    Number oldBalance = (Number) source.get("balance");
-                    int deduction = "create".equals(ctx.get("op")) ? payment.intValue() / 2 : payment.intValue();
-                    source.put("balance", oldBalance.intValue() - deduction);
-                    return ctx;
-                }
-            };
-        }
-
-        @Override
-        public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    public static class ExtractContextInSourceScriptPlugin extends Plugin implements ScriptPlugin {
-        @Override
-        public ScriptEngine getScriptEngine(Settings settings) {
-            return new ExtractContextInSourceScriptEngine();
-        }
-    }
-
-    public static class ExtractContextInSourceScriptEngine implements ScriptEngine {
-
-        public static final String NAME = "extract_ctx";
-
-        @Override
-        public void close() throws IOException {
-        }
-
-        @Override
-        public String getType() {
-            return NAME;
-        }
+    private static final String UPDATE_SCRIPTS = "update_scripts";
+    private static final String PUT_VALUES_SCRIPT = "put_values";
+    private static final String FIELD_INC_SCRIPT = "field_inc";
+    private static final String UPSERT_SCRIPT = "scripted_upsert";
+    private static final String EXTRACT_CTX_SCRIPT = "extract_ctx";
 
+    public static class UpdateScriptsPlugin extends MockScriptPlugin {
         @Override
-        public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
-            return new Object(); // unused
+        public String pluginScriptLang() {
+            return UPDATE_SCRIPTS;
         }
-
         @Override
-        public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> params) {
-            return new ExecutableScript() {
-
-                Map<String, Object> vars = new HashMap<>();
-
-                @Override
-                public void setNextVar(String name, Object value) {
-                    vars.put(name, value);
-                }
-
-                @Override
-                public Object run() {
-                    Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
-                    assertNotNull(ctx);
-
-                    Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
-                    Map<String, Object> ctxWithoutSource = new HashMap<>(ctx);
-                    ctxWithoutSource.remove("_source");
-                    source.put("update_context", ctxWithoutSource);
-
-                    return ctx;
+        protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
+            Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
+            scripts.put(PUT_VALUES_SCRIPT, vars -> {
+                Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
+                assertNotNull(ctx);
+
+                Map<String, Object> params = new HashMap<>((Map<String, Object>) vars.get("params"));
+
+                Map<String, Object> newCtx = (Map<String, Object>) params.remove("_ctx");
+                if (newCtx != null) {
+                    assertFalse(newCtx.containsKey("_source"));
+                    ctx.putAll(newCtx);
                 }
-            };
-        }
 
-        @Override
-        public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, Map<String, Object> vars) {
-            throw new UnsupportedOperationException();
+                Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
+                source.putAll(params);
+
+                return ctx;
+            });
+            scripts.put(FIELD_INC_SCRIPT, vars -> {
+                Map<String, Object> params = (Map<String, Object>) vars.get("params");
+                String fieldname = (String) vars.get("field");
+                Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
+                assertNotNull(ctx);
+                Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
+                Number currentValue = (Number) source.get(fieldname);
+                Number inc = (Number) params.getOrDefault("inc", 1);
+                source.put(fieldname, currentValue.longValue() + inc.longValue());
+                return ctx;
+            });
+            scripts.put(UPSERT_SCRIPT, vars -> {
+                Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
+                assertNotNull(ctx);
+                Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
+                Number payment = (Number) vars.get("payment");
+                Number oldBalance = (Number) source.get("balance");
+                int deduction = "create".equals(ctx.get("op")) ? payment.intValue() / 2 : payment.intValue();
+                source.put("balance", oldBalance.intValue() - deduction);
+                return ctx;
+            });
+            scripts.put(EXTRACT_CTX_SCRIPT, vars -> {
+                Map<String, Object> ctx = (Map<String, Object>) vars.get("ctx");
+                assertNotNull(ctx);
+
+                Map<String, Object> source = (Map<String, Object>) ctx.get("_source");
+                Map<String, Object> ctxWithoutSource = new HashMap<>(ctx);
+                ctxWithoutSource.remove("_source");
+                source.put("update_context", ctxWithoutSource);
+
+                return ctx;
+            });
+            return scripts;
         }
     }
 
     @Override
     protected Collection<Class<? extends Plugin>> nodePlugins() {
-        return Arrays.asList(
-                PutFieldValuesScriptPlugin.class,
-                FieldIncrementScriptPlugin.class,
-                ScriptedUpsertScriptPlugin.class,
-                ExtractContextInSourceScriptPlugin.class,
-                InternalSettingsPlugin.class
-        );
+        return Arrays.asList(UpdateScriptsPlugin.class, InternalSettingsPlugin.class);
     }
 
     private void createTestIndex() throws Exception {
@@ -323,10 +147,11 @@ public class UpdateIT extends ESIntegTestCase {
     public void testUpsert() throws Exception {
         createTestIndex();
         ensureGreen();
+        Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
 
         UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
                 .setUpsert(XContentFactory.jsonBuilder().startObject().field("field", 1).endObject())
-                .setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
+                .setScript(fieldIncScript)
                 .execute().actionGet();
         assertEquals(DocWriteResponse.Result.CREATED, updateResponse.getResult());
         assertThat(updateResponse.getIndex(), equalTo("test"));
@@ -338,7 +163,7 @@ public class UpdateIT extends ESIntegTestCase {
 
         updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
                 .setUpsert(XContentFactory.jsonBuilder().startObject().field("field", 1).endObject())
-                .setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
+                .setScript(fieldIncScript)
                 .execute().actionGet();
         assertEquals(DocWriteResponse.Result.UPDATED, updateResponse.getResult());
         assertThat(updateResponse.getIndex(), equalTo("test"));
@@ -367,7 +192,7 @@ public class UpdateIT extends ESIntegTestCase {
         UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
                 .setUpsert(XContentFactory.jsonBuilder().startObject().field("balance", openingBalance).endObject())
                 .setScriptedUpsert(true)
-                .setScript(new Script(ScriptType.INLINE, "scripted_upsert", "", params))
+                .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, UPSERT_SCRIPT, params))
                 .execute().actionGet();
         assertEquals(DocWriteResponse.Result.CREATED, updateResponse.getResult());
         assertThat(updateResponse.getIndex(), equalTo("test"));
@@ -381,7 +206,7 @@ public class UpdateIT extends ESIntegTestCase {
         updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
                 .setUpsert(XContentFactory.jsonBuilder().startObject().field("balance", openingBalance).endObject())
                 .setScriptedUpsert(true)
-                .setScript(new Script(ScriptType.INLINE, "scripted_upsert", "", params))
+                .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, UPSERT_SCRIPT, params))
                 .execute().actionGet();
         assertEquals(DocWriteResponse.Result.UPDATED, updateResponse.getResult());
         assertThat(updateResponse.getIndex(), equalTo("test"));
@@ -425,7 +250,7 @@ public class UpdateIT extends ESIntegTestCase {
 
         UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
                 .setUpsert(XContentFactory.jsonBuilder().startObject().field("bar", "baz").endObject())
-                .setScript(new Script(ScriptType.INLINE, "put_values", "", Collections.singletonMap("extra", "foo")))
+                .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, PUT_VALUES_SCRIPT, Collections.singletonMap("extra", "foo")))
                 .setFetchSource(true)
                 .execute().actionGet();
 
@@ -437,7 +262,7 @@ public class UpdateIT extends ESIntegTestCase {
 
         updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
                 .setUpsert(XContentFactory.jsonBuilder().startObject().field("bar", "baz").endObject())
-                .setScript(new Script(ScriptType.INLINE, "put_values", "", Collections.singletonMap("extra", "foo")))
+                .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, PUT_VALUES_SCRIPT, Collections.singletonMap("extra", "foo")))
                 .setFields("_source")
                 .execute().actionGet();
 
@@ -451,7 +276,7 @@ public class UpdateIT extends ESIntegTestCase {
     public void testIndexAutoCreation() throws Exception {
         UpdateResponse updateResponse = client().prepareUpdate("test", "type1", "1")
                 .setUpsert(XContentFactory.jsonBuilder().startObject().field("bar", "baz").endObject())
-                .setScript(new Script(ScriptType.INLINE, "put_values", "", Collections.singletonMap("extra", "foo")))
+                .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, PUT_VALUES_SCRIPT, Collections.singletonMap("extra", "foo")))
                 .setFetchSource(true)
                 .execute().actionGet();
 
@@ -466,9 +291,9 @@ public class UpdateIT extends ESIntegTestCase {
         createTestIndex();
         ensureGreen();
 
+        Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
         try {
-            client().prepareUpdate(indexOrAlias(), "type1", "1")
-                    .setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap())).execute().actionGet();
+            client().prepareUpdate(indexOrAlias(), "type1", "1").setScript(fieldIncScript).execute().actionGet();
             fail();
         } catch (DocumentMissingException e) {
             // all is well
@@ -477,7 +302,7 @@ public class UpdateIT extends ESIntegTestCase {
         client().prepareIndex("test", "type1", "1").setSource("field", 1).execute().actionGet();
 
         UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
-                .setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap())).execute().actionGet();
+            .setScript(fieldIncScript).execute().actionGet();
         assertThat(updateResponse.getVersion(), equalTo(2L));
         assertEquals(DocWriteResponse.Result.UPDATED, updateResponse.getResult());
         assertThat(updateResponse.getIndex(), equalTo("test"));
@@ -489,8 +314,9 @@ public class UpdateIT extends ESIntegTestCase {
 
         Map<String, Object> params = new HashMap<>();
         params.put("inc", 3);
+        params.put("field", "field");
         updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
-                .setScript(new Script(ScriptType.INLINE, "field_inc", "field", params)).execute().actionGet();
+                .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, params)).execute().actionGet();
         assertThat(updateResponse.getVersion(), equalTo(3L));
         assertEquals(DocWriteResponse.Result.UPDATED, updateResponse.getResult());
         assertThat(updateResponse.getIndex(), equalTo("test"));
@@ -502,7 +328,8 @@ public class UpdateIT extends ESIntegTestCase {
 
         // check noop
         updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
-                .setScript(new Script(ScriptType.INLINE, "put_values", "", Collections.singletonMap("_ctx", Collections.singletonMap("op", "none")))).execute().actionGet();
+                .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, PUT_VALUES_SCRIPT,
+                    Collections.singletonMap("_ctx", Collections.singletonMap("op", "none")))).execute().actionGet();
         assertThat(updateResponse.getVersion(), equalTo(3L));
         assertEquals(DocWriteResponse.Result.NOOP, updateResponse.getResult());
         assertThat(updateResponse.getIndex(), equalTo("test"));
@@ -514,7 +341,8 @@ public class UpdateIT extends ESIntegTestCase {
 
         // check delete
         updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
-                .setScript(new Script(ScriptType.INLINE, "put_values", "", Collections.singletonMap("_ctx", Collections.singletonMap("op", "delete")))).execute().actionGet();
+                .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, PUT_VALUES_SCRIPT,
+                    Collections.singletonMap("_ctx", Collections.singletonMap("op", "delete")))).execute().actionGet();
         assertThat(updateResponse.getVersion(), equalTo(4L));
         assertEquals(DocWriteResponse.Result.DELETED, updateResponse.getResult());
         assertThat(updateResponse.getIndex(), equalTo("test"));
@@ -527,7 +355,7 @@ public class UpdateIT extends ESIntegTestCase {
         // check fields parameter
         client().prepareIndex("test", "type1", "1").setSource("field", 1).execute().actionGet();
         updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
-            .setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
+            .setScript(fieldIncScript)
             .setFields("field")
             .setFetchSource(true)
             .execute().actionGet();
@@ -540,7 +368,7 @@ public class UpdateIT extends ESIntegTestCase {
         // check _source parameter
         client().prepareIndex("test", "type1", "1").setSource("field1", 1, "field2", 2).execute().actionGet();
         updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
-            .setScript(new Script(ScriptType.INLINE, "field_inc", "field1", Collections.emptyMap()))
+            .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field1")))
             .setFetchSource("field1", "field2")
             .get();
         assertThat(updateResponse.getIndex(), equalTo("test"));
@@ -600,10 +428,11 @@ public class UpdateIT extends ESIntegTestCase {
         createTestIndex();
         ensureGreen();
 
+        Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
         try {
             client().prepareUpdate(indexOrAlias(), "type1", "1")
                     .setDoc(XContentFactory.jsonBuilder().startObject().field("field", 1).endObject())
-                    .setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
+                    .setScript(fieldIncScript)
                     .execute().actionGet();
             fail("Should have thrown ActionRequestValidationException");
         } catch (ActionRequestValidationException e) {
@@ -616,9 +445,10 @@ public class UpdateIT extends ESIntegTestCase {
     public void testUpdateRequestWithScriptAndShouldUpsertDoc() throws Exception {
         createTestIndex();
         ensureGreen();
+        Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
         try {
             client().prepareUpdate(indexOrAlias(), "type1", "1")
-                    .setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
+                    .setScript(fieldIncScript)
                     .setDocAsUpsert(true)
                     .execute().actionGet();
             fail("Should have thrown ActionRequestValidationException");
@@ -667,7 +497,7 @@ public class UpdateIT extends ESIntegTestCase {
         // Update the first object and note context variables values
         UpdateResponse updateResponse = client().prepareUpdate("test", "subtype1", "id1")
                 .setRouting("routing1")
-                .setScript(new Script(ScriptType.INLINE, "extract_ctx", "", Collections.emptyMap()))
+                .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, EXTRACT_CTX_SCRIPT, Collections.emptyMap()))
                 .execute().actionGet();
 
         assertEquals(2, updateResponse.getVersion());
@@ -683,7 +513,7 @@ public class UpdateIT extends ESIntegTestCase {
 
         // Idem with the second object
         updateResponse = client().prepareUpdate("test", "type1", "parentId1")
-                .setScript(new Script(ScriptType.INLINE, "extract_ctx", "", Collections.emptyMap()))
+                .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, EXTRACT_CTX_SCRIPT, Collections.emptyMap()))
                 .execute().actionGet();
 
         assertEquals(2, updateResponse.getVersion());
@@ -710,6 +540,7 @@ public class UpdateIT extends ESIntegTestCase {
         final int numberOfUpdatesPerThread = scaledRandomIntBetween(100, 500);
         final List<Exception> failures = new CopyOnWriteArrayList<>();
 
+        Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
         for (int i = 0; i < numberOfThreads; i++) {
             Runnable r = new Runnable() {
                 @Override
@@ -722,13 +553,13 @@ public class UpdateIT extends ESIntegTestCase {
                             }
                             if (useBulkApi) {
                                 UpdateRequestBuilder updateRequestBuilder = client().prepareUpdate(indexOrAlias(), "type1", Integer.toString(i))
-                                        .setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
+                                        .setScript(fieldIncScript)
                                         .setRetryOnConflict(Integer.MAX_VALUE)
                                         .setUpsert(jsonBuilder().startObject().field("field", 1).endObject());
                                 client().prepareBulk().add(updateRequestBuilder).execute().actionGet();
                             } else {
                                 client().prepareUpdate(indexOrAlias(), "type1", Integer.toString(i))
-                                        .setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
+                                        .setScript(fieldIncScript)
                                         .setRetryOnConflict(Integer.MAX_VALUE)
                                         .setUpsert(jsonBuilder().startObject().field("field", 1).endObject())
                                         .execute().actionGet();
@@ -773,6 +604,7 @@ public class UpdateIT extends ESIntegTestCase {
                 .setSettings(Settings.builder().put(MergePolicyConfig.INDEX_MERGE_ENABLED, false)));
         ensureGreen();
 
+        Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
         final int numberOfThreads = scaledRandomIntBetween(3,5);
         final int numberOfIdsPerThread = scaledRandomIntBetween(3,10);
         final int numberOfUpdatesPerId = scaledRandomIntBetween(10,100);
@@ -848,7 +680,7 @@ public class UpdateIT extends ESIntegTestCase {
                             updateRequestsOutstanding.acquire();
                             try {
                                 UpdateRequest ur = client().prepareUpdate("test", "type1", Integer.toString(j))
-                                        .setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
+                                        .setScript(fieldIncScript)
                                         .setRetryOnConflict(retryOnConflict)
                                         .setUpsert(jsonBuilder().startObject().field("field", 1).endObject())
                                         .request();
@@ -948,7 +780,7 @@ public class UpdateIT extends ESIntegTestCase {
         //All the previous operations should be complete or failed at this point
         for (int i = 0; i < numberOfIdsPerThread; ++i) {
             UpdateResponse ur = client().prepareUpdate("test", "type1", Integer.toString(i))
-                    .setScript(new Script(ScriptType.INLINE, "field_inc", "field", Collections.emptyMap()))
+                    .setScript(fieldIncScript)
                 .setRetryOnConflict(Integer.MAX_VALUE)
                 .setUpsert(jsonBuilder().startObject().field("field", 1).endObject())
                 .execute().actionGet();

+ 17 - 13
test/framework/src/main/java/org/elasticsearch/script/MockScriptEngine.java

@@ -98,13 +98,13 @@ public class MockScriptEngine implements ScriptEngine {
 
         private final String name;
         private final String source;
-        private final Map<String, String> params;
+        private final Map<String, String> options;
         private final Function<Map<String, Object>, Object> script;
 
-        public MockCompiledScript(String name, Map<String, String> params, String source, Function<Map<String, Object>, Object> script) {
+        public MockCompiledScript(String name, Map<String, String> options, String source, Function<Map<String, Object>, Object> script) {
             this.name = name;
             this.source = source;
-            this.params = params;
+            this.options = options;
             this.script = script;
         }
 
@@ -112,24 +112,28 @@ public class MockScriptEngine implements ScriptEngine {
             return name;
         }
 
-        public ExecutableScript createExecutableScript(Map<String, Object> vars) {
+        public ExecutableScript createExecutableScript(Map<String, Object> params) {
             Map<String, Object> context = new HashMap<>();
-            if (params != null) {
-                context.putAll(params);
+            if (options != null) {
+                context.putAll(options); // TODO: remove this once scripts know to look for options under options key
+                context.put("options", options);
             }
-            if (vars != null) {
-                context.putAll(vars);
+            if (params != null) {
+                context.putAll(params); // TODO: remove this once scripts know to look for params under params key
+                context.put("params", params);
             }
             return new MockExecutableScript(context, script != null ? script : ctx -> source);
         }
 
-        public SearchScript createSearchScript(Map<String, Object> vars, SearchLookup lookup) {
+        public SearchScript createSearchScript(Map<String, Object> params, SearchLookup lookup) {
             Map<String, Object> context = new HashMap<>();
-            if (params != null) {
-                context.putAll(params);
+            if (options != null) {
+                context.putAll(options); // TODO: remove this once scripts know to look for options under options key
+                context.put("options", options);
             }
-            if (vars != null) {
-                context.putAll(vars);
+            if (params != null) {
+                context.putAll(params); // TODO: remove this once scripts know to look for params under params key
+                context.put("params", params);
             }
             return new MockSearchScript(lookup, context, script != null ? script : ctx -> source);
         }