/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF 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.apache.hadoop.lib.service.instrumentation; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.StringWriter; import java.util.Arrays; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.lib.server.Server; import org.apache.hadoop.lib.service.Instrumentation; import org.apache.hadoop.lib.service.scheduler.SchedulerService; import org.apache.hadoop.test.HTestCase; import org.apache.hadoop.test.TestDir; import org.apache.hadoop.test.TestDirHelper; import org.apache.hadoop.util.StringUtils; import org.apache.hadoop.util.Time; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.junit.Test; public class TestInstrumentationService extends HTestCase { @Override protected float getWaitForRatio() { return 1; } @Test public void cron() { InstrumentationService.Cron cron = new InstrumentationService.Cron(); assertEquals(cron.start, 0); assertEquals(cron.lapStart, 0); assertEquals(cron.own, 0); assertEquals(cron.total, 0); long begin = Time.now(); assertEquals(cron.start(), cron); assertEquals(cron.start(), cron); assertEquals(cron.start, begin, 20); assertEquals(cron.start, cron.lapStart); sleep(100); assertEquals(cron.stop(), cron); long end = Time.now(); long delta = end - begin; assertEquals(cron.own, delta, 20); assertEquals(cron.total, 0); assertEquals(cron.lapStart, 0); sleep(100); long reStart = Time.now(); cron.start(); assertEquals(cron.start, begin, 20); assertEquals(cron.lapStart, reStart, 20); sleep(100); cron.stop(); long reEnd = Time.now(); delta += reEnd - reStart; assertEquals(cron.own, delta, 20); assertEquals(cron.total, 0); assertEquals(cron.lapStart, 0); cron.end(); assertEquals(cron.total, reEnd - begin, 20); try { cron.start(); fail(); } catch (IllegalStateException ex) { } catch (Exception ex) { fail(); } try { cron.stop(); fail(); } catch (IllegalStateException ex) { } catch (Exception ex) { fail(); } } @Test public void timer() throws Exception { InstrumentationService.Timer timer = new InstrumentationService.Timer(2); InstrumentationService.Cron cron = new InstrumentationService.Cron(); long ownStart; long ownEnd; long totalStart; long totalEnd; long ownDelta; long totalDelta; long avgTotal; long avgOwn; cron.start(); ownStart = Time.now(); totalStart = ownStart; ownDelta = 0; sleep(100); cron.stop(); ownEnd = Time.now(); ownDelta += ownEnd - ownStart; sleep(100); cron.start(); ownStart = Time.now(); sleep(100); cron.stop(); ownEnd = Time.now(); ownDelta += ownEnd - ownStart; totalEnd = ownEnd; totalDelta = totalEnd - totalStart; avgTotal = totalDelta; avgOwn = ownDelta; timer.addCron(cron); long[] values = timer.getValues(); assertEquals(values[InstrumentationService.Timer.LAST_TOTAL], totalDelta, 20); assertEquals(values[InstrumentationService.Timer.LAST_OWN], ownDelta, 20); assertEquals(values[InstrumentationService.Timer.AVG_TOTAL], avgTotal, 20); assertEquals(values[InstrumentationService.Timer.AVG_OWN], avgOwn, 20); cron = new InstrumentationService.Cron(); cron.start(); ownStart = Time.now(); totalStart = ownStart; ownDelta = 0; sleep(200); cron.stop(); ownEnd = Time.now(); ownDelta += ownEnd - ownStart; sleep(200); cron.start(); ownStart = Time.now(); sleep(200); cron.stop(); ownEnd = Time.now(); ownDelta += ownEnd - ownStart; totalEnd = ownEnd; totalDelta = totalEnd - totalStart; avgTotal = (avgTotal * 1 + totalDelta) / 2; avgOwn = (avgOwn * 1 + ownDelta) / 2; timer.addCron(cron); values = timer.getValues(); assertEquals(values[InstrumentationService.Timer.LAST_TOTAL], totalDelta, 20); assertEquals(values[InstrumentationService.Timer.LAST_OWN], ownDelta, 20); assertEquals(values[InstrumentationService.Timer.AVG_TOTAL], avgTotal, 20); assertEquals(values[InstrumentationService.Timer.AVG_OWN], avgOwn, 20); avgTotal = totalDelta; avgOwn = ownDelta; cron = new InstrumentationService.Cron(); cron.start(); ownStart = Time.now(); totalStart = ownStart; ownDelta = 0; sleep(300); cron.stop(); ownEnd = Time.now(); ownDelta += ownEnd - ownStart; sleep(300); cron.start(); ownStart = Time.now(); sleep(300); cron.stop(); ownEnd = Time.now(); ownDelta += ownEnd - ownStart; totalEnd = ownEnd; totalDelta = totalEnd - totalStart; avgTotal = (avgTotal * 1 + totalDelta) / 2; avgOwn = (avgOwn * 1 + ownDelta) / 2; cron.stop(); timer.addCron(cron); values = timer.getValues(); assertEquals(values[InstrumentationService.Timer.LAST_TOTAL], totalDelta, 20); assertEquals(values[InstrumentationService.Timer.LAST_OWN], ownDelta, 20); assertEquals(values[InstrumentationService.Timer.AVG_TOTAL], avgTotal, 20); assertEquals(values[InstrumentationService.Timer.AVG_OWN], avgOwn, 20); JSONObject json = (JSONObject) new JSONParser().parse(timer.toJSONString()); assertEquals(json.size(), 4); assertEquals(json.get("lastTotal"), values[InstrumentationService.Timer.LAST_TOTAL]); assertEquals(json.get("lastOwn"), values[InstrumentationService.Timer.LAST_OWN]); assertEquals(json.get("avgTotal"), values[InstrumentationService.Timer.AVG_TOTAL]); assertEquals(json.get("avgOwn"), values[InstrumentationService.Timer.AVG_OWN]); StringWriter writer = new StringWriter(); timer.writeJSONString(writer); writer.close(); json = (JSONObject) new JSONParser().parse(writer.toString()); assertEquals(json.size(), 4); assertEquals(json.get("lastTotal"), values[InstrumentationService.Timer.LAST_TOTAL]); assertEquals(json.get("lastOwn"), values[InstrumentationService.Timer.LAST_OWN]); assertEquals(json.get("avgTotal"), values[InstrumentationService.Timer.AVG_TOTAL]); assertEquals(json.get("avgOwn"), values[InstrumentationService.Timer.AVG_OWN]); } @Test public void sampler() throws Exception { final long value[] = new long[1]; Instrumentation.Variable<Long> var = new Instrumentation.Variable<Long>() { @Override public Long getValue() { return value[0]; } }; InstrumentationService.Sampler sampler = new InstrumentationService.Sampler(); sampler.init(4, var); assertEquals(sampler.getRate(), 0f, 0.0001); sampler.sample(); assertEquals(sampler.getRate(), 0f, 0.0001); value[0] = 1; sampler.sample(); assertEquals(sampler.getRate(), (0d + 1) / 2, 0.0001); value[0] = 2; sampler.sample(); assertEquals(sampler.getRate(), (0d + 1 + 2) / 3, 0.0001); value[0] = 3; sampler.sample(); assertEquals(sampler.getRate(), (0d + 1 + 2 + 3) / 4, 0.0001); value[0] = 4; sampler.sample(); assertEquals(sampler.getRate(), (4d + 1 + 2 + 3) / 4, 0.0001); JSONObject json = (JSONObject) new JSONParser().parse(sampler.toJSONString()); assertEquals(json.size(), 2); assertEquals(json.get("sampler"), sampler.getRate()); assertEquals(json.get("size"), 4L); StringWriter writer = new StringWriter(); sampler.writeJSONString(writer); writer.close(); json = (JSONObject) new JSONParser().parse(writer.toString()); assertEquals(json.size(), 2); assertEquals(json.get("sampler"), sampler.getRate()); assertEquals(json.get("size"), 4L); } @Test public void variableHolder() throws Exception { InstrumentationService.VariableHolder<String> variableHolder = new InstrumentationService.VariableHolder<String>(); variableHolder.var = new Instrumentation.Variable<String>() { @Override public String getValue() { return "foo"; } }; JSONObject json = (JSONObject) new JSONParser().parse(variableHolder.toJSONString()); assertEquals(json.size(), 1); assertEquals(json.get("value"), "foo"); StringWriter writer = new StringWriter(); variableHolder.writeJSONString(writer); writer.close(); json = (JSONObject) new JSONParser().parse(writer.toString()); assertEquals(json.size(), 1); assertEquals(json.get("value"), "foo"); } @Test @TestDir @SuppressWarnings("unchecked") public void service() throws Exception { String dir = TestDirHelper.getTestDir().getAbsolutePath(); String services = StringUtils.join(",", Arrays.asList(InstrumentationService.class.getName())); Configuration conf = new Configuration(false); conf.set("server.services", services); Server server = new Server("server", dir, dir, dir, dir, conf); server.init(); Instrumentation instrumentation = server.get(Instrumentation.class); assertNotNull(instrumentation); instrumentation.incr("g", "c", 1); instrumentation.incr("g", "c", 2); instrumentation.incr("g", "c1", 2); Instrumentation.Cron cron = instrumentation.createCron(); cron.start(); sleep(100); cron.stop(); instrumentation.addCron("g", "t", cron); cron = instrumentation.createCron(); cron.start(); sleep(200); cron.stop(); instrumentation.addCron("g", "t", cron); Instrumentation.Variable<String> var = new Instrumentation.Variable<String>() { @Override public String getValue() { return "foo"; } }; instrumentation.addVariable("g", "v", var); Instrumentation.Variable<Long> varToSample = new Instrumentation.Variable<Long>() { @Override public Long getValue() { return 1L; } }; instrumentation.addSampler("g", "s", 10, varToSample); Map<String, ?> snapshot = instrumentation.getSnapshot(); assertNotNull(snapshot.get("os-env")); assertNotNull(snapshot.get("sys-props")); assertNotNull(snapshot.get("jvm")); assertNotNull(snapshot.get("counters")); assertNotNull(snapshot.get("timers")); assertNotNull(snapshot.get("variables")); assertNotNull(snapshot.get("samplers")); assertNotNull(((Map<String, String>) snapshot.get("os-env")).get("PATH")); assertNotNull(((Map<String, String>) snapshot.get("sys-props")).get("java.version")); assertNotNull(((Map<String, ?>) snapshot.get("jvm")).get("free.memory")); assertNotNull(((Map<String, ?>) snapshot.get("jvm")).get("max.memory")); assertNotNull(((Map<String, ?>) snapshot.get("jvm")).get("total.memory")); assertNotNull(((Map<String, Map<String, Object>>) snapshot.get("counters")).get("g")); assertNotNull(((Map<String, Map<String, Object>>) snapshot.get("timers")).get("g")); assertNotNull(((Map<String, Map<String, Object>>) snapshot.get("variables")).get("g")); assertNotNull(((Map<String, Map<String, Object>>) snapshot.get("samplers")).get("g")); assertNotNull(((Map<String, Map<String, Object>>) snapshot.get("counters")).get("g").get("c")); assertNotNull(((Map<String, Map<String, Object>>) snapshot.get("counters")).get("g").get("c1")); assertNotNull(((Map<String, Map<String, Object>>) snapshot.get("timers")).get("g").get("t")); assertNotNull(((Map<String, Map<String, Object>>) snapshot.get("variables")).get("g").get("v")); assertNotNull(((Map<String, Map<String, Object>>) snapshot.get("samplers")).get("g").get("s")); StringWriter writer = new StringWriter(); JSONObject.writeJSONString(snapshot, writer); writer.close(); server.destroy(); } @Test @TestDir @SuppressWarnings("unchecked") public void sampling() throws Exception { String dir = TestDirHelper.getTestDir().getAbsolutePath(); String services = StringUtils.join(",", Arrays.asList(InstrumentationService.class.getName(), SchedulerService.class.getName())); Configuration conf = new Configuration(false); conf.set("server.services", services); Server server = new Server("server", dir, dir, dir, dir, conf); server.init(); Instrumentation instrumentation = server.get(Instrumentation.class); final AtomicInteger count = new AtomicInteger(); Instrumentation.Variable<Long> varToSample = new Instrumentation.Variable<Long>() { @Override public Long getValue() { return (long) count.incrementAndGet(); } }; instrumentation.addSampler("g", "s", 10, varToSample); sleep(2000); int i = count.get(); assertTrue(i > 0); Map<String, Map<String, ?>> snapshot = instrumentation.getSnapshot(); Map<String, Map<String, Object>> samplers = (Map<String, Map<String, Object>>) snapshot.get("samplers"); InstrumentationService.Sampler sampler = (InstrumentationService.Sampler) samplers.get("g").get("s"); assertTrue(sampler.getRate() > 0); server.destroy(); } }