Move back some messy tests from Groovy plugin to core

This commit moves back some messy tests that have been placed in lang-groovy module in https://github.com/elastic/elasticsearch/pull/13834. It removes the dependency on Groovy plugin as well as change back the tests to integration tests (IT suffix).

It also changes the current MockScriptEngine and MockScriptPlugin to make it easier to use.
This commit is contained in:
Tanguy Leroux 2016-07-06 12:55:20 +02:00
parent a13717633c
commit b58f2eb5c2
13 changed files with 699 additions and 210 deletions

View File

@ -1125,12 +1125,9 @@
<suppress files="modules[/\\]lang-expression[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]expression[/\\]MoreExpressionTests.java" checks="LineLength" /> <suppress files="modules[/\\]lang-expression[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]expression[/\\]MoreExpressionTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]groovy[/\\]GroovyPlugin.java" checks="LineLength" /> <suppress files="modules[/\\]lang-groovy[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]groovy[/\\]GroovyPlugin.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]groovy[/\\]GroovyScriptEngineService.java" checks="LineLength" /> <suppress files="modules[/\\]lang-groovy[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]groovy[/\\]GroovyScriptEngineService.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]BucketScriptTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]BulkTests.java" checks="LineLength" /> <suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]BulkTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]DoubleTermsTests.java" checks="LineLength" /> <suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]DoubleTermsTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]EquivalenceTests.java" checks="LineLength" /> <suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]EquivalenceTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]HDRPercentileRanksTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]HDRPercentilesTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]HistogramTests.java" checks="LineLength" /> <suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]HistogramTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]IPv4RangeTests.java" checks="LineLength" /> <suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]IPv4RangeTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]IndexLookupTests.java" checks="LineLength" /> <suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]IndexLookupTests.java" checks="LineLength" />

View File

@ -58,7 +58,7 @@ public class FileScriptTests extends ESTestCase {
CompiledScript compiledScript = scriptService.compile(script, ScriptContext.Standard.SEARCH, Collections.emptyMap()); CompiledScript compiledScript = scriptService.compile(script, ScriptContext.Standard.SEARCH, Collections.emptyMap());
assertNotNull(compiledScript); assertNotNull(compiledScript);
MockCompiledScript executable = (MockCompiledScript) compiledScript.compiled(); MockCompiledScript executable = (MockCompiledScript) compiledScript.compiled();
assertEquals("script1.mockscript", executable.name); assertEquals("script1.mockscript", executable.getName());
} }
public void testAllOpsDisabled() throws Exception { public void testAllOpsDisabled() throws Exception {

View File

@ -24,6 +24,9 @@ import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.ESIntegTestCase;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.function.Function;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
@ -41,7 +44,7 @@ public class StoredScriptsIT extends ESIntegTestCase {
@Override @Override
protected Collection<Class<? extends Plugin>> nodePlugins() { protected Collection<Class<? extends Plugin>> nodePlugins() {
return pluginList(MockScriptEngine.TestPlugin.class); return pluginList(CustomScriptPlugin.class);
} }
public void testBasics() { public void testBasics() {
@ -79,4 +82,11 @@ public class StoredScriptsIT extends ESIntegTestCase {
assertEquals("Limit of script size in bytes [64] has been exceeded for script [foobar] with size [65]", e.getMessage()); assertEquals("Limit of script size in bytes [64] has been exceeded for script [foobar] with size [65]", e.getMessage());
} }
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
return Collections.emptyMap();
}
}
} }

View File

@ -0,0 +1,85 @@
/*
* 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;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.script.MockScriptPlugin;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
/**
* This class contains various mocked scripts that are used in aggregations integration tests.
*/
public class AggregationTestScriptsPlugin extends MockScriptPlugin {
@Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("20 - _value", vars -> {
double value = (double) vars.get("_value");
return 20.0d - value;
});
scripts.put("_value - 1", vars -> {
double value = (double) vars.get("_value");
return value - 1.0d;
});
scripts.put("_value - dec", vars -> {
double value = (double) vars.get("_value");
int dec = (int) vars.get("dec");
return value - dec;
});
scripts.put("doc['value'].value", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
return doc.get("value");
});
scripts.put("doc['value'].value - dec", vars -> {
int dec = (int) vars.get("dec");
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Longs value = (ScriptDocValues.Longs) doc.get("value");
return value.getValue() - dec;
});
scripts.put("doc['values'].values", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
return doc.get("values");
});
scripts.put("decrement all values", vars -> {
int dec = (int) vars.get("dec");
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Longs values = (ScriptDocValues.Longs) doc.get("values");
double[] res = new double[values.size()];
for (int i = 0; i < res.length; i++) {
res[i] = values.get(i) - dec;
}
return res;
});
return scripts;
}
}

View File

