summaryrefslogtreecommitdiffstats
path: root/statistics/src/test
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /statistics/src/test
Publish
Diffstat (limited to 'statistics/src/test')
-rw-r--r--statistics/src/test/java/com/yahoo/statistics/CounterGroupTestCase.java132
-rw-r--r--statistics/src/test/java/com/yahoo/statistics/CounterTestCase.java103
-rw-r--r--statistics/src/test/java/com/yahoo/statistics/HistogramTestCase.java75
-rw-r--r--statistics/src/test/java/com/yahoo/statistics/ProxyTestCase.java62
-rw-r--r--statistics/src/test/java/com/yahoo/statistics/StatisticsImplTestCase.java108
-rw-r--r--statistics/src/test/java/com/yahoo/statistics/ValueGroupTestCase.java116
-rw-r--r--statistics/src/test/java/com/yahoo/statistics/ValueTestCase.java284
7 files changed, 880 insertions, 0 deletions
diff --git a/statistics/src/test/java/com/yahoo/statistics/CounterGroupTestCase.java b/statistics/src/test/java/com/yahoo/statistics/CounterGroupTestCase.java
new file mode 100644
index 00000000000..5e51c3b4754
--- /dev/null
+++ b/statistics/src/test/java/com/yahoo/statistics/CounterGroupTestCase.java
@@ -0,0 +1,132 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.statistics;
+
+
+import java.util.Arrays;
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import com.yahoo.container.StatisticsConfig;
+
+/**
+ * Test set for groups of counters.
+ *
+ * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ */
+public class CounterGroupTestCase extends junit.framework.TestCase {
+ private volatile boolean gotRecord = false;
+
+ private class CounterGroupHandler extends Handler {
+ // This is for testing CounterProxy
+ @Override
+ public void publish(LogRecord record) {
+ com.yahoo.log.event.CountGroup msg = (com.yahoo.log.event.CountGroup) ((Object[]) record.getParameters())[0];
+ assertEquals("test", msg.getValue("name"));
+ String values = msg.getValue("values");
+ assertFalse("Unexpected value for a.", values.indexOf("a=500") == -1);
+ assertFalse("Unexpected value for b.", values.indexOf("b=1") == -1);
+ assertFalse("Unexpected value for c.", values.indexOf("c=0") == -1);
+ gotRecord = true;
+
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void close() throws SecurityException {
+ }
+ }
+
+ public void testBasic() {
+ Logger logger = Logger.getLogger(CounterGroup.class.getName());
+ boolean initUseParentHandlers = logger.getUseParentHandlers();
+ Handler logChecker = new CounterGroupHandler();
+ logger.setUseParentHandlers(false);
+ CounterGroup c = new CounterGroup("test", Statistics.nullImplementation, false);
+ Counter n;
+ c.increment("a");
+ c.increment("b");
+ c.increment("a", 499);
+ n = c.getCounter("a");
+ assertEquals(500, n.get());
+ n = c.getCounter("b");
+ assertEquals(1, n.get());
+ n = c.getCounter("c");
+ assertEquals(0, n.get());
+ logger.addHandler(logChecker);
+ c.run();
+ assertFalse("The logging handler did not really run.", gotRecord == false);
+ // cleanup:
+ logger.removeHandler(logChecker);
+ logger.setUseParentHandlers(initUseParentHandlers);
+ }
+
+ public void testObjectContracts() {
+ CounterGroup c = new CounterGroup("test", Statistics.nullImplementation, false);
+ CounterGroup c2 = new CounterGroup("test", Statistics.nullImplementation, false);
+ c2.increment("nalle");
+ assertEquals(c, c2);
+ assertEquals(c.hashCode(), c2.hashCode());
+ c2 = new CounterGroup("nalle", Statistics.nullImplementation, false);
+ assertFalse("Different names should lead to different hashcodes",
+ c.hashCode() == c2.hashCode());
+ assertFalse("Different names should lead to equals() return false",
+ c.equals(c2));
+ }
+
+ public void testConfigStuff() {
+ Logger logger = Logger.getLogger(CounterGroup.class.getName());
+ boolean initUseParentHandlers = logger.getUseParentHandlers();
+ logger.setUseParentHandlers(false);
+ MockStatistics m = new MockStatistics();
+ final String joppe = "joppe";
+ StatisticsConfig config = new StatisticsConfig(
+ new StatisticsConfig.Builder().counterresets(Arrays
+ .asList(new StatisticsConfig.Counterresets.Builder[] {
+ new StatisticsConfig.Counterresets.Builder().name(joppe) })));
+ m.config = config;
+ CounterGroup c = new CounterGroup("nalle", m);
+ CounterGroup c2 = new CounterGroup(joppe, m);
+ final String bamse = "bamse";
+ c.increment(bamse);
+ c2.increment(bamse);
+ assertEquals(1L, c.getCounter(bamse).get());
+ assertEquals(1L, c2.getCounter(bamse).get());
+ c2.increment(bamse);
+ assertEquals(1L, c.getCounter(bamse).get());
+ assertEquals(2L, c2.getCounter(bamse).get());
+ c.run();
+ c2.run();
+ assertEquals(1L, c.getCounter(bamse).get());
+ assertEquals(0L, c2.getCounter(bamse).get());
+ logger.setUseParentHandlers(initUseParentHandlers);
+ }
+
+ public class MockStatistics implements Statistics {
+ public StatisticsConfig config = null;
+ public int registerCount = 0;
+
+ @Override
+ public void register(Handle h) {
+ registerCount += 1;
+ }
+
+ @Override
+ public void remove(String name) {
+ }
+
+ @Override
+ public StatisticsConfig getConfig() {
+ return config;
+ }
+
+ @Override
+ public int purge() {
+ return 0;
+ }
+ }
+
+}
diff --git a/statistics/src/test/java/com/yahoo/statistics/CounterTestCase.java b/statistics/src/test/java/com/yahoo/statistics/CounterTestCase.java
new file mode 100644
index 00000000000..800e993bb0f
--- /dev/null
+++ b/statistics/src/test/java/com/yahoo/statistics/CounterTestCase.java
@@ -0,0 +1,103 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.statistics;
+
+
+import java.util.Arrays;
+import java.util.logging.Logger;
+
+import com.yahoo.container.StatisticsConfig;
+
+/**
+ * Check counters work.
+ *
+ * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ */
+
+public class CounterTestCase extends junit.framework.TestCase {
+
+ public void testBasic() {
+ Counter c = new Counter("test", Statistics.nullImplementation, false);
+ c.increment();
+ assertEquals(1, c.get());
+ c.increment(499);
+ assertEquals(500, c.get());
+ c.reset();
+ assertEquals(500, c.get());
+ c = new Counter("test", Statistics.nullImplementation, false, null, true);
+ c.increment();
+ assertEquals(1, c.get());
+ c.increment(499);
+ assertEquals(500, c.get());
+ c.reset();
+ assertEquals(0, c.get());
+ }
+
+ public void testObjectContracts() {
+ final String counterName = "test";
+ Counter c = new Counter(counterName, Statistics.nullImplementation, false);
+ Counter c2 = new Counter(counterName, Statistics.nullImplementation, false);
+ c2.increment();
+ assertEquals(c, c2);
+ assertEquals(c.hashCode(), c2.hashCode());
+ c2 = new Counter("nalle", Statistics.nullImplementation, false);
+ assertFalse("Different names should lead to different hashcodes",
+ c.hashCode() == c2.hashCode());
+ assertFalse("Different names should lead to equals() return false",
+ c.equals(c2));
+ String prefix = "com.yahoo.statistics.Counter";
+ String suffix = counterName + " 0";
+ String image = c.toString();
+ assertEquals(suffix, image.substring(image.length() - suffix.length()));
+ assertEquals(prefix, image.substring(0, prefix.length()));
+ }
+
+ public void testConfigStuff() {
+ Logger logger = Logger.getLogger(Counter.class.getName());
+ boolean initUseParentHandlers = logger.getUseParentHandlers();
+ logger.setUseParentHandlers(false);
+ MockStatistics m = new MockStatistics();
+ final String joppe = "joppe";
+ StatisticsConfig config = new StatisticsConfig(
+ new StatisticsConfig.Builder().counterresets(Arrays
+ .asList(new StatisticsConfig.Counterresets.Builder[] { new StatisticsConfig.Counterresets.Builder()
+ .name(joppe) })));
+ m.config = config;
+ Counter c = new Counter("nalle", m, true);
+ Counter c2 = new Counter(joppe, m, true);
+ c.increment();
+ c2.increment();
+ assertEquals(1L, c.get());
+ assertEquals(1L, c2.get());
+ c.run();
+ c2.run();
+ assertEquals(1L, c.get());
+ assertEquals(0L, c2.get());
+ logger.setUseParentHandlers(initUseParentHandlers);
+
+ }
+
+ public class MockStatistics implements Statistics {
+ public StatisticsConfig config = null;
+ public int registerCount = 0;
+
+ @Override
+ public void register(Handle h) {
+ registerCount += 1;
+ }
+
+ @Override
+ public void remove(String name) {
+ }
+
+ @Override
+ public StatisticsConfig getConfig() {
+ return config;
+ }
+
+ @Override
+ public int purge() {
+ return 0;
+ }
+ }
+
+}
diff --git a/statistics/src/test/java/com/yahoo/statistics/HistogramTestCase.java b/statistics/src/test/java/com/yahoo/statistics/HistogramTestCase.java
new file mode 100644
index 00000000000..575feaa93f8
--- /dev/null
+++ b/statistics/src/test/java/com/yahoo/statistics/HistogramTestCase.java
@@ -0,0 +1,75 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.statistics;
+
+
+
+
+/**
+ * Some low level checking of the histograms.
+ *
+ * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ */
+
+public class HistogramTestCase extends junit.framework.TestCase {
+
+ public HistogramTestCase(String name) {
+ super(name);
+ }
+
+ public void testFindBucket() {
+ Limits l = new Limits();
+ double[] thresholds = {.5, 1.0, 5.0};
+ double[] value = {.5, .5};
+ l.addAxis("latency", thresholds);
+ thresholds = new double[] {500.0, 1000.0, 5000.0};
+ l.addAxis("size", thresholds);
+ Histogram h = new Histogram(l);
+ assertEquals("latency,size ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0)) < 0.5 ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0)) < 1.0 ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0)) < 5.0 ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0))",
+ h.toString());
+ h.put(value);
+ assertEquals("latency,size ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0)) < 0.5 ((1) < 500.0 (0) < 1000.0 (0) < 5000.0 (0)) < 1.0 ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0)) < 5.0 ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0))",
+ h.toString());
+
+ }
+
+ public void testMerge() {
+ Limits l = new Limits();
+ double[] thresholds = {.5, 1.0, 5.0};
+ double[] value = {.75};
+ l.addAxis("latency", thresholds);
+ Histogram h = new Histogram(l);
+ Histogram h2 = new Histogram(l);
+ h.put(value);
+ h.put(value);
+ h2.put(value);
+ h2.merge(h);
+ assertEquals("(0) < 0.5 (3) < 1.0 (0) < 5.0 (0)", h2.toString());
+ }
+
+ public void testMultiDimensionalMerge() {
+ Limits l = new Limits();
+ double[] thresholds = {.5, 1.0, 5.0};
+ double[] value = {.5, .5};
+ l.addAxis("latency", thresholds);
+ thresholds = new double[] {500.0, 1000.0, 5000.0};
+ l.addAxis("size", thresholds);
+ Histogram h = new Histogram(l);
+ Histogram h2 = new Histogram(l);
+ h.put(value);
+ assertEquals("latency,size ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0)) < 0.5 ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0)) < 1.0 ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0)) < 5.0 ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0))",
+ h2.toString());
+ h2.merge(h);
+ assertEquals("latency,size ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0)) < 0.5 ((1) < 500.0 (0) < 1000.0 (0) < 5000.0 (0)) < 1.0 ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0)) < 5.0 ((0) < 500.0 (0) < 1000.0 (0) < 5000.0 (0))",
+ h.toString());
+ }
+
+ public void testEmptyHistogram() {
+ try {
+ new Histogram(new Limits());
+ } catch (IndexOutOfBoundsException e) {
+ return;
+ }
+ fail("Got no exception when trying to create an empty histogram.");
+ }
+
+}
diff --git a/statistics/src/test/java/com/yahoo/statistics/ProxyTestCase.java b/statistics/src/test/java/com/yahoo/statistics/ProxyTestCase.java
new file mode 100644
index 00000000000..a7fc02a1fbf
--- /dev/null
+++ b/statistics/src/test/java/com/yahoo/statistics/ProxyTestCase.java
@@ -0,0 +1,62 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.statistics;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tabular checking of statistics proxies.
+ *
+ * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ */
+public class ProxyTestCase {
+ private static final double MAX = 2.0d;
+ private static final double MEAN = 1.0d;
+ private static final double MIN = -1.0d;
+ private static final double RAW = 0.5d;
+ private static final long C_RAW = 3;
+ ValueProxy vp;
+ CounterProxy cp;
+ Histogram h = new Histogram(new Limits(new double[] { 1.0d }));
+
+ @Before
+ public void setUp() throws Exception {
+ vp = new ValueProxy("nalle");
+ vp.setRaw(RAW);
+ vp.setMin(MIN);
+ vp.setMean(MEAN);
+ vp.setMax(MAX);
+ vp.setHistogram(h);
+ cp = new CounterProxy("nalle");
+ cp.setRaw(C_RAW);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public final void test() {
+ assertFalse(vp.hasHistogram() == false);
+ assertFalse(vp.hasRaw() == false);
+ assertFalse(vp.hasMin() == false);
+ assertFalse(vp.hasMean() == false);
+ assertFalse(vp.hasMax() == false);
+ assertFalse(cp.hasRaw() == false);
+ assertEquals(C_RAW, cp.getRaw());
+ assertEquals(MAX, vp.getMax(), 1e-9);
+ assertEquals(MEAN, vp.getMean(), 1e-9);
+ assertEquals(MIN, vp.getMin(), 1e-9);
+ assertEquals(RAW, vp.getRaw(), 1e-9);
+ assertSame(h, vp.getHistogram());
+
+ final long t = 11L;
+ Proxy p = new Proxy("nalle", t) {
+ };
+ assertEquals(t, p.getTimestamp());
+ }
+
+}
diff --git a/statistics/src/test/java/com/yahoo/statistics/StatisticsImplTestCase.java b/statistics/src/test/java/com/yahoo/statistics/StatisticsImplTestCase.java
new file mode 100644
index 00000000000..e6694a0b654
--- /dev/null
+++ b/statistics/src/test/java/com/yahoo/statistics/StatisticsImplTestCase.java
@@ -0,0 +1,108 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.statistics;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+
+import java.util.logging.Logger;
+
+import org.junit.Test;
+
+import com.yahoo.container.StatisticsConfig;
+
+/**
+ * Check register/remove semantics.
+ *
+ * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ */
+public class StatisticsImplTestCase {
+ private static class TestHandle extends Handle {
+
+ TestHandle(final String name, final Statistics manager,
+ final Callback parametrizedCallback) {
+ super(name, manager, parametrizedCallback);
+ }
+
+ @Override
+ public void runHandle() {
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (o == this) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return getName().hashCode();
+ }
+
+ }
+
+ @Test
+ public final void testRegister() {
+ final StatisticsConfig config = new StatisticsConfig(
+ new StatisticsConfig.Builder().collectionintervalsec(31e9)
+ .loggingintervalsec(31e9));
+ final StatisticsImpl s = new StatisticsImpl(config);
+ final Logger logger = Logger.getLogger(TestHandle.class.getName());
+ final boolean initUseParentHandlers = logger.getUseParentHandlers();
+ logger.setUseParentHandlers(false);
+ final String firstHandle = "a";
+ final Handle a = new TestHandle(firstHandle, s, null);
+ final Handle a2 = new TestHandle(firstHandle, s, null);
+ final String secondHandle = "b";
+ final Handle b = new TestHandle(secondHandle, s, null);
+ s.register(a);
+ s.register(a2);
+ assertFalse("Old handle should be cancelled.", a.isCancelled() == false);
+ assertFalse("New handle should not be cancelled.", a2.isCancelled());
+ assertEquals("Internal handles map semantics have been changed?", 1,
+ s.handles.size());
+ s.register(b);
+ s.remove(secondHandle);
+ assertFalse("Removed handle should be cancelled.",
+ b.isCancelled() == false);
+ a2.cancel();
+ s.purge();
+ assertEquals("Cancelled tasks should be removed.", 0, s.handles.size());
+ s.deconstruct();
+ assertSame(config, s.getConfig());
+ logger.setUseParentHandlers(initUseParentHandlers);
+ }
+
+ @Test
+ public void freezeNullImplementationBehavior() {
+ Statistics s = Statistics.nullImplementation;
+ assertEquals(0, s.purge());
+ // invoke s.register
+ Handle h = new Handle("nalle", s, null) {
+ @Override
+ public void runHandle() {
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+
+ };
+ assertEquals(0, s.purge());
+ s.register(h);
+ s.remove("nalle");
+ s.register(h);
+ h.cancel();
+ assertEquals(0, s.purge());
+ }
+
+}
diff --git a/statistics/src/test/java/com/yahoo/statistics/ValueGroupTestCase.java b/statistics/src/test/java/com/yahoo/statistics/ValueGroupTestCase.java
new file mode 100644
index 00000000000..1491575626f
--- /dev/null
+++ b/statistics/src/test/java/com/yahoo/statistics/ValueGroupTestCase.java
@@ -0,0 +1,116 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.statistics;
+
+
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import com.yahoo.container.StatisticsConfig;
+
+/**
+ * Test set for groups of values.
+ *
+ * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ */
+public class ValueGroupTestCase extends junit.framework.TestCase {
+ private volatile boolean gotRecord = false;
+
+ private class ValueGroupHandler extends Handler {
+ // this is for testing ValueProxy
+
+ @Override
+ public void publish(LogRecord record) {
+ com.yahoo.log.event.ValueGroup msg = (com.yahoo.log.event.ValueGroup) ((Object[]) record.getParameters())[0];
+ assertEquals("test", msg.getValue("name"));
+ String values = msg.getValue("values");
+ assertFalse("Unexpected value for a.", values.indexOf("a=-50.0") == -1);
+ assertFalse("Unexpected value for b.", values.indexOf("b=40.0") == -1);
+ assertFalse("Unexpected value for c.", values.indexOf("c=0.0") == -1);
+ gotRecord = true;
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void close() throws SecurityException {
+ }
+ }
+
+ public void testBasic() {
+ Logger logger = Logger.getLogger(ValueGroup.class.getName());
+ boolean initUseParentHandlers = logger.getUseParentHandlers();
+ Handler logChecker = new ValueGroupHandler();
+ logger.setUseParentHandlers(false);
+ final MockStatistics manager = new MockStatistics();
+ ValueGroup v = new ValueGroup("test", manager);
+ v.put("a", 50.0);
+ v.put("b", 40.0);
+ v.put("a", -50.0);
+ assertTrue("Last value inserted to a was -50",
+ -50.0 == v.getValue("a").get());
+ assertTrue("Last value inserted to b was 40.",
+ 40.0 == v.getValue("b").get());
+ assertTrue("c has not been used yet",
+ 0.0 == v.getValue("c").get());
+ logger.addHandler(logChecker);
+ v.run();
+ assertFalse("The logging handler did not really run.", gotRecord == false);
+ assertEquals(1, manager.registerCount);
+ // cleanup:
+ logger.removeHandler(logChecker);
+ logger.setUseParentHandlers(initUseParentHandlers);
+ }
+
+ public void testOverlappingSubnames() {
+ final MockStatistics manager = new MockStatistics();
+ ValueGroup v = new ValueGroup("jappe", manager);
+ ValueGroup v2 = new ValueGroup("nalle", manager);
+ final String name = "mobil";
+ v.put(name, 50.0);
+ v2.put(name, 40.0);
+ assertEquals(50.0, v.getValue(name).get(), 1e-9);
+ assertEquals(40.0, v2.getValue(name).get(), 1e-9);
+ assertEquals(2, manager.registerCount);
+ }
+
+ public void testObjectContracts() {
+ ValueGroup v = new ValueGroup("test", new MockStatistics());
+ ValueGroup v2 = new ValueGroup("test", new MockStatistics());
+ v2.put("nalle", 2.0);
+ assertEquals(v, v2);
+ assertEquals(v.hashCode(), v2.hashCode());
+ v2 = new ValueGroup("nalle", new MockStatistics());
+ assertFalse("Different names should lead to different hashcodes",
+ v.hashCode() == v2.hashCode());
+ assertFalse("Different names should lead to equals() return false",
+ v.equals(v2));
+ }
+
+ public class MockStatistics implements Statistics {
+ public StatisticsConfig config = null;
+ public int registerCount = 0;
+
+ @Override
+ public void register(Handle h) {
+ registerCount += 1;
+ }
+
+ @Override
+ public void remove(String name) {
+ }
+
+ @Override
+ public StatisticsConfig getConfig() {
+ return config;
+ }
+
+ @Override
+ public int purge() {
+ return 0;
+ }
+ }
+
+}
diff --git a/statistics/src/test/java/com/yahoo/statistics/ValueTestCase.java b/statistics/src/test/java/com/yahoo/statistics/ValueTestCase.java
new file mode 100644
index 00000000000..b837b775040
--- /dev/null
+++ b/statistics/src/test/java/com/yahoo/statistics/ValueTestCase.java
@@ -0,0 +1,284 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.statistics;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import com.yahoo.container.StatisticsConfig;
+import static com.yahoo.container.StatisticsConfig.Values.Operations;
+import com.yahoo.statistics.Value.Parameters;
+
+/**
+ * Check correct statistics are generated for basic values.
+ *
+ * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ */
+public class ValueTestCase extends junit.framework.TestCase {
+
+ private static final String NALLE = "nalle";
+ private static final double SECOND = 43.0d;
+ private static final double FIRST = 42.0d;
+
+ private static class TrivialCallback implements Callback {
+
+ @Override
+ public void run(Handle h, boolean firstRun) {
+ Value v = (Value) h;
+ if (firstRun) {
+ v.put(FIRST);
+ } else {
+ v.put(SECOND);
+ }
+ }
+
+ }
+
+ public void testMean() {
+ Value v = new Value("thingie", Statistics.nullImplementation, new Parameters().setLogMean(true));
+ v.put(1.0);
+ v.put(2.0);
+ v.put(4.0);
+ v.put(-1.0);
+ assertTrue("Mean should be 1.5", 1.5 == v.getMean());
+ ValueProxy vp = v.getProxyAndReset();
+ assertTrue("Proxy mean should be 1.5", 1.5 == vp.getMean());
+ assertTrue("Value should have been reset.", 0.0d == v.getMean());
+ }
+
+ public void testMin() {
+ Value v = new Value("thingie", Statistics.nullImplementation, new Parameters().setLogMin(true));
+ v.put(2.0);
+ assertTrue("Min should be 2.0", 2.0 == v.getMin());
+ v.put(1.0);
+ assertTrue("Min should be 1.0", 1.0 == v.getMin());
+ v.put(-1.0);
+ v.put(4.0);
+ assertTrue("Min should be -1.0", -1.0 == v.getMin());
+ }
+
+ public void testMax() {
+ Value v = new Value("thingie", Statistics.nullImplementation, new Parameters().setLogMax(true));
+ v.put(-1.0);
+ assertTrue("Max should be -1.0", -1.0 == v.getMax());
+ v.put(1.0);
+ v.put(2.0);
+ assertTrue("Max should be 2.0", 2.0 == v.getMax());
+ v.put(4.0);
+ v.put(-1.0);
+ assertTrue("Max should be 4.0", 4.0 == v.getMax());
+ }
+
+ public void testHistogram() {
+ Value v = new Value("thingie", Statistics.nullImplementation, new Parameters()
+ .setLogHistogram(true).setHistogramId(HistogramType.REGULAR)
+ .setLimits(new Limits(new double[] { 0.0, 1.0, 2.0 })));
+ v.put(-1.0);
+ v.put(0.0);
+ v.put(1.0);
+ v.put(2.0);
+ v.put(3.0);
+ assertTrue(v.toString().endsWith(
+ " thingie (1) < 0.0 (1) < 1.0 (1) < 2.0 (2)"));
+ }
+
+ public void testCallback() {
+ Logger logger = Logger.getLogger(Value.class.getName());
+ boolean initUseParentHandlers = logger.getUseParentHandlers();
+ logger.setUseParentHandlers(false);
+ Value v = new Value("thingie", Statistics.nullImplementation, new Parameters()
+ .setLogRaw(true).setCallback(new TrivialCallback()));
+ v.run();
+ assertEquals(FIRST, v.get());
+ v.run();
+ assertEquals(SECOND, v.get());
+ v.run();
+ assertEquals(SECOND, v.get());
+ logger.setUseParentHandlers(initUseParentHandlers);
+ }
+
+ public void testParameter() {
+ Value.Parameters p = new Value.Parameters().setLogInsertions(true)
+ .setNameExtension(true).setAppendChar('_');
+ Value.Parameters p2 = new Value.Parameters().setLogSum(true);
+ assertNull(p2.appendChar);
+ assertNull(p.logSum);
+ p2.merge(p);
+ assertEquals(new Character('_'), p2.appendChar);
+ assertNull(p2.logMax);
+ assertEquals(Boolean.TRUE, p2.logSum);
+ }
+
+ private class CheckHistogram extends Handler {
+ volatile boolean gotRecord = false;
+ volatile boolean gotWarning = false;
+ final String histogram;
+ final String representation;
+
+ public CheckHistogram(String histogram, String representation) {
+ this.histogram = histogram;
+ this.representation = representation;
+ }
+
+ @Override
+ public void publish(LogRecord record) {
+ if (record.getParameters() == null) {
+ assertEquals(Value.HISTOGRAM_TYPE_WARNING + " '" + NALLE + "'", record.getMessage());
+ gotWarning = true;
+ return;
+ }
+ if (!(record.getParameters()[0] instanceof com.yahoo.log.event.Histogram)) {
+ return;
+ }
+ com.yahoo.log.event.Histogram msg = (com.yahoo.log.event.Histogram) ((Object[]) record.getParameters())[0];
+ assertEquals(NALLE, msg.getValue("name"));
+ assertEquals(histogram, msg.getValue("counts"));
+ assertEquals(representation, msg.getValue("representation"));
+ gotRecord = true;
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void close() throws SecurityException {
+ }
+ }
+
+ public void testParameterFromConfig() {
+ Logger logger = Logger.getLogger(Value.class.getName());
+ boolean initUseParentHandlers = logger.getUseParentHandlers();
+ logger.setUseParentHandlers(false);
+ CheckHistogram h = new CheckHistogram("(0) < 0.0 (0) < 1.0 (0) < 2.0 (1)", "REGULAR");
+ logger.addHandler(h);
+ List<Operations.Arguments.Builder> histogram = Arrays.asList(new Operations.Arguments.Builder[] {
+ new Operations.Arguments.Builder().key("limits").value("0, 1, 2")});
+ List<Operations.Builder> ops = Arrays.asList(new Operations.Builder[] {
+ new Operations.Builder().name(Operations.Name.Enum.MEAN),
+ new Operations.Builder().name(Operations.Name.Enum.MIN),
+ new Operations.Builder().name(Operations.Name.Enum.MAX),
+ new Operations.Builder().name(Operations.Name.Enum.RAW),
+ new Operations.Builder().name(Operations.Name.Enum.INSERTIONS),
+ new Operations.Builder().name(Operations.Name.Enum.REGULAR).arguments(histogram),
+ new Operations.Builder().name(Operations.Name.Enum.SUM) });
+ StatisticsConfig c = new StatisticsConfig(
+ new StatisticsConfig.Builder()
+ .values(new StatisticsConfig.Values.Builder().name(
+ NALLE).operations(ops)));
+ MockStatistics m = new MockStatistics();
+ m.config = c;
+ Value v = Value.buildValue(NALLE, m, null);
+ final double x = 79.0d;
+ v.put(x);
+ assertEquals(x, v.getMean());
+ v.run();
+ assertEquals(true, h.gotRecord);
+ logger.removeHandler(h);
+ logger.setUseParentHandlers(initUseParentHandlers);
+ }
+
+ public void testReverseHistogram() {
+ Logger logger = Logger.getLogger(Value.class.getName());
+ boolean initUseParentHandlers = logger.getUseParentHandlers();
+ logger.setUseParentHandlers(false);
+ CheckHistogram h = new CheckHistogram("(0) < 0.0 (2) < 1.0 (2) < 2.0 (0)", "REGULAR");
+ logger.addHandler(h);
+ List<Operations.Arguments.Builder> histogram = Arrays.asList(new Operations.Arguments.Builder[] {
+ new Operations.Arguments.Builder().key("limits").value("0, 1, 2")});
+ List<Operations.Builder> ops = Arrays.asList(new Operations.Builder[] {
+ new Operations.Builder().name(Operations.Name.Enum.REVERSE_CUMULATIVE).arguments(histogram) });
+ StatisticsConfig c = new StatisticsConfig(
+ new StatisticsConfig.Builder()
+ .values(new StatisticsConfig.Values.Builder().name(
+ NALLE).operations(ops)));
+ MockStatistics m = new MockStatistics();
+ m.config = c;
+ Value v = Value.buildValue(NALLE, m, null);
+ assertEquals(HistogramType.REGULAR.toString(), v.histogramId.toString());
+ v.put(.5d);
+ v.put(.5d);
+ v.put(1.5d);
+ v.put(1.5d);
+ v.run();
+ assertEquals(true, h.gotRecord);
+ assertEquals(true, h.gotWarning);
+ logger.removeHandler(h);
+ logger.setUseParentHandlers(initUseParentHandlers);
+ }
+
+ public void testCumulativeHistogram() {
+ Logger logger = Logger.getLogger(Value.class.getName());
+ boolean initUseParentHandlers = logger.getUseParentHandlers();
+ logger.setUseParentHandlers(false);
+ CheckHistogram h = new CheckHistogram("(0) < 0.0 (2) < 1.0 (2) < 2.0 (0)", "REGULAR");
+ logger.addHandler(h);
+ List<Operations.Arguments.Builder> histogram = Arrays.asList(new Operations.Arguments.Builder[] {
+ new Operations.Arguments.Builder().key("limits").value("0, 1, 2")});
+ List<Operations.Builder> ops = Arrays.asList(new Operations.Builder[] {
+ new Operations.Builder().name(Operations.Name.Enum.CUMULATIVE).arguments(histogram) });
+ StatisticsConfig c = new StatisticsConfig(
+ new StatisticsConfig.Builder()
+ .values(new StatisticsConfig.Values.Builder().name(
+ NALLE).operations(ops)));
+ MockStatistics m = new MockStatistics();
+ m.config = c;
+ Value v = Value.buildValue(NALLE, m, null);
+ assertEquals(HistogramType.REGULAR.toString(), v.histogramId.toString());
+ v.put(.5d);
+ v.put(.5d);
+ v.put(1.5d);
+ v.put(1.5d);
+ v.run();
+ assertEquals(true, h.gotRecord);
+ assertEquals(true, h.gotWarning);
+ logger.removeHandler(h);
+ logger.setUseParentHandlers(initUseParentHandlers);
+ }
+
+ public void testObjectContracts() {
+ final String valueName = "test";
+ Value v = new Value(valueName, Statistics.nullImplementation, Value.defaultParameters());
+ Value v2 = new Value(valueName, Statistics.nullImplementation, Value.defaultParameters());
+ v2.put(1.0);
+ assertEquals(v, v2);
+ assertEquals(v.hashCode(), v2.hashCode());
+ v2 = new Value("nalle", Statistics.nullImplementation, Value.defaultParameters());
+ assertFalse("Different names should lead to different hashcodes",
+ v.hashCode() == v2.hashCode());
+ assertFalse("Different names should lead to equals() return false",
+ v.equals(v2));
+ String image = v.toString();
+ String prefix = "com.yahoo.statistics.Value";
+ assertEquals(prefix, image.substring(0, prefix.length()));
+ assertEquals(valueName, image.substring(image.length() - valueName.length()));
+ }
+
+
+ public class MockStatistics implements Statistics {
+ public StatisticsConfig config = null;
+ public int registerCount = 0;
+
+ @Override
+ public void register(Handle h) {
+ registerCount += 1;
+ }
+
+ @Override
+ public void remove(String name) {
+ }
+
+ @Override
+ public StatisticsConfig getConfig() {
+ return config;
+ }
+
+ @Override
+ public int purge() {
+ return 0;
+ }
+ }
+
+}