/* Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. Contact: SYSTAP, LLC DBA Blazegraph 2501 Calvert ST NW #106 Washington, DC 20008 licenses@blazegraph.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Created on Mar 19, 2008 */ package com.bigdata.counters; import java.util.Random; import junit.framework.TestCase2; /** * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a> * @version $Id$ * * @todo unit tests when overwrite is disabled. */ public class TestHistoryInstrument extends TestCase2 { // 60 seconds. final private static long t60 = 60 * 1000; /** * Time zero is an arbitrary time occurring on an exact _hour_ boundary. * This constraint is imposed so that we can consistently test overflow * behavior. Overflow SHOULD occur immediately _before_ you add the sample * which would cause the sample recorded [capacity * period] units ago to be * overwritten (even if the sample in danger of being overwritten is a * <code>null</code>. If we accept a truly random starting time then it * is harder to setup the unit tests to test overflow handling. */ final private long t0 = new Random().nextInt(100)*1000L*60*60; /** * */ public TestHistoryInstrument() { super(); } /** * @param arg0 */ public TestHistoryInstrument(String arg0) { super(arg0); } /** * Test of {@link History} adds two samples spaced one minute apart and then * a 3rd sample that is two minutes later. */ public void test_history01() { // a history buffer with 60 samples each spaced 60 seconds apart. final History<Double> h = new History<Double>(new Double[60], t60, true/*overwrite*/); assertEquals(0,h.size()); assertEquals(60,h.capacity()); if(log.isInfoEnabled()) log.info("\n"+h.toString()); // add the first sample. h.add(t0,12d); assertEquals(1,h.size()); assertEquals(60,h.capacity()); assertEquals(12d,h.getAverage().doubleValue()); if(log.isInfoEnabled()) log.info("\n"+h.toString()); // add a 2nd sample. h.add(t0+t60,6d); assertEquals(2,h.size()); assertEquals(60,h.capacity()); assertEquals(((6d+12d)/2d),h.getAverage().doubleValue()); if(log.isInfoEnabled()) log.info("\n"+h.toString()); // add a 2nd sample, but skip 60 seconds. h.add(t0+t60*3,9d); assertEquals(3,h.size()); assertEquals(60,h.capacity()); assertEquals(((6d+12d+9d)/3d),h.getAverage().doubleValue()); if(log.isInfoEnabled()) log.info("\n"+h.toString()); } /** * Test that overflow occurs correctly using a short buffer. */ public void test_historyOverflow() { /* * a history buffer with 2 samples each spaced 60 seconds apart. */ final History<Double> h = new History<Double>(new Double[2], t60, true/* overwrite */); assertEquals(0,h.size()); assertEquals(2,h.capacity()); /* * a history buffer with 3 samples each spaced two minutes apart. */ final History<Double> h2 = new History<Double>(3,h); assertEquals(0,h2.size()); assertEquals(3,h2.capacity()); if(log.isInfoEnabled()) log.info("\nh="+h.toString()); if(log.isInfoEnabled()) log.info("\nh2="+h2.toString()); /* * feed in data. */ /* add the first sample. * * TODO There is a stochastic test failure in CI (pretty rare). If fails on the next with: java.lang.IllegalArgumentException: timestamp=0, value=12.0 at com.bigdata.counters.History.add(History.java:726) at com.bigdata.counters.TestHistoryInstrument.test_historyOverflow(TestHistoryInstrument.java:143) */ h.add(t0,12d); if(log.isInfoEnabled()) log.info("\nh="+h.toString()); if(log.isInfoEnabled()) log.info("\nh2="+h2.toString()); assertEquals(1,h.size()); assertEquals(0,h2.size()); assertEquals(12d,h.getAverage().doubleValue()); // add a 2nd sample. h.add(t0+t60,6d); if(log.isInfoEnabled()) log.info("\nh="+h.toString()); if(log.isInfoEnabled()) log.info("\nh2="+h2.toString()); assertEquals(2,h.size()); assertEquals(0,h2.size()); assertEquals(((6d+12d)/2d),h.getAverage().doubleValue()); /* * add a 3rd sample, this should cause the first buffer to overflow. */ h.add(t0+t60+t60,9d); assertEquals(2,h.size()); assertEquals(1,h2.size()); if(log.isInfoEnabled()) log.info("\nh="+h.toString()); if(log.isInfoEnabled()) log.info("\nh2="+h2.toString()); // check average in the base buffer. assertEquals(((6d+9d)/2d),h.getAverage().doubleValue()); // overflow should propagate the average before adding the new sample. assertEquals((12d+6d)/2d,h2.getAverage().doubleValue()); } // /** // * Test {@link HistoryInstrument}. // */ // public void test_001() { // // HistoryInstrument<Double> h = new HistoryInstrument<Double>(new Double[]{}); // // assertEquals(60,h.minutes.capacity()); // assertEquals(24,h.hours.capacity()); // assertEquals(30,h.days.capacity()); // // assertTrue(h.minutes.isNumeric()); // assertFalse(h.minutes.isLong()); // assertTrue(h.minutes.isDouble()); // // if(log.isInfoEnabled()) log.info(h.toString()); // // /* // * Fill the entire buffer with per-minute samples and verify that we // * overflow to the per hour samples buffer when we add the 61st sample. // */ // int nsamples = 1; // e.g., the 1st sample. // for(int i=0; i<60; i++) { // // h.minutes.add(t0+i*t60, (double)i); // // assertEquals(i+1,h.minutes.size()); // // if (nsamples == 61) { // // assertEquals("nsamples="+nsamples,1,h.hours.size()); // // } else { // // assertEquals("nsamples="+nsamples,0,h.hours.size()); // // } // // nsamples++; // // } // // if(log.isInfoEnabled()) log.info(h.toString()); // // } }