@ -16,20 +16,19 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.elasticsearch.messy.tests; package org.elasticsearch.search.aggregations.metrics;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService.ScriptType; import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.script.groovy.GroovyPlugin; import org.elasticsearch.search.aggregations.AggregationTestScriptsPlugin;
import org.elasticsearch.search.aggregations.bucket.filter.Filter; import org.elasticsearch.search.aggregations.bucket.filter.Filter;
import org.elasticsearch.search.aggregations.bucket.global.Global; import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram.Order; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram.Order;
import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.AbstractNumericTestCase;
import org.elasticsearch.search.aggregations.metrics.percentiles.Percentile; import org.elasticsearch.search.aggregations.metrics.percentiles.Percentile;
import org.elasticsearch.search.aggregations.metrics.percentiles.PercentileRanks; import org.elasticsearch.search.aggregations.metrics.percentiles.PercentileRanks;
import org.elasticsearch.search.aggregations.metrics.percentiles.PercentilesMethod; import org.elasticsearch.search.aggregations.metrics.percentiles.PercentilesMethod;
@ -41,6 +40,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static java.util.Collections.emptyMap;
import static org.elasticsearch.common.util.CollectionUtils.iterableAsArrayList; import static org.elasticsearch.common.util.CollectionUtils.iterableAsArrayList;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.index.query.QueryBuilders.termQuery;
@ -56,13 +56,11 @@ import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.sameInstance; import static org.hamcrest.Matchers.sameInstance;
/** public class HDRPercentileRanksIT extends AbstractNumericTestCase {
*
*/
public class HDRPercentileRanksTests extends AbstractNumericTestCase {
@Override @Override
protected Collection<Class<? extends Plugin>> nodePlugins() { protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class); return Collections.singleton(AggregationTestScriptsPlugin.class);
} }
private static double[] randomPercents(long minValue, long maxValue) { private static double[] randomPercents(long minValue, long maxValue) {
@ -82,7 +80,7 @@ public class HDRPercentileRanksTests extends AbstractNumericTestCase {
} }
} }
Arrays.sort(percents); Arrays.sort(percents);
Loggers.getLogger(HDRPercentileRanksTests.class).info("Using values={}", Arrays.toString(percents)); Loggers.getLogger(HDRPercentileRanksIT.class).info("Using values={}", Arrays.toString(percents));
return percents; return percents;
} }
@ -208,7 +206,7 @@ public class HDRPercentileRanksTests extends AbstractNumericTestCase {
PercentileRanks values = global.getAggregations().get("percentile_ranks"); PercentileRanks values = global.getAggregations().get("percentile_ranks");
assertThat(values, notNullValue()); assertThat(values, notNullValue());
assertThat(values.getName(), equalTo("percentile_ranks")); assertThat(values.getName(), equalTo("percentile_ranks"));
assertThat((PercentileRanks) global.getProperty("percentile_ranks"), sameInstance(values)); assertThat(global.getProperty("percentile_ranks"), sameInstance(values));
} }
@ -255,8 +253,12 @@ public class HDRPercentileRanksTests extends AbstractNumericTestCase {
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentileRanks("percentile_ranks").method(PercentilesMethod.HDR).numberOfSignificantValueDigits(sigDigits) percentileRanks("percentile_ranks")
.field("value").script(new Script("_value - 1")).values(pcts)) .method(PercentilesMethod.HDR)
.numberOfSignificantValueDigits(sigDigits)
.field("value")
.script(new Script("_value - 1", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, emptyMap()))
.values(pcts))
.execute().actionGet(); .execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -275,8 +277,12 @@ public class HDRPercentileRanksTests extends AbstractNumericTestCase {
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentileRanks("percentile_ranks").method(PercentilesMethod.HDR).numberOfSignificantValueDigits(sigDigits) percentileRanks("percentile_ranks")
.field("value").script(new Script("_value - dec", ScriptType.INLINE, null, params)).values(pcts)) .method(PercentilesMethod.HDR)
.numberOfSignificantValueDigits(sigDigits)
.field("value")
.script(new Script("_value - dec", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, params))
.values(pcts))
.execute().actionGet(); .execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -311,8 +317,12 @@ public class HDRPercentileRanksTests extends AbstractNumericTestCase {
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentileRanks("percentile_ranks").method(PercentilesMethod.HDR).numberOfSignificantValueDigits(sigDigits) percentileRanks("percentile_ranks")
.field("values").script(new Script("_value - 1")).values(pcts)) .method(PercentilesMethod.HDR)
.numberOfSignificantValueDigits(sigDigits)
.field("values")
.script(new Script("_value - 1", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, emptyMap()))
.values(pcts))
.execute().actionGet(); .execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -328,8 +338,12 @@ public class HDRPercentileRanksTests extends AbstractNumericTestCase {
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentileRanks("percentile_ranks").method(PercentilesMethod.HDR).numberOfSignificantValueDigits(sigDigits) percentileRanks("percentile_ranks")
.field("values").script(new Script("20 - _value")).values(pcts)) .method(PercentilesMethod.HDR)
.numberOfSignificantValueDigits(sigDigits)
.field("values")
.script(new Script("20 - _value", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, emptyMap()))
.values(pcts))
.execute().actionGet(); .execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -348,8 +362,12 @@ public class HDRPercentileRanksTests extends AbstractNumericTestCase {
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentileRanks("percentile_ranks").method(PercentilesMethod.HDR).numberOfSignificantValueDigits(sigDigits) percentileRanks("percentile_ranks")
.field("values").script(new Script("_value - dec", ScriptType.INLINE, null, params)).values(pcts)) .method(PercentilesMethod.HDR)
.numberOfSignificantValueDigits(sigDigits)
.field("values")
.script(new Script("_value - dec", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, params))
.values(pcts))
.execute().actionGet(); .execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -366,8 +384,11 @@ public class HDRPercentileRanksTests extends AbstractNumericTestCase {
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentileRanks("percentile_ranks").method(PercentilesMethod.HDR).numberOfSignificantValueDigits(sigDigits) percentileRanks("percentile_ranks")
.script(new Script("doc['value'].value")).values(pcts)) .method(PercentilesMethod.HDR)
.numberOfSignificantValueDigits(sigDigits)
.script(new Script("doc['value'].value", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, emptyMap()))
.values(pcts))
.execute().actionGet(); .execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -381,13 +402,19 @@ public class HDRPercentileRanksTests extends AbstractNumericTestCase {
int sigDigits = randomSignificantDigits(); int sigDigits = randomSignificantDigits();
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("dec", 1); params.put("dec", 1);
Script script = new Script("doc['value'].value - dec", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, params);
final double[] pcts = randomPercents(minValue - 1, maxValue - 1); final double[] pcts = randomPercents(minValue - 1, maxValue - 1);
SearchResponse searchResponse = client() SearchResponse searchResponse = client()
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentileRanks("percentile_ranks").method(PercentilesMethod.HDR).numberOfSignificantValueDigits(sigDigits) percentileRanks("percentile_ranks")
.script(new Script("doc['value'].value - dec", ScriptType.INLINE, null, params)).values(pcts)) .method(PercentilesMethod.HDR)
.numberOfSignificantValueDigits(sigDigits)
.script(script)
.values(pcts))
.execute().actionGet(); .execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -400,12 +427,18 @@ public class HDRPercentileRanksTests extends AbstractNumericTestCase {
public void testScriptMultiValued() throws Exception { public void testScriptMultiValued() throws Exception {
int sigDigits = randomSignificantDigits(); int sigDigits = randomSignificantDigits();
final double[] pcts = randomPercents(minValues, maxValues); final double[] pcts = randomPercents(minValues, maxValues);
Script script = new Script("doc['values'].values", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, emptyMap());
SearchResponse searchResponse = client() SearchResponse searchResponse = client()
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentileRanks("percentile_ranks").method(PercentilesMethod.HDR).numberOfSignificantValueDigits(sigDigits) percentileRanks("percentile_ranks")
.script(new Script("doc['values'].values")).values(pcts)) .method(PercentilesMethod.HDR)
.numberOfSignificantValueDigits(sigDigits)
.script(script)
.values(pcts))
.execute().actionGet(); .execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -419,6 +452,17 @@ public class HDRPercentileRanksTests extends AbstractNumericTestCase {
int sigDigits = randomSignificantDigits(); int sigDigits = randomSignificantDigits();
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("dec", 1); params.put("dec", 1);
// Equivalent to:
//
// List values = doc['values'].values;
// double[] res = new double[values.size()];
// for (int i = 0; i < res.length; i++) {
// res[i] = values.get(i) - dec;
// };
// return res;
Script script = new Script("decrement all values", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, params);
final double[] pcts = randomPercents(minValues - 1, maxValues - 1); final double[] pcts = randomPercents(minValues - 1, maxValues - 1);
SearchResponse searchResponse = client() SearchResponse searchResponse = client()
.prepareSearch("idx") .prepareSearch("idx")
@ -427,9 +471,7 @@ public class HDRPercentileRanksTests extends AbstractNumericTestCase {
percentileRanks("percentile_ranks") percentileRanks("percentile_ranks")
.method(PercentilesMethod.HDR) .method(PercentilesMethod.HDR)
.numberOfSignificantValueDigits(sigDigits) .numberOfSignificantValueDigits(sigDigits)
.script(new Script( .script(script)
"List values = doc['values'].values; double[] res = new double[values.size()]; for (int i = 0; i < res.length; i++) { res[i] = values.get(i) - dec; }; return res;",
ScriptType.INLINE, null, params))
.values(pcts)) .values(pcts))
.execute().actionGet(); .execute().actionGet();

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.elasticsearch.messy.tests; package org.elasticsearch.search.aggregations.metrics;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.logging.Loggers;
@ -24,13 +24,12 @@ import org.elasticsearch.common.util.CollectionUtils;
import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService.ScriptType; import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.script.groovy.GroovyPlugin; import org.elasticsearch.search.aggregations.AggregationTestScriptsPlugin;
import org.elasticsearch.search.aggregations.bucket.filter.Filter; import org.elasticsearch.search.aggregations.bucket.filter.Filter;
import org.elasticsearch.search.aggregations.bucket.global.Global; import org.elasticsearch.search.aggregations.bucket.global.Global;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram.Order; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram.Order;
import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.AbstractNumericTestCase;
import org.elasticsearch.search.aggregations.metrics.percentiles.Percentile; import org.elasticsearch.search.aggregations.metrics.percentiles.Percentile;
import org.elasticsearch.search.aggregations.metrics.percentiles.Percentiles; import org.elasticsearch.search.aggregations.metrics.percentiles.Percentiles;
import org.elasticsearch.search.aggregations.metrics.percentiles.PercentilesMethod; import org.elasticsearch.search.aggregations.metrics.percentiles.PercentilesMethod;
@ -42,6 +41,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static java.util.Collections.emptyMap;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.filter; import static org.elasticsearch.search.aggregations.AggregationBuilders.filter;
@ -57,13 +57,11 @@ import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.sameInstance; import static org.hamcrest.Matchers.sameInstance;
/** public class HDRPercentilesIT extends AbstractNumericTestCase {
*
*/
public class HDRPercentilesTests extends AbstractNumericTestCase {
@Override @Override
protected Collection<Class<? extends Plugin>> nodePlugins() { protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class); return Collections.singleton(AggregationTestScriptsPlugin.class);
} }
private static double[] randomPercentiles() { private static double[] randomPercentiles() {
@ -83,7 +81,7 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
} }
} }
Arrays.sort(percentiles); Arrays.sort(percentiles);
Loggers.getLogger(HDRPercentilesTests.class).info("Using percentiles={}", Arrays.toString(percentiles)); Loggers.getLogger(HDRPercentilesIT.class).info("Using percentiles={}", Arrays.toString(percentiles));
return percentiles; return percentiles;
} }
@ -130,8 +128,8 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
percentiles("percentiles").field("value") percentiles("percentiles").field("value")
.numberOfSignificantValueDigits(sigDigits) .numberOfSignificantValueDigits(sigDigits)
.method(PercentilesMethod.HDR) .method(PercentilesMethod.HDR)
.percentiles(10, .percentiles(10, 15)))
15))).execute().actionGet(); .execute().actionGet();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(2L)); assertThat(searchResponse.getHits().getTotalHits(), equalTo(2L));
Histogram histo = searchResponse.getAggregations().get("histo"); Histogram histo = searchResponse.getAggregations().get("histo");
@ -210,7 +208,7 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
Percentiles percentiles = global.getAggregations().get("percentiles"); Percentiles percentiles = global.getAggregations().get("percentiles");
assertThat(percentiles, notNullValue()); assertThat(percentiles, notNullValue());
assertThat(percentiles.getName(), equalTo("percentiles")); assertThat(percentiles.getName(), equalTo("percentiles"));
assertThat((Percentiles) global.getProperty("percentiles"), sameInstance(percentiles)); assertThat(global.getProperty("percentiles"), sameInstance(percentiles));
} }
@ -240,8 +238,13 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentiles("percentiles").numberOfSignificantValueDigits(sigDigits).method(PercentilesMethod.HDR).field("value") percentiles("percentiles")
.script(new Script("_value - 1")).percentiles(pcts)).execute().actionGet(); .numberOfSignificantValueDigits(sigDigits)
.method(PercentilesMethod.HDR)
.field("value")
.script(new Script("_value - 1", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, emptyMap()))
.percentiles(pcts))
.execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -253,15 +256,20 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
public void testSingleValuedFieldWithValueScriptWithParams() throws Exception { public void testSingleValuedFieldWithValueScriptWithParams() throws Exception {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("dec", 1); params.put("dec", 1);
final double[] pcts = randomPercentiles(); final double[] pcts = randomPercentiles();
int sigDigits = randomSignificantDigits(); int sigDigits = randomSignificantDigits();
SearchResponse searchResponse = client() SearchResponse searchResponse = client()
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentiles("percentiles").numberOfSignificantValueDigits(sigDigits).method(PercentilesMethod.HDR).field("value") percentiles("percentiles")
.script(new Script("_value - dec", ScriptType.INLINE, null, params)).percentiles(pcts)).execute() .numberOfSignificantValueDigits(sigDigits)
.actionGet(); .method(PercentilesMethod.HDR)
.field("value")
.script(new Script("_value - dec", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, params))
.percentiles(pcts))
.execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -295,8 +303,13 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentiles("percentiles").numberOfSignificantValueDigits(sigDigits).method(PercentilesMethod.HDR).field("values") percentiles("percentiles")
.script(new Script("_value - 1")).percentiles(pcts)).execute().actionGet(); .numberOfSignificantValueDigits(sigDigits)
.method(PercentilesMethod.HDR)
.field("values")
.script(new Script("_value - 1", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, emptyMap()))
.percentiles(pcts))
.execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -311,8 +324,13 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentiles("percentiles").numberOfSignificantValueDigits(sigDigits).method(PercentilesMethod.HDR).field("values") percentiles("percentiles")
.script(new Script("20 - _value")).percentiles(pcts)).execute().actionGet(); .numberOfSignificantValueDigits(sigDigits)
.method(PercentilesMethod.HDR)
.field("values")
.script(new Script("20 - _value", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, emptyMap()))
.percentiles(pcts))
.execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -324,15 +342,20 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
public void testMultiValuedFieldWithValueScriptWithParams() throws Exception { public void testMultiValuedFieldWithValueScriptWithParams() throws Exception {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("dec", 1); params.put("dec", 1);
final double[] pcts = randomPercentiles(); final double[] pcts = randomPercentiles();
int sigDigits = randomSignificantDigits(); int sigDigits = randomSignificantDigits();
SearchResponse searchResponse = client() SearchResponse searchResponse = client()
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentiles("percentiles").numberOfSignificantValueDigits(sigDigits).method(PercentilesMethod.HDR).field("values") percentiles("percentiles")
.script(new Script("_value - dec", ScriptType.INLINE, null, params)).percentiles(pcts)).execute() .numberOfSignificantValueDigits(sigDigits)
.actionGet(); .method(PercentilesMethod.HDR)
.field("values")
.script(new Script("_value - dec", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, params))
.percentiles(pcts))
.execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -348,8 +371,12 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentiles("percentiles").numberOfSignificantValueDigits(sigDigits).method(PercentilesMethod.HDR) percentiles("percentiles")
.script(new Script("doc['value'].value")).percentiles(pcts)).execute().actionGet(); .numberOfSignificantValueDigits(sigDigits)
.method(PercentilesMethod.HDR)
.script(new Script("doc['value'].value", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, emptyMap()))
.percentiles(pcts))
.execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -361,14 +388,20 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
public void testScriptSingleValuedWithParams() throws Exception { public void testScriptSingleValuedWithParams() throws Exception {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("dec", 1); params.put("dec", 1);
Script script = new Script("doc['value'].value - dec", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, params);
final double[] pcts = randomPercentiles(); final double[] pcts = randomPercentiles();
int sigDigits = randomSignificantDigits(); int sigDigits = randomSignificantDigits();
SearchResponse searchResponse = client() SearchResponse searchResponse = client()
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentiles("percentiles").numberOfSignificantValueDigits(sigDigits).method(PercentilesMethod.HDR) percentiles("percentiles")
.script(new Script("doc['value'].value - dec", ScriptType.INLINE, null, params)).percentiles(pcts)) .numberOfSignificantValueDigits(sigDigits)
.method(PercentilesMethod.HDR)
.script(script)
.percentiles(pcts))
.execute().actionGet(); .execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -381,12 +414,19 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
public void testScriptMultiValued() throws Exception { public void testScriptMultiValued() throws Exception {
final double[] pcts = randomPercentiles(); final double[] pcts = randomPercentiles();
int sigDigits = randomSignificantDigits(); int sigDigits = randomSignificantDigits();
Script script = new Script("doc['values'].values", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, emptyMap());
SearchResponse searchResponse = client() SearchResponse searchResponse = client()
.prepareSearch("idx") .prepareSearch("idx")
.setQuery(matchAllQuery()) .setQuery(matchAllQuery())
.addAggregation( .addAggregation(
percentiles("percentiles").numberOfSignificantValueDigits(sigDigits).method(PercentilesMethod.HDR) percentiles("percentiles")
.script(new Script("doc['values'].values")).percentiles(pcts)).execute().actionGet(); .numberOfSignificantValueDigits(sigDigits)
.method(PercentilesMethod.HDR)
.script(script)
.percentiles(pcts))
.execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);
@ -398,6 +438,17 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
public void testScriptMultiValuedWithParams() throws Exception { public void testScriptMultiValuedWithParams() throws Exception {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("dec", 1); params.put("dec", 1);
// Equivalent to:
//
// List values = doc['values'].values;
// double[] res = new double[values.size()];
// for (int i = 0; i < res.length; i++) {
// res[i] = values.get(i) - dec;
// };
// return res;
Script script = new Script("decrement all values", ScriptType.INLINE, AggregationTestScriptsPlugin.NAME, params);
final double[] pcts = randomPercentiles(); final double[] pcts = randomPercentiles();
int sigDigits = randomSignificantDigits(); int sigDigits = randomSignificantDigits();
SearchResponse searchResponse = client() SearchResponse searchResponse = client()
@ -407,9 +458,9 @@ public class HDRPercentilesTests extends AbstractNumericTestCase {
percentiles("percentiles") percentiles("percentiles")
.numberOfSignificantValueDigits(sigDigits) .numberOfSignificantValueDigits(sigDigits)
.method(PercentilesMethod.HDR) .method(PercentilesMethod.HDR)
.script(new Script( .script(script)
"List values = doc['values'].values; double[] res = new double[values.size()]; for (int i = 0; i < res.length; i++) { res[i] = values.get(i) - dec; }; return res;", .percentiles(pcts))
ScriptType.INLINE, null, params)).percentiles(pcts)).execute().actionGet(); .execute().actionGet();
assertHitCount(searchResponse, 10); assertHitCount(searchResponse, 10);

View File

@ -30,6 +30,7 @@ import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptEngine; import org.elasticsearch.script.MockScriptEngine;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHit;
@ -54,6 +55,8 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Function;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.common.xcontent.XContentFactory.smileBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.smileBuilder;
@ -92,7 +95,14 @@ public class TopHitsIT extends ESIntegTestCase {
@Override @Override
protected Collection<Class<? extends Plugin>> nodePlugins() { protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(MockScriptEngine.TestPlugin.class); return Collections.singleton(CustomScriptPlugin.class);
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
return Collections.emptyMap();
}
} }
public static String randomExecutionHint() { public static String randomExecutionHint() {

View File

@ -17,23 +17,21 @@
* under the License. * under the License.
*/ */
package org.elasticsearch.messy.tests; package org.elasticsearch.search.aggregations.pipeline;
import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService.ScriptType; import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.script.groovy.GroovyPlugin;
import org.elasticsearch.script.groovy.GroovyScriptEngineService;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogram; import org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogram;
import org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogram.Bucket; import org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogram.Bucket;
import org.elasticsearch.search.aggregations.metrics.sum.Sum; import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy; import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
import org.elasticsearch.search.aggregations.pipeline.SimpleValue;
import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.ESIntegTestCase;
import java.io.IOException; import java.io.IOException;
@ -43,18 +41,20 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram; import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum; import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilders.bucketScript; import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilders.bucketScript;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
@ESIntegTestCase.SuiteScopeTestCase @ESIntegTestCase.SuiteScopeTestCase
public class BucketScriptTests extends ESIntegTestCase { public class BucketScriptIT extends ESIntegTestCase {
private static final String FIELD_1_NAME = "field1"; private static final String FIELD_1_NAME = "field1";
private static final String FIELD_2_NAME = "field2"; private static final String FIELD_2_NAME = "field2";
@ -68,7 +68,54 @@ public class BucketScriptTests extends ESIntegTestCase {
@Override @Override
protected Collection<Class<? extends Plugin>> nodePlugins() { protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class); return Collections.singleton(CustomScriptPlugin.class);
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("_value0 + _value1 + _value2", vars -> {
double value0 = (double) vars.get("_value0");
double value1 = (double) vars.get("_value1");
double value2 = (double) vars.get("_value2");
return value0 + value1 + value2;
});
scripts.put("_value0 + _value1 / _value2", vars -> {
double value0 = (double) vars.get("_value0");
double value1 = (double) vars.get("_value1");
double value2 = (double) vars.get("_value2");
return value0 + value1 / value2;
});
scripts.put("_value0", vars -> vars.get("_value0"));
scripts.put("foo + bar + baz", vars -> {
double foo = (double) vars.get("foo");
double bar = (double) vars.get("bar");
double baz = (double) vars.get("baz");
return foo + bar + baz;
});
scripts.put("(_value0 + _value1 + _value2) * factor", vars -> {
double value0 = (double) vars.get("_value0");
double value1 = (double) vars.get("_value1");
double value2 = (double) vars.get("_value2");
return (value0 + value1 + value2) * (int) vars.get("factor");
});
scripts.put("my_script", vars -> {
double value0 = (double) vars.get("_value0");
double value1 = (double) vars.get("_value1");
double value2 = (double) vars.get("_value2");
return value0 + value1 + value2;
});
return scripts;
}
} }
@Override @Override
@ -86,11 +133,6 @@ public class BucketScriptTests extends ESIntegTestCase {
builders.add(client().prepareIndex("idx", "type").setSource(newDocBuilder())); builders.add(client().prepareIndex("idx", "type").setSource(newDocBuilder()));
} }
client().admin().cluster().preparePutStoredScript()
.setId("my_script")
.setScriptLang(GroovyScriptEngineService.NAME)
.setSource(new BytesArray("{ \"script\": \"_value0 + _value1 + _value2\" }")).get();
indexRandom(true, builders); indexRandom(true, builders);
ensureSearchable(); ensureSearchable();
} }
@ -117,8 +159,10 @@ public class BucketScriptTests extends ESIntegTestCase {
.subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(sum("field4Sum").field(FIELD_4_NAME)) .subAggregation(sum("field4Sum").field(FIELD_4_NAME))
.subAggregation( .subAggregation(
bucketScript("seriesArithmetic", new Script("_value0 + _value1 + _value2", ScriptType.INLINE, null, null) bucketScript("seriesArithmetic",
, "field2Sum", "field3Sum", "field4Sum"))).execute().actionGet(); new Script("_value0 + _value1 + _value2", ScriptType.INLINE, CustomScriptPlugin.NAME, null)
, "field2Sum", "field3Sum", "field4Sum")))
.execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -161,8 +205,10 @@ public class BucketScriptTests extends ESIntegTestCase {
.subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(sum("field4Sum").field(FIELD_4_NAME)) .subAggregation(sum("field4Sum").field(FIELD_4_NAME))
.subAggregation( .subAggregation(
bucketScript("seriesArithmetic", new Script("_value0 + _value1 / _value2", ScriptType.INLINE, null, null), bucketScript("seriesArithmetic",
"field2Sum", "field3Sum", "field4Sum"))).execute().actionGet(); new Script("_value0 + _value1 / _value2", ScriptType.INLINE, CustomScriptPlugin.NAME, null),
"field2Sum", "field3Sum", "field4Sum")))
.execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -203,8 +249,10 @@ public class BucketScriptTests extends ESIntegTestCase {
.interval(interval) .interval(interval)
.subAggregation(sum("field2Sum").field(FIELD_2_NAME)) .subAggregation(sum("field2Sum").field(FIELD_2_NAME))
.subAggregation( .subAggregation(
bucketScript("seriesArithmetic", new Script("_value0", ScriptType.INLINE, null, null), bucketScript("seriesArithmetic",
"field2Sum"))).execute().actionGet(); new Script("_value0", ScriptType.INLINE, CustomScriptPlugin.NAME, null),
"field2Sum")))
.execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -246,7 +294,8 @@ public class BucketScriptTests extends ESIntegTestCase {
.subAggregation(sum("field4Sum").field(FIELD_4_NAME)) .subAggregation(sum("field4Sum").field(FIELD_4_NAME))
.subAggregation( .subAggregation(
bucketScript("seriesArithmetic", bucketsPathsMap, bucketScript("seriesArithmetic", bucketsPathsMap,
new Script("foo + bar + baz", ScriptType.INLINE, null, null)))).execute().actionGet(); new Script("foo + bar + baz", ScriptType.INLINE, CustomScriptPlugin.NAME, null))))
.execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -281,6 +330,9 @@ public class BucketScriptTests extends ESIntegTestCase {
public void testInlineScriptWithParams() { public void testInlineScriptWithParams() {
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();
params.put("factor", 3); params.put("factor", 3);
Script script = new Script("(_value0 + _value1 + _value2) * factor", ScriptType.INLINE, CustomScriptPlugin.NAME, params);
SearchResponse response = client() SearchResponse response = client()
.prepareSearch("idx") .prepareSearch("idx")
.addAggregation( .addAggregation(
@ -290,9 +342,8 @@ public class BucketScriptTests extends ESIntegTestCase {
.subAggregation(sum("field2Sum").field(FIELD_2_NAME)) .subAggregation(sum("field2Sum").field(FIELD_2_NAME))
.subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(sum("field4Sum").field(FIELD_4_NAME)) .subAggregation(sum("field4Sum").field(FIELD_4_NAME))
.subAggregation( .subAggregation(bucketScript("seriesArithmetic", script, "field2Sum", "field3Sum", "field4Sum")))
bucketScript("seriesArithmetic", new Script("(_value0 + _value1 + _value2) * factor", ScriptType.INLINE, null, params), .execute().actionGet();
"field2Sum", "field3Sum", "field4Sum"))).execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -335,8 +386,10 @@ public class BucketScriptTests extends ESIntegTestCase {
.subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(sum("field4Sum").field(FIELD_4_NAME)) .subAggregation(sum("field4Sum").field(FIELD_4_NAME))
.subAggregation( .subAggregation(
bucketScript("seriesArithmetic", new Script("_value0 + _value1 + _value2", ScriptType.INLINE, null, null), bucketScript("seriesArithmetic",
"field2Sum", "field3Sum", "field4Sum").gapPolicy(GapPolicy.INSERT_ZEROS))).execute().actionGet(); new Script("_value0 + _value1 + _value2", ScriptType.INLINE, CustomScriptPlugin.NAME, null),
"field2Sum", "field3Sum", "field4Sum").gapPolicy(GapPolicy.INSERT_ZEROS)))
.execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -370,7 +423,13 @@ public class BucketScriptTests extends ESIntegTestCase {
} }
} }
public void testIndexedScript() { public void testStoredScript() {
assertAcked(client().admin().cluster().preparePutStoredScript()
.setId("my_script")
.setScriptLang(CustomScriptPlugin.NAME)
// Script source is not interpreted but it references a pre-defined script from CustomScriptPlugin
.setSource(new BytesArray("{ \"script\": \"my_script\" }")));
SearchResponse response = client() SearchResponse response = client()
.prepareSearch("idx") .prepareSearch("idx")
.addAggregation( .addAggregation(
@ -381,7 +440,8 @@ public class BucketScriptTests extends ESIntegTestCase {
.subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(sum("field4Sum").field(FIELD_4_NAME)) .subAggregation(sum("field4Sum").field(FIELD_4_NAME))
.subAggregation( .subAggregation(
bucketScript("seriesArithmetic", new Script("my_script", ScriptType.STORED, null, null), bucketScript("seriesArithmetic",
new Script("my_script", ScriptType.STORED, CustomScriptPlugin.NAME, null),
"field2Sum", "field3Sum", "field4Sum"))).execute().actionGet(); "field2Sum", "field3Sum", "field4Sum"))).execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -425,7 +485,8 @@ public class BucketScriptTests extends ESIntegTestCase {
.subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(sum("field4Sum").field(FIELD_4_NAME)) .subAggregation(sum("field4Sum").field(FIELD_4_NAME))
.subAggregation( .subAggregation(
bucketScript("seriesArithmetic", new Script("_value0 + _value1 + _value2", ScriptType.INLINE, null, null), bucketScript("seriesArithmetic",
new Script("_value0 + _value1 + _value2", ScriptType.INLINE, CustomScriptPlugin.NAME, null),
"field2Sum", "field3Sum", "field4Sum"))) "field2Sum", "field3Sum", "field4Sum")))
.execute().actionGet(); .execute().actionGet();
@ -448,7 +509,8 @@ public class BucketScriptTests extends ESIntegTestCase {
.subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(sum("field4Sum").field(FIELD_4_NAME)) .subAggregation(sum("field4Sum").field(FIELD_4_NAME))
.subAggregation( .subAggregation(
bucketScript("seriesArithmetic", new Script("_value0 + _value1 + _value2", ScriptType.INLINE, null, null), bucketScript("seriesArithmetic",
new Script("_value0 + _value1 + _value2", ScriptType.INLINE, CustomScriptPlugin.NAME, null),
"field2Sum", "field3Sum", "field4Sum"))).execute().actionGet(); "field2Sum", "field3Sum", "field4Sum"))).execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);

