|
|
@@ -36,16 +36,24 @@ import org.elasticsearch.test.ESTestCase;
|
|
|
import org.junit.Before;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
+import java.util.Collection;
|
|
|
import java.util.Collections;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.HashSet;
|
|
|
+import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
import java.util.function.Function;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
import static org.elasticsearch.script.ScriptService.MAX_COMPILATION_RATE_FUNCTION;
|
|
|
+import static org.elasticsearch.script.ScriptService.SCRIPT_CACHE_EXPIRE_SETTING;
|
|
|
+import static org.elasticsearch.script.ScriptService.SCRIPT_CACHE_SIZE_SETTING;
|
|
|
+import static org.elasticsearch.script.ScriptService.SCRIPT_GENERAL_CACHE_EXPIRE_SETTING;
|
|
|
+import static org.elasticsearch.script.ScriptService.SCRIPT_GENERAL_CACHE_SIZE_SETTING;
|
|
|
import static org.elasticsearch.script.ScriptService.SCRIPT_GENERAL_MAX_COMPILATIONS_RATE_SETTING;
|
|
|
import static org.elasticsearch.script.ScriptService.SCRIPT_MAX_COMPILATIONS_RATE_SETTING;
|
|
|
+import static org.elasticsearch.script.ScriptService.USE_CONTEXT_RATE_KEY;
|
|
|
import static org.hamcrest.CoreMatchers.containsString;
|
|
|
import static org.hamcrest.Matchers.is;
|
|
|
import static org.hamcrest.Matchers.notNullValue;
|
|
|
@@ -226,7 +234,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|
|
|
|
|
public void testCompilationStatsOnCacheHit() throws IOException {
|
|
|
Settings.Builder builder = Settings.builder();
|
|
|
- builder.put(ScriptService.SCRIPT_GENERAL_CACHE_SIZE_SETTING.getKey(), 1);
|
|
|
+ builder.put(SCRIPT_GENERAL_CACHE_SIZE_SETTING.getKey(), 1);
|
|
|
buildScriptService(builder.build());
|
|
|
Script script = new Script(ScriptType.INLINE, "test", "1+1", Collections.emptyMap());
|
|
|
ScriptContext<?> context = randomFrom(contexts.values());
|
|
|
@@ -243,7 +251,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|
|
|
|
|
public void testCacheEvictionCountedInCacheEvictionsStats() throws IOException {
|
|
|
Settings.Builder builder = Settings.builder();
|
|
|
- builder.put(ScriptService.SCRIPT_GENERAL_CACHE_SIZE_SETTING.getKey(), 1);
|
|
|
+ builder.put(SCRIPT_GENERAL_CACHE_SIZE_SETTING.getKey(), 1);
|
|
|
buildScriptService(builder.build());
|
|
|
scriptService.compile(new Script(ScriptType.INLINE, "test", "1+1", Collections.emptyMap()), randomFrom(contexts.values()));
|
|
|
scriptService.compile(new Script(ScriptType.INLINE, "test", "2+2", Collections.emptyMap()), randomFrom(contexts.values()));
|
|
|
@@ -361,7 +369,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|
|
TimeValue cacheExpireFooParsed = TimeValue.parseTimeValue(cacheExpireFoo, "");
|
|
|
|
|
|
Settings s = Settings.builder()
|
|
|
- .put(ScriptService.SCRIPT_GENERAL_CACHE_SIZE_SETTING.getKey(), cacheSizeBackup)
|
|
|
+ .put(SCRIPT_GENERAL_CACHE_SIZE_SETTING.getKey(), cacheSizeBackup)
|
|
|
.put(ScriptService.SCRIPT_CACHE_SIZE_SETTING.getConcreteSettingForNamespace("foo").getKey(), cacheSizeFoo)
|
|
|
.put(ScriptService.SCRIPT_GENERAL_CACHE_EXPIRE_SETTING.getKey(), cacheExpireBackup)
|
|
|
.put(ScriptService.SCRIPT_CACHE_EXPIRE_SETTING.getConcreteSettingForNamespace("foo").getKey(), cacheExpireFoo)
|
|
|
@@ -396,7 +404,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|
|
boolean compilationLimitsEnabled = true;
|
|
|
ScriptService.CacheHolder holder = new ScriptService.CacheHolder(
|
|
|
Settings.builder().put(SCRIPT_GENERAL_MAX_COMPILATIONS_RATE_SETTING.getKey(), compilationRate).build(),
|
|
|
- new HashSet<>(Collections.singleton("foo")),
|
|
|
+ Set.of(newContext("foo")),
|
|
|
compilationLimitsEnabled
|
|
|
);
|
|
|
|
|
|
@@ -407,7 +415,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|
|
compilationLimitsEnabled = false;
|
|
|
holder = new ScriptService.CacheHolder(
|
|
|
Settings.builder().put(SCRIPT_GENERAL_MAX_COMPILATIONS_RATE_SETTING.getKey(), compilationRate).build(),
|
|
|
- new HashSet<>(Collections.singleton("foo")),
|
|
|
+ new HashSet<>(Collections.singleton(newContext("foo"))),
|
|
|
compilationLimitsEnabled
|
|
|
);
|
|
|
|
|
|
@@ -426,13 +434,13 @@ public class ScriptServiceTests extends ESTestCase {
|
|
|
.put(SCRIPT_MAX_COMPILATIONS_RATE_SETTING.getConcreteSettingForNamespace("foo").getKey(), fooCompilationRate)
|
|
|
.put(SCRIPT_MAX_COMPILATIONS_RATE_SETTING.getConcreteSettingForNamespace("bar").getKey(), barCompilationRate)
|
|
|
.build();
|
|
|
- Set<String> contexts = Set.of("foo", "bar", "baz");
|
|
|
+ Collection<ScriptContext<?>> contexts = Set.of(newContext("foo"), newContext("bar"), newContext("baz"));
|
|
|
ScriptService.CacheHolder holder = new ScriptService.CacheHolder(s, contexts, compilationLimitsEnabled);
|
|
|
|
|
|
assertNull(holder.general);
|
|
|
assertNotNull(holder.contextCache);
|
|
|
assertEquals(3, holder.contextCache.size());
|
|
|
- assertEquals(contexts, holder.contextCache.keySet());
|
|
|
+ assertEquals(contexts.stream().map(c -> c.name).collect(Collectors.toSet()), holder.contextCache.keySet());
|
|
|
|
|
|
assertEquals(ScriptService.MAX_COMPILATION_RATE_FUNCTION.apply(fooCompilationRate), holder.contextCache.get("foo").get().rate);
|
|
|
assertEquals(ScriptService.MAX_COMPILATION_RATE_FUNCTION.apply(barCompilationRate), holder.contextCache.get("bar").get().rate);
|
|
|
@@ -477,7 +485,8 @@ public class ScriptServiceTests extends ESTestCase {
|
|
|
Settings s = Settings.builder()
|
|
|
.put(SCRIPT_GENERAL_MAX_COMPILATIONS_RATE_SETTING.getKey(), compilationRate)
|
|
|
.build();
|
|
|
- Set<String> contexts = Set.of("foo", "bar", "baz", "qux");
|
|
|
+ Collection<ScriptContext<?>> contexts = Set.of(newContext("foo"), newContext("bar"), newContext("baz"),
|
|
|
+ newContext("qux"));
|
|
|
ScriptService.CacheHolder holder = new ScriptService.CacheHolder(s, contexts, true);
|
|
|
|
|
|
assertNotNull(holder.general);
|
|
|
@@ -496,7 +505,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|
|
assertNull(holder.general);
|
|
|
assertNotNull(holder.contextCache);
|
|
|
assertEquals(4, holder.contextCache.size());
|
|
|
- assertEquals(contexts, holder.contextCache.keySet());
|
|
|
+ assertEquals(contexts.stream().map(c -> c.name).collect(Collectors.toSet()), holder.contextCache.keySet());
|
|
|
|
|
|
assertEquals(ScriptService.MAX_COMPILATION_RATE_FUNCTION.apply(fooCompilationRate), holder.contextCache.get("foo").get().rate);
|
|
|
assertEquals(ScriptService.MAX_COMPILATION_RATE_FUNCTION.apply(barCompilationRate), holder.contextCache.get("bar").get().rate);
|
|
|
@@ -506,7 +515,7 @@ public class ScriptServiceTests extends ESTestCase {
|
|
|
|
|
|
holder.updateContextSettings(Settings.builder()
|
|
|
.put(SCRIPT_MAX_COMPILATIONS_RATE_SETTING.getConcreteSettingForNamespace("bar").getKey(), fooCompilationRate).build(),
|
|
|
- "bar"
|
|
|
+ newContext("bar")
|
|
|
);
|
|
|
assertEquals(ScriptService.MAX_COMPILATION_RATE_FUNCTION.apply(fooCompilationRate), holder.contextCache.get("bar").get().rate);
|
|
|
|
|
|
@@ -529,6 +538,93 @@ public class ScriptServiceTests extends ESTestCase {
|
|
|
assertSame(holder, update);
|
|
|
}
|
|
|
|
|
|
+ public void testFallbackToContextDefaults() {
|
|
|
+ Tuple<Integer, TimeValue> contextDefaultRate = new Tuple<>(randomIntBetween(10, 1024),
|
|
|
+ TimeValue.timeValueMinutes(randomIntBetween(10, 200)));
|
|
|
+ String name = "foo";
|
|
|
+ ScriptContext<?> foo = new ScriptContext<>(name,
|
|
|
+ ScriptContextTests.DummyScript.Factory.class,
|
|
|
+ randomIntBetween(1, 1024),
|
|
|
+ TimeValue.timeValueMinutes(randomIntBetween(10, 200)),
|
|
|
+ contextDefaultRate);
|
|
|
+
|
|
|
+
|
|
|
+ int generalCacheSize = randomIntBetween(1, 1024);
|
|
|
+ TimeValue generalExpire = TimeValue.timeValueMinutes(randomIntBetween(10, 200));
|
|
|
+
|
|
|
+ String contextRateStr = randomIntBetween(10, 1024) + "/" + randomIntBetween(10, 200) + "m";
|
|
|
+ Tuple<Integer, TimeValue> contextRate = MAX_COMPILATION_RATE_FUNCTION.apply(contextRateStr);
|
|
|
+ int contextCacheSize = randomIntBetween(1, 1024);
|
|
|
+ TimeValue contextExpire = TimeValue.timeValueMinutes(randomIntBetween(10, 200));
|
|
|
+
|
|
|
+ // Use context specific
|
|
|
+ ScriptService.CacheHolder contextCache = new ScriptService.CacheHolder(
|
|
|
+ Settings.builder()
|
|
|
+ .put(SCRIPT_CACHE_SIZE_SETTING.getConcreteSettingForNamespace(name).getKey(), contextCacheSize)
|
|
|
+ .put(SCRIPT_CACHE_EXPIRE_SETTING.getConcreteSettingForNamespace(name).getKey(), contextExpire)
|
|
|
+ .put(SCRIPT_MAX_COMPILATIONS_RATE_SETTING.getConcreteSettingForNamespace(name).getKey(), contextRateStr)
|
|
|
+ .put(SCRIPT_GENERAL_CACHE_SIZE_SETTING.getKey(), generalCacheSize)
|
|
|
+ .put(SCRIPT_GENERAL_CACHE_EXPIRE_SETTING.getKey(), generalExpire)
|
|
|
+ .put(SCRIPT_GENERAL_MAX_COMPILATIONS_RATE_SETTING.getKey(), USE_CONTEXT_RATE_KEY)
|
|
|
+ .build(),
|
|
|
+ List.of(foo),
|
|
|
+ true);
|
|
|
+
|
|
|
+ assertNotNull(contextCache.contextCache);
|
|
|
+ assertNotNull(contextCache.contextCache.get(name));
|
|
|
+ assertNotNull(contextCache.contextCache.get(name).get());
|
|
|
+
|
|
|
+ assertEquals(contextRate, contextCache.contextCache.get(name).get().rate);
|
|
|
+ assertEquals(contextCacheSize, contextCache.contextCache.get(name).get().cacheSize);
|
|
|
+ assertEquals(contextExpire, contextCache.contextCache.get(name).get().cacheExpire);
|
|
|
+
|
|
|
+ // Fallback to general
|
|
|
+ contextCache = new ScriptService.CacheHolder(
|
|
|
+ Settings.builder()
|
|
|
+ .put(SCRIPT_GENERAL_CACHE_SIZE_SETTING.getKey(), generalCacheSize)
|
|
|
+ .put(SCRIPT_GENERAL_CACHE_EXPIRE_SETTING.getKey(), generalExpire)
|
|
|
+ .put(SCRIPT_GENERAL_MAX_COMPILATIONS_RATE_SETTING.getKey(), USE_CONTEXT_RATE_KEY)
|
|
|
+ .build(),
|
|
|
+ List.of(foo),
|
|
|
+ true);
|
|
|
+
|
|
|
+ assertNotNull(contextCache.contextCache);
|
|
|
+ assertNotNull(contextCache.contextCache.get(name));
|
|
|
+ assertNotNull(contextCache.contextCache.get(name).get());
|
|
|
+
|
|
|
+ assertEquals(contextDefaultRate, contextCache.contextCache.get(name).get().rate);
|
|
|
+ assertEquals(generalCacheSize, contextCache.contextCache.get(name).get().cacheSize);
|
|
|
+ assertEquals(generalExpire, contextCache.contextCache.get(name).get().cacheExpire);
|
|
|
+
|
|
|
+ // Fallback to context defaults
|
|
|
+ contextCache = new ScriptService.CacheHolder(
|
|
|
+ Settings.builder()
|
|
|
+ .put(SCRIPT_GENERAL_MAX_COMPILATIONS_RATE_SETTING.getKey(), USE_CONTEXT_RATE_KEY)
|
|
|
+ .build(),
|
|
|
+ List.of(foo),
|
|
|
+ true);
|
|
|
+
|
|
|
+ assertNotNull(contextCache.contextCache);
|
|
|
+ assertNotNull(contextCache.contextCache.get(name));
|
|
|
+ assertNotNull(contextCache.contextCache.get(name).get());
|
|
|
+
|
|
|
+ assertEquals(contextDefaultRate, contextCache.contextCache.get(name).get().rate);
|
|
|
+ assertEquals(foo.cacheSizeDefault, contextCache.contextCache.get(name).get().cacheSize);
|
|
|
+ assertEquals(foo.cacheExpireDefault, contextCache.contextCache.get(name).get().cacheExpire);
|
|
|
+
|
|
|
+ // Use context specific for ingest
|
|
|
+ contextCache = new ScriptService.CacheHolder(
|
|
|
+ Settings.builder()
|
|
|
+ .put(SCRIPT_GENERAL_MAX_COMPILATIONS_RATE_SETTING.getKey(), USE_CONTEXT_RATE_KEY)
|
|
|
+ .build(),
|
|
|
+ List.of(foo, IngestScript.CONTEXT, IngestConditionalScript.CONTEXT),
|
|
|
+ true);
|
|
|
+ assertEquals(new Tuple<>(375, TimeValue.timeValueMinutes(5)),
|
|
|
+ contextCache.contextCache.get("ingest").get().rate);
|
|
|
+ assertEquals(200, contextCache.contextCache.get("ingest").get().cacheSize);
|
|
|
+ assertEquals(TimeValue.timeValueMillis(0), contextCache.contextCache.get("ingest").get().cacheExpire);
|
|
|
+ }
|
|
|
+
|
|
|
private void assertCompileRejected(String lang, String script, ScriptType scriptType, ScriptContext scriptContext) {
|
|
|
try {
|
|
|
scriptService.compile(new Script(scriptType, lang, script, Collections.emptyMap()), scriptContext);
|
|
|
@@ -545,4 +641,8 @@ public class ScriptServiceTests extends ESTestCase {
|
|
|
notNullValue()
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+ ScriptContext<ScriptContextTests.DummyScript.Factory> newContext(String name) {
|
|
|
+ return new ScriptContext<>(name, ScriptContextTests.DummyScript.Factory.class);
|
|
|
+ }
|
|
|
}
|