From a1fd01d4ccb91a3a10d7d19446da13010413cb86 Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Fri, 29 Jan 2016 09:39:02 -0500 Subject: [PATCH] No leniency in parsing JVM GC monitor settings This commit removes some leniency in the parsing of the JVM GC monitor settings, and adds tests for the JVM GC monitor settings. --- .../monitor/jvm/JvmGcMonitorService.java | 31 +++-- .../jvm/JvmGcMonitorServiceSettingsTests.java | 113 ++++++++++++++++++ 2 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 core/src/test/java/org/elasticsearch/monitor/jvm/JvmGcMonitorServiceSettingsTests.java diff --git a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java index 1d0da9821b5..97c813a0fe3 100644 --- a/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java +++ b/core/src/main/java/org/elasticsearch/monitor/jvm/JvmGcMonitorService.java @@ -50,7 +50,9 @@ public class JvmGcMonitorService extends AbstractLifecycleComponent ENABLED_SETTING = Setting.boolSetting("monitor.jvm.gc.enabled", true, false, Scope.CLUSTER); public final static Setting REFRESH_INTERVAL_SETTING = Setting.timeSetting("monitor.jvm.gc.refresh_interval", TimeValue.timeValueSeconds(1), TimeValue.timeValueSeconds(1), false, Scope.CLUSTER); - public final static Setting GC_SETTING = Setting.groupSetting("monitor.jvm.gc.collector.", false, Scope.CLUSTER); + + private static String GC_COLLECTOR_PREFIX = "monitor.jvm.gc.collector."; + public final static Setting GC_SETTING = Setting.groupSetting(GC_COLLECTOR_PREFIX, false, Scope.CLUSTER); static class GcThreshold { public final String name; @@ -87,14 +89,10 @@ public class JvmGcMonitorService extends AbstractLifecycleComponent gcThresholdGroups = GC_SETTING.get(settings).getAsGroups(); for (Map.Entry entry : gcThresholdGroups.entrySet()) { String name = entry.getKey(); - TimeValue warn = entry.getValue().getAsTime("warn", null); - TimeValue info = entry.getValue().getAsTime("info", null); - TimeValue debug = entry.getValue().getAsTime("debug", null); - if (warn == null || info == null || debug == null) { - logger.warn("ignoring gc_threshold for [{}], missing warn/info/debug values", name); - } else { - gcThresholds.put(name, new GcThreshold(name, warn.millis(), info.millis(), debug.millis())); - } + TimeValue warn = getValidThreshold(entry.getValue(), entry.getKey(), "warn"); + TimeValue info = getValidThreshold(entry.getValue(), entry.getKey(), "info"); + TimeValue debug = getValidThreshold(entry.getValue(), entry.getKey(), "debug"); + gcThresholds.put(name, new GcThreshold(name, warn.millis(), info.millis(), debug.millis())); } gcThresholds.putIfAbsent(GcNames.YOUNG, new GcThreshold(GcNames.YOUNG, 1000, 700, 400)); gcThresholds.putIfAbsent(GcNames.OLD, new GcThreshold(GcNames.OLD, 10000, 5000, 2000)); @@ -104,6 +102,21 @@ public class JvmGcMonitorService extends AbstractLifecycleComponent { scheduled.set(true); return null; }, () -> assertTrue(scheduled.get())); + } + + public void testDisabledSetting() throws InterruptedException { + Settings settings = Settings.builder().put("monitor.jvm.gc.enabled", "false").build(); + AtomicBoolean scheduled = new AtomicBoolean(); + execute(settings, (command, interval) -> { scheduled.set(true); return null; }, () -> assertFalse(scheduled.get())); + } + + public void testNegativeSetting() throws InterruptedException { + String collector = randomAsciiOfLength(5); + Settings settings = Settings.builder().put("monitor.jvm.gc.collector." + collector + ".warn", "-" + randomTimeValue()).build(); + execute(settings, (command, interval) -> null, t -> { + assertThat(t, instanceOf(IllegalArgumentException.class)); + assertThat(t.getMessage(), allOf(containsString("invalid gc_threshold"), containsString("for [monitor.jvm.gc.collector." + collector + "."))); + }, true, null); + } + + public void testMissingSetting() throws InterruptedException { + String collector = randomAsciiOfLength(5); + Set> entries = new HashSet<>(); + entries.add(new AbstractMap.SimpleEntry<>("monitor.jvm.gc.collector." + collector + ".warn", randomTimeValue())); + entries.add(new AbstractMap.SimpleEntry<>("monitor.jvm.gc.collector." + collector + ".info", randomTimeValue())); + entries.add(new AbstractMap.SimpleEntry<>("monitor.jvm.gc.collector." + collector + ".debug", randomTimeValue())); + Settings.Builder builder = Settings.builder(); + + // drop a random setting or two + for (@SuppressWarnings("unchecked") AbstractMap.SimpleEntry entry : randomSubsetOf(randomIntBetween(1, 2), entries.toArray(new AbstractMap.SimpleEntry[0]))) { + builder.put(entry.getKey(), entry.getValue()); + } + + // we should get an exception that a setting is missing + execute(builder.build(), (command, interval) -> null, t -> { + assertThat(t, instanceOf(IllegalArgumentException.class)); + assertThat(t.getMessage(), containsString("missing gc_threshold for [monitor.jvm.gc.collector." + collector + ".")); + }, true, null); + } + + private static void execute(Settings settings, BiFunction> scheduler, Runnable asserts) throws InterruptedException { + execute(settings, scheduler, null, false, asserts); + } + + private static void execute(Settings settings, BiFunction> scheduler, Consumer consumer, boolean constructionShouldFail, Runnable asserts) throws InterruptedException { + assert constructionShouldFail == (consumer != null); + assert constructionShouldFail == (asserts == null); + ThreadPool threadPool = null; + try { + threadPool = new ThreadPool(JvmGcMonitorServiceSettingsTests.class.getCanonicalName()) { + @Override + public ScheduledFuture scheduleWithFixedDelay(Runnable command, TimeValue interval) { + return scheduler.apply(command, interval); + } + }; + try { + JvmGcMonitorService service = new JvmGcMonitorService(settings, threadPool); + if (constructionShouldFail) { + fail("construction of jvm gc service should have failed"); + } + service.doStart(); + asserts.run(); + service.doStop(); + } catch (Throwable t) { + consumer.accept(t); + } + } finally { + ThreadPool.terminate(threadPool, 30, TimeUnit.SECONDS); + } + } + +}