View File

@ -17,17 +17,16 @@
* under the License. * under the License.
*/ */
package org.elasticsearch.messy.tests; package org.elasticsearch.search.aggregations.pipeline;
import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService.ScriptType; import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.script.groovy.GroovyPlugin;
import org.elasticsearch.script.groovy.GroovyScriptEngineService;
import org.elasticsearch.search.aggregations.bucket.histogram.ExtendedBounds; import org.elasticsearch.search.aggregations.bucket.histogram.ExtendedBounds;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogram; import org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogram;
@ -43,12 +42,14 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram; import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum; import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilders.bucketSelector; import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilders.bucketSelector;
import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilders.derivative; import static org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilders.derivative;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.greaterThan;
@ -57,7 +58,7 @@ import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
@ESIntegTestCase.SuiteScopeTestCase @ESIntegTestCase.SuiteScopeTestCase
public class BucketSelectorTests extends ESIntegTestCase { public class BucketSelectorIT extends ESIntegTestCase {
private static final String FIELD_1_NAME = "field1"; private static final String FIELD_1_NAME = "field1";
private static final String FIELD_2_NAME = "field2"; private static final String FIELD_2_NAME = "field2";
@ -71,7 +72,69 @@ public class BucketSelectorTests extends ESIntegTestCase {
@Override @Override
protected Collection<Class<? extends Plugin>> nodePlugins() { protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class); return Collections.singleton(CustomScriptPlugin.class);
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)", vars -> {
double value0 = (double) vars.get("_value0");
double value1 = (double) vars.get("_value1");
return Double.isNaN(value0) ? false : (value0 + value1 > 100);
});
scripts.put("Double.isNaN(_value0) ? true : (_value0 < 10000)", vars -> {
double value0 = (double) vars.get("_value0");
return Double.isNaN(value0) ? true : (value0 < 10000);
});
scripts.put("Double.isNaN(_value0) ? false : (_value0 > 10000)", vars -> {
double value0 = (double) vars.get("_value0");
return Double.isNaN(value0) ? false : (value0 > 10000);
});
scripts.put("Double.isNaN(_value0) ? false : (_value0 < _value1)", vars -> {
double value0 = (double) vars.get("_value0");
double value1 = (double) vars.get("_value1");
return Double.isNaN(value0) ? false : (value0 < value1);
});
scripts.put("Double.isNaN(_value0) ? false : (_value0 > 100)", vars -> {
double value0 = (double) vars.get("_value0");
return Double.isNaN(value0) ? false : (value0 > 10000);
});
scripts.put("Double.isNaN(my_value1) ? false : (my_value1 + my_value2 > 100)", vars -> {
double myValue1 = (double) vars.get("my_value1");
double myValue2 = (double) vars.get("my_value2");
return Double.isNaN(myValue1) ? false : (myValue1 + myValue2 > 100);
});
scripts.put("Double.isNaN(_value0) ? false : (_value0 + _value1 > threshold)", vars -> {
double value0 = (double) vars.get("_value0");
double value1 = (double) vars.get("_value1");
int threshold = (int) vars.get("threshold");
return Double.isNaN(value0) ? false : (value0 + value1 > threshold);
});
scripts.put("_value0 + _value1 > 100", vars -> {
double value0 = (double) vars.get("_value0");
double value1 = (double) vars.get("_value1");
return (value0 + value1 > 100);
});
scripts.put("my_script", vars -> {
double value0 = (double) vars.get("_value0");
double value1 = (double) vars.get("_value1");
return Double.isNaN(value0) ? false : (value0 + value1 > 100);
});
return scripts;
}
} }
@Override @Override
@ -94,9 +157,6 @@ public class BucketSelectorTests extends ESIntegTestCase {
builders.add(client().prepareIndex("idx_with_gaps", "type").setSource(newDocBuilder(3, 1, 0, 0))); builders.add(client().prepareIndex("idx_with_gaps", "type").setSource(newDocBuilder(3, 1, 0, 0)));
builders.add(client().prepareIndex("idx_with_gaps", "type").setSource(newDocBuilder(3, 3, 0, 0))); builders.add(client().prepareIndex("idx_with_gaps", "type").setSource(newDocBuilder(3, 3, 0, 0)));
client().admin().cluster().preparePutStoredScript().setId("my_script").setScriptLang(GroovyScriptEngineService.NAME)
.setSource(new BytesArray("{ \"script\": \"Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)\" }")).get();
indexRandom(true, builders); indexRandom(true, builders);
ensureSearchable(); ensureSearchable();
} }
@ -118,12 +178,13 @@ public class BucketSelectorTests extends ESIntegTestCase {
} }
public void testInlineScript() { public void testInlineScript() {
Script script =
new Script("Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client().prepareSearch("idx") SearchResponse response = client().prepareSearch("idx")
.addAggregation(histogram("histo").field(FIELD_1_NAME).interval(interval) .addAggregation(histogram("histo").field(FIELD_1_NAME).interval(interval)
.subAggregation(sum("field2Sum").field(FIELD_2_NAME)).subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field2Sum").field(FIELD_2_NAME)).subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(bucketSelector("bucketSelector", .subAggregation(bucketSelector("bucketSelector", script, "field2Sum", "field3Sum")))
new Script("Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)", ScriptType.INLINE, null, null),
"field2Sum", "field3Sum")))
.execute().actionGet(); .execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -146,6 +207,8 @@ public class BucketSelectorTests extends ESIntegTestCase {
} }
public void testInlineScriptNoBucketsPruned() { public void testInlineScriptNoBucketsPruned() {
Script script = new Script("Double.isNaN(_value0) ? true : (_value0 < 10000)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client() SearchResponse response = client()
.prepareSearch("idx") .prepareSearch("idx")
.addAggregation( .addAggregation(
@ -154,10 +217,8 @@ public class BucketSelectorTests extends ESIntegTestCase {
.interval(interval) .interval(interval)
.subAggregation(sum("field2Sum").field(FIELD_2_NAME)) .subAggregation(sum("field2Sum").field(FIELD_2_NAME))
.subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation( .subAggregation(bucketSelector("bucketSelector", script, "field2Sum", "field3Sum")))
bucketSelector("bucketSelector", new Script("Double.isNaN(_value0) ? true : (_value0 < 10000)", .execute().actionGet();
ScriptType.INLINE, null, null), "field2Sum", "field3Sum"))).execute()
.actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -179,6 +240,8 @@ public class BucketSelectorTests extends ESIntegTestCase {
} }
public void testInlineScriptNoBucketsLeft() { public void testInlineScriptNoBucketsLeft() {
Script script = new Script("Double.isNaN(_value0) ? false : (_value0 > 10000)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client() SearchResponse response = client()
.prepareSearch("idx") .prepareSearch("idx")
.addAggregation( .addAggregation(
@ -187,9 +250,8 @@ public class BucketSelectorTests extends ESIntegTestCase {
.interval(interval) .interval(interval)
.subAggregation(sum("field2Sum").field(FIELD_2_NAME)) .subAggregation(sum("field2Sum").field(FIELD_2_NAME))
.subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation( .subAggregation(bucketSelector("bucketSelector", script, "field2Sum", "field3Sum")))
bucketSelector("bucketSelector", new Script("Double.isNaN(_value0) ? false : (_value0 > 10000)", .execute().actionGet();
ScriptType.INLINE, null, null), "field2Sum", "field3Sum"))).execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -201,6 +263,8 @@ public class BucketSelectorTests extends ESIntegTestCase {
} }
public void testInlineScript2() { public void testInlineScript2() {
Script script = new Script("Double.isNaN(_value0) ? false : (_value0 < _value1)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client() SearchResponse response = client()
.prepareSearch("idx") .prepareSearch("idx")
.addAggregation( .addAggregation(
@ -209,9 +273,8 @@ public class BucketSelectorTests extends ESIntegTestCase {
.interval(interval) .interval(interval)
.subAggregation(sum("field2Sum").field(FIELD_2_NAME)) .subAggregation(sum("field2Sum").field(FIELD_2_NAME))
.subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation( .subAggregation(bucketSelector("bucketSelector", script, "field2Sum", "field3Sum")))
bucketSelector("bucketSelector", new Script("Double.isNaN(_value0) ? false : (_value0 < _value1)", .execute().actionGet();
ScriptType.INLINE, null, null), "field2Sum", "field3Sum"))).execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -233,6 +296,8 @@ public class BucketSelectorTests extends ESIntegTestCase {
} }
public void testInlineScriptSingleVariable() { public void testInlineScriptSingleVariable() {
Script script = new Script("Double.isNaN(_value0) ? false : (_value0 > 100)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client() SearchResponse response = client()
.prepareSearch("idx") .prepareSearch("idx")
.addAggregation( .addAggregation(
@ -240,9 +305,8 @@ public class BucketSelectorTests extends ESIntegTestCase {
.field(FIELD_1_NAME) .field(FIELD_1_NAME)
.interval(interval) .interval(interval)
.subAggregation(sum("field2Sum").field(FIELD_2_NAME)) .subAggregation(sum("field2Sum").field(FIELD_2_NAME))
.subAggregation( .subAggregation(bucketSelector("bucketSelector", script, "field2Sum")))
bucketSelector("bucketSelector", new Script("Double.isNaN(_value0) ? false : (_value0 > 100)", .execute().actionGet();
ScriptType.INLINE,null, null), "field2Sum"))).execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -261,15 +325,21 @@ public class BucketSelectorTests extends ESIntegTestCase {
} }
public void testInlineScriptNamedVars() { public void testInlineScriptNamedVars() {
Script script = new Script("Double.isNaN(my_value1) ? false : (my_value1 + my_value2 > 100)", ScriptType.INLINE,
CustomScriptPlugin.NAME, null);
Map<String, String> bucketPathsMap = new HashMap<>(); Map<String, String> bucketPathsMap = new HashMap<>();
bucketPathsMap.put("my_value1", "field2Sum"); bucketPathsMap.put("my_value1", "field2Sum");
bucketPathsMap.put("my_value2", "field3Sum"); bucketPathsMap.put("my_value2", "field3Sum");
SearchResponse response = client().prepareSearch("idx") SearchResponse response = client().prepareSearch("idx")
.addAggregation(histogram("histo").field(FIELD_1_NAME).interval(interval) .addAggregation(
.subAggregation(sum("field2Sum").field(FIELD_2_NAME)).subAggregation(sum("field3Sum").field(FIELD_3_NAME)) histogram("histo")
.subAggregation(bucketSelector("bucketSelector", bucketPathsMap, new Script( .field(FIELD_1_NAME)
"Double.isNaN(my_value1) ? false : (my_value1 + my_value2 > 100)", ScriptType.INLINE, null, null)))) .interval(interval)
.subAggregation(sum("field2Sum").field(FIELD_2_NAME))
.subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(bucketSelector("bucketSelector", bucketPathsMap, script)))
.execute().actionGet(); .execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -292,13 +362,17 @@ public class BucketSelectorTests extends ESIntegTestCase {
} }
public void testInlineScriptWithParams() { public void testInlineScriptWithParams() {
Map<String, Object> params = new HashMap<>(); Script script = new Script("Double.isNaN(_value0) ? false : (_value0 + _value1 > threshold)", ScriptType.INLINE,
params.put("threshold", 100); CustomScriptPlugin.NAME, Collections.singletonMap("threshold", 100));
SearchResponse response = client().prepareSearch("idx").addAggregation(histogram("histo").field(FIELD_1_NAME).interval(interval)
.subAggregation(sum("field2Sum").field(FIELD_2_NAME)).subAggregation(sum("field3Sum").field(FIELD_3_NAME)) SearchResponse response = client().prepareSearch("idx")
.subAggregation(bucketSelector("bucketSelector", .addAggregation(
new Script("Double.isNaN(_value0) ? false : (_value0 + _value1 > threshold)", ScriptType.INLINE, null, params), histogram("histo")
"field2Sum", "field3Sum"))) .field(FIELD_1_NAME)
.interval(interval)
.subAggregation(sum("field2Sum").field(FIELD_2_NAME))
.subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(bucketSelector("bucketSelector", script, "field2Sum", "field3Sum")))
.execute().actionGet(); .execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -321,12 +395,16 @@ public class BucketSelectorTests extends ESIntegTestCase {
} }
public void testInlineScriptInsertZeros() { public void testInlineScriptInsertZeros() {
Script script = new Script("_value0 + _value1 > 100", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client().prepareSearch("idx") SearchResponse response = client().prepareSearch("idx")
.addAggregation( .addAggregation(
histogram("histo").field(FIELD_1_NAME).interval(interval).subAggregation(sum("field2Sum").field(FIELD_2_NAME)) histogram("histo")
.field(FIELD_1_NAME)
.interval(interval)
.subAggregation(sum("field2Sum").field(FIELD_2_NAME))
.subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(bucketSelector("bucketSelector", .subAggregation(bucketSelector("bucketSelector", script , "field2Sum", "field3Sum")
new Script("_value0 + _value1 > 100", ScriptType.INLINE, null, null), "field2Sum", "field3Sum")
.gapPolicy(GapPolicy.INSERT_ZEROS))) .gapPolicy(GapPolicy.INSERT_ZEROS)))
.execute().actionGet(); .execute().actionGet();
@ -349,7 +427,15 @@ public class BucketSelectorTests extends ESIntegTestCase {
} }
} }
public void testIndexedScript() { public void testStoredScript() {
assertAcked(client().admin().cluster().preparePutStoredScript()
.setId("my_script")
.setScriptLang(CustomScriptPlugin.NAME)
// Source is not interpreted but my_script is defined in CustomScriptPlugin
.setSource(new BytesArray("{ \"script\": \"Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)\" }")));
Script script = new Script("my_script", ScriptType.STORED, CustomScriptPlugin.NAME, null);
SearchResponse response = client() SearchResponse response = client()
.prepareSearch("idx") .prepareSearch("idx")
.addAggregation( .addAggregation(
@ -358,9 +444,8 @@ public class BucketSelectorTests extends ESIntegTestCase {
.interval(interval) .interval(interval)
.subAggregation(sum("field2Sum").field(FIELD_2_NAME)) .subAggregation(sum("field2Sum").field(FIELD_2_NAME))
.subAggregation(sum("field3Sum").field(FIELD_3_NAME)) .subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation( .subAggregation(bucketSelector("bucketSelector", script, "field2Sum", "field3Sum")))
bucketSelector("bucketSelector", new Script("my_script", ScriptType.STORED, null, null), .execute().actionGet();
"field2Sum", "field3Sum"))).execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -382,12 +467,17 @@ public class BucketSelectorTests extends ESIntegTestCase {
} }
public void testUnmapped() throws Exception { public void testUnmapped() throws Exception {
Script script = new Script("Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)", ScriptType.INLINE,
CustomScriptPlugin.NAME, null);
SearchResponse response = client().prepareSearch("idx_unmapped") SearchResponse response = client().prepareSearch("idx_unmapped")
.addAggregation(histogram("histo").field(FIELD_1_NAME).interval(interval) .addAggregation(
.subAggregation(sum("field2Sum").field(FIELD_2_NAME)).subAggregation(sum("field3Sum").field(FIELD_3_NAME)) histogram("histo")
.subAggregation(bucketSelector("bucketSelector", .field(FIELD_1_NAME)
new Script("Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)", ScriptType.INLINE, null, null), .interval(interval)
"field2Sum", "field3Sum"))) .subAggregation(sum("field2Sum").field(FIELD_2_NAME))
.subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(bucketSelector("bucketSelector", script, "field2Sum", "field3Sum")))
.execute().actionGet(); .execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -399,12 +489,17 @@ public class BucketSelectorTests extends ESIntegTestCase {
} }
public void testPartiallyUnmapped() throws Exception { public void testPartiallyUnmapped() throws Exception {
Script script = new Script("Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)", ScriptType.INLINE,
CustomScriptPlugin.NAME, null);
SearchResponse response = client().prepareSearch("idx", "idx_unmapped") SearchResponse response = client().prepareSearch("idx", "idx_unmapped")
.addAggregation(histogram("histo").field(FIELD_1_NAME).interval(interval) .addAggregation(
.subAggregation(sum("field2Sum").field(FIELD_2_NAME)).subAggregation(sum("field3Sum").field(FIELD_3_NAME)) histogram("histo")
.subAggregation(bucketSelector("bucketSelector", .field(FIELD_1_NAME)
new Script("Double.isNaN(_value0) ? false : (_value0 + _value1 > 100)", ScriptType.INLINE, null, null), .interval(interval)
"field2Sum", "field3Sum"))) .subAggregation(sum("field2Sum").field(FIELD_2_NAME))
.subAggregation(sum("field3Sum").field(FIELD_3_NAME))
.subAggregation(bucketSelector("bucketSelector", script, "field2Sum", "field3Sum")))
.execute().actionGet(); .execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);
@ -428,9 +523,18 @@ public class BucketSelectorTests extends ESIntegTestCase {
public void testEmptyBuckets() { public void testEmptyBuckets() {
SearchResponse response = client().prepareSearch("idx_with_gaps") SearchResponse response = client().prepareSearch("idx_with_gaps")
.addAggregation(histogram("histo").field(FIELD_1_NAME).interval(1) .addAggregation(
.subAggregation(histogram("inner_histo").field(FIELD_1_NAME).interval(1).extendedBounds(new ExtendedBounds(1L, 4L)) histogram("histo")
.minDocCount(0).subAggregation(derivative("derivative", "_count").gapPolicy(GapPolicy.INSERT_ZEROS)))) .field(FIELD_1_NAME)
.interval(1)
.subAggregation(
histogram("inner_histo")
.field(FIELD_1_NAME)
.interval(1)
.extendedBounds(new ExtendedBounds(1L, 4L))
.minDocCount(0)
.subAggregation(derivative("derivative", "_count")
.gapPolicy(GapPolicy.INSERT_ZEROS))))
.execute().actionGet(); .execute().actionGet();
assertSearchResponse(response); assertSearchResponse(response);

View File

@ -31,6 +31,7 @@ import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.InnerHitBuilder; import org.elasticsearch.index.query.InnerHitBuilder;
import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptEngine; import org.elasticsearch.script.MockScriptEngine;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHit;
@ -47,6 +48,8 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.function.Function;
import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
@ -71,9 +74,17 @@ import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
public class InnerHitsIT extends ESIntegTestCase { public class InnerHitsIT extends ESIntegTestCase {
@Override @Override
protected Collection<Class<? extends Plugin>> nodePlugins() { protected Collection<Class<? extends Plugin>> nodePlugins() {
return pluginList(MockScriptEngine.TestPlugin.class); return Collections.singleton(CustomScriptPlugin.class);
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
return Collections.emptyMap();
}
} }
public void testSimpleNested() throws Exception { public void testSimpleNested() throws Exception {

View File

@ -36,8 +36,6 @@
*/ */
/* List of renames that took place: /* List of renames that took place:
renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/AvgIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/AvgTests.java renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/AvgIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/AvgTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketScriptIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BucketScriptTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketSelectorIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BucketSelectorTests.java
renamed: core/src/test/java/org/elasticsearch/document/BulkIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BulkTests.java renamed: core/src/test/java/org/elasticsearch/document/BulkIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BulkTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/CardinalityIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/CardinalityTests.java renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/CardinalityIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/CardinalityTests.java
renamed: core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ChildQuerySearchTests.java renamed: core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ChildQuerySearchTests.java
@ -50,8 +48,6 @@
renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/ExtendedStatsIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ExtendedStatsTests.java renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/ExtendedStatsIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ExtendedStatsTests.java
renamed: core/src/test/java/org/elasticsearch/search/functionscore/FunctionScoreIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/FunctionScoreTests.java renamed: core/src/test/java/org/elasticsearch/search/functionscore/FunctionScoreIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/FunctionScoreTests.java
renamed: core/src/test/java/org/elasticsearch/search/geo/GeoDistanceIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/GeoDistanceTests.java renamed: core/src/test/java/org/elasticsearch/search/geo/GeoDistanceIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/GeoDistanceTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/HDRPercentileRanksIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/HDRPercentileRanksTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/HDRPercentilesIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/HDRPercentilesTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/bucket/HistogramIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/HistogramTests.java renamed: core/src/test/java/org/elasticsearch/search/aggregations/bucket/HistogramIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/HistogramTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/bucket/IPv4RangeIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/IPv4RangeTests.java renamed: core/src/test/java/org/elasticsearch/search/aggregations/bucket/IPv4RangeIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/IPv4RangeTests.java
renamed: core/src/test/java/org/elasticsearch/script/IndexLookupIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/IndexLookupTests.java renamed: core/src/test/java/org/elasticsearch/script/IndexLookupIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/IndexLookupTests.java

View File

@ -22,92 +22,60 @@ package org.elasticsearch.script;
import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.LeafReaderContext;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.search.lookup.LeafSearchLookup;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.plugins.ScriptPlugin;
import org.elasticsearch.search.lookup.SearchLookup; import org.elasticsearch.search.lookup.SearchLookup;
import java.io.IOException; import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
/** /**
* A dummy script engine used for testing. Scripts must be a number. Many * A mocked script engine that can be used for testing purpose.
* tests rely on the fact this thing returns a String as its compiled form.
* they even try to serialize it over the network!
*/ */
public class MockScriptEngine implements ScriptEngineService { public class MockScriptEngine implements ScriptEngineService {
public static final String NAME = "mockscript"; public static final String NAME = "mockscript";
/** A compiled script, just holds the scripts name, source, and params that were passed in */ private final String type;
public static class MockCompiledScript { private final Map<String, Function<Map<String, Object>, Object>> scripts;
public final String name;
public final String source;
public final Map<String,String> params;
MockCompiledScript(String name, String source, Map<String,String> params) { public MockScriptEngine(String type, Map<String, Function<Map<String, Object>, Object>> scripts) {
this.name = name; this.type = type;
this.source = source; this.scripts = Collections.unmodifiableMap(scripts);
this.params = params;
}
} }
public static class TestPlugin extends Plugin implements ScriptPlugin { public MockScriptEngine() {
@Override this(NAME, Collections.emptyMap());
public ScriptEngineService getScriptEngineService(Settings settings) {
return new MockScriptEngine();
}
} }
@Override @Override
public String getType() { public String getType() {
return NAME; return type;
} }
@Override @Override
public String getExtension() { public String getExtension() {
return NAME; return getType();
} }
@Override @Override
public Object compile(String scriptName, String scriptSource, Map<String, String> params) { public Object compile(String name, String source, Map<String, String> params) {
return new MockCompiledScript(scriptName, scriptSource, params); Function<Map<String, Object>, Object> script = scripts.get(source);
return new MockCompiledScript(name, params, source, script);
} }
@Override @Override
public ExecutableScript executable(CompiledScript compiledScript, @Nullable Map<String, Object> vars) { public ExecutableScript executable(CompiledScript compiledScript, @Nullable Map<String, Object> vars) {
assert compiledScript.compiled() instanceof MockCompiledScript MockCompiledScript compiled = (MockCompiledScript) compiledScript.compiled();
: "do NOT pass compiled scripts from other engines to me, I will fail your test, got: " + compiledScript; return compiled.createExecutableScript(vars);
return new AbstractExecutableScript() {
@Override
public Object run() {
return new BytesArray(((MockCompiledScript)compiledScript.compiled()).source);
}
};
} }
@Override @Override
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) { public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) {
return new SearchScript() { MockCompiledScript compiled = (MockCompiledScript) compiledScript.compiled();
@Override return compiled.createSearchScript(vars, lookup);
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
AbstractSearchScript leafSearchScript = new AbstractSearchScript() {
@Override
public Object run() {
return ((MockCompiledScript)compiledScript.compiled()).source;
}
};
leafSearchScript.setLookup(lookup.getLeafSearchLookup(context));
return leafSearchScript;
}
@Override
public boolean needsScores() {
return false;
}
};
} }
@Override @Override
@ -118,4 +86,111 @@ public class MockScriptEngine implements ScriptEngineService {
public boolean isInlineScriptEnabled() { public boolean isInlineScriptEnabled() {
return true; return true;
} }
public class MockCompiledScript {
private final String name;
private final String source;
private final Map<String, String> params;
private final Function<Map<String, Object>, Object> script;
public MockCompiledScript(String name, Map<String, String> params, String source, Function<Map<String, Object>, Object> script) {
this.name = name;
this.source = source;
this.params = params;
this.script = script;
}
public String getName() {
return name;
}
public ExecutableScript createExecutableScript(Map<String, Object> vars) {
Map<String, Object> context = new HashMap<>();
if (params != null) {
context.putAll(params);
}
if (vars != null) {
context.putAll(vars);
}
return new MockExecutableScript(context, script != null ? script : ctx -> new BytesArray(source));
}
public SearchScript createSearchScript(Map<String, Object> vars, SearchLookup lookup) {
Map<String, Object> context = new HashMap<>();
if (params != null) {
context.putAll(params);
}
if (vars != null) {
context.putAll(vars);
}
return new MockSearchScript(lookup, context, script != null ? script : ctx -> source);
}
}
public class MockExecutableScript implements ExecutableScript {
private final Function<Map<String, Object>, Object> script;
private final Map<String, Object> vars;
public MockExecutableScript(Map<String, Object> vars, Function<Map<String, Object>, Object> script) {
this.vars = vars;
this.script = script;
}
@Override
public void setNextVar(String name, Object value) {
vars.put(name, value);
}
@Override
public Object run() {
return script.apply(vars);
}
}
public class MockSearchScript implements SearchScript {
private final Function<Map<String, Object>, Object> script;
private final Map<String, Object> vars;
private final SearchLookup lookup;
public MockSearchScript(SearchLookup lookup, Map<String, Object> vars, Function<Map<String, Object>, Object> script) {
this.lookup = lookup;
this.vars = vars;
this.script = script;
}
@Override
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
Map<String, Object> ctx = new HashMap<>();
ctx.putAll(leafLookup.asMap());
if (vars != null) {
ctx.putAll(vars);
}
AbstractSearchScript leafSearchScript = new AbstractSearchScript() {
@Override
public Object run() {
return script.apply(ctx);
}
@Override
public void setNextVar(String name, Object value) {
ctx.put(name, value);
}
};
leafSearchScript.setLookup(leafLookup);
return leafSearchScript;
}
@Override
public boolean needsScores() {
return false;
}
}
} }

View File

@ -0,0 +1,46 @@
/*
* 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.script;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.plugins.ScriptPlugin;
import java.util.Map;
import java.util.function.Function;
/**
* A script plugin that uses {@link MockScriptEngine} as the script engine for tests.
*/
public abstract class MockScriptPlugin extends Plugin implements ScriptPlugin {
public static final String NAME = MockScriptEngine.NAME;
@Override
public ScriptEngineService getScriptEngineService(Settings settings) {
return new MockScriptEngine(pluginScriptLang(), pluginScripts());
}
protected abstract Map<String, Function<Map<String, Object>, Object>> pluginScripts();
public String pluginScriptLang() {
return NAME;
}
}