/* * Copyright 2013 Rackspace * * Licensed 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 com.rackspacecloud.blueflood.service; import com.rackspacecloud.blueflood.cache.MetadataCache; import com.rackspacecloud.blueflood.concurrent.ThreadPoolBuilder; import com.rackspacecloud.blueflood.io.*; import com.rackspacecloud.blueflood.rollup.Granularity; import com.rackspacecloud.blueflood.types.*; import com.rackspacecloud.blueflood.utils.TimeValue; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.TimeUnit; public class RollupRunnableIntegrationTest extends IntegrationTestBase { // gentle reader: remember, all column families are truncated between tests // in super.setUp() private AbstractMetricsRW basicRW = IOContainer.fromConfig().getBasicMetricsRW(); private AbstractMetricsRW preAggrRW = IOContainer.fromConfig().getPreAggregatedMetricsRW(); private final Locator counterLocator = Locator.createLocatorFromPathComponents("runnabletest", "counter"); private final Locator gaugeLocator = Locator.createLocatorFromPathComponents("runnabletest", "gauge"); private final Locator timerLocator = Locator.createLocatorFromPathComponents("runnabletest", "timer"); private final Locator setLocator = Locator.createLocatorFromPathComponents("runnabletest", "set"); private final Locator normalLocator = Locator.createLocatorFromPathComponents("runnabletest", "just_some_data"); private final Range range = new Range(0, 6 * 60 * 1000); private MetadataCache cache; @Before public void generateData() throws Exception { final TimeValue ttl = new TimeValue(24, TimeUnit.HOURS); // cache needs to be populated so rollups knows which serializer to use. cache = MetadataCache.createLoadingCacheInstance(ttl, 2); String cacheKey = MetricMetadata.ROLLUP_TYPE.name().toLowerCase(); cache.put(counterLocator, cacheKey, RollupType.COUNTER.name()); cache.put(gaugeLocator, cacheKey, RollupType.GAUGE.name()); cache.put(timerLocator, cacheKey, RollupType.TIMER.name()); cache.put(setLocator, cacheKey, RollupType.SET.name()); // do not put normalLocator in the cache. it will constitute a miss. // put some full resolution data. Collection<IMetric> preaggregatedMetrics = new ArrayList<IMetric>(); Collection<IMetric> normalMetrics = new ArrayList<IMetric>(); for (int i = 1; i <= 5; i++) { long time = i * 30000; IMetric metric; BluefloodCounterRollup counter = new BluefloodCounterRollup() .withCount(i) .withRate(i * i) .withSampleCount(1); metric = new PreaggregatedMetric(time, counterLocator, ttl, counter); preaggregatedMetrics.add(metric); BluefloodGaugeRollup gauge = new BluefloodGaugeRollup() .withLatest(time, i); metric = new PreaggregatedMetric(time, gaugeLocator, ttl, gauge); preaggregatedMetrics.add(metric); BluefloodTimerRollup timer = new BluefloodTimerRollup() .withCount(5 * i + 1) .withMaxValue(100 - i) .withMinValue(100 - i - i) .withAverage(i / 2) .withCountPS((double)i).withSum(Double.valueOf(2 * i)) .withVariance((double) i / 2d); metric = new PreaggregatedMetric(time, timerLocator, ttl, timer); preaggregatedMetrics.add(metric); BluefloodSetRollup rollup = new BluefloodSetRollup().withObject(i); metric = new PreaggregatedMetric(time, setLocator, ttl, rollup); preaggregatedMetrics.add(metric); metric = new Metric(normalLocator, i, time, ttl, "centipawns"); normalMetrics.add(metric); } preAggrRW.insertMetrics(preaggregatedMetrics); basicRW.insertMetrics(normalMetrics); } @Test public void testNormalMetrics() throws IOException { // full res has 5 samples. Range customRange = new Range(0, 10 * 60 * 1000); Points points = basicRW.getDataToRollup( normalLocator, RollupType.NOT_A_ROLLUP, customRange, CassandraModel.CF_METRICS_FULL_NAME); System.out.println(String.format("points=%s", points.getPoints().toString())); Assert.assertEquals(String.format("Full res points for locator=%s range=%s", normalLocator, range), 5, basicRW.getDataToRollup( normalLocator, RollupType.NOT_A_ROLLUP, range, CassandraModel.CF_METRICS_FULL_NAME).getPoints().size()); // assert nothing in 5m for this locator. Assert.assertEquals("5m res points", 0, basicRW.getDataToRollup( normalLocator, RollupType.BF_BASIC, range, CassandraModel.CF_METRICS_5M_NAME).getPoints().size()); RollupExecutionContext rec = new RollupExecutionContext(Thread.currentThread()); SingleRollupReadContext rc = new SingleRollupReadContext(normalLocator, range, Granularity.MIN_5); RollupBatchWriter batchWriter = new RollupBatchWriter(new ThreadPoolBuilder().build(), rec); RollupRunnable rr = new RollupRunnable(rec, rc, batchWriter); rr.run(); while (!rec.doneReading() && !rec.doneWriting()) { batchWriter.drainBatch(); try { Thread.sleep(1000l); } catch (InterruptedException e) { } } // assert something in 5m for this locator. Assert.assertEquals(1, basicRW.getDataToRollup( normalLocator, RollupType.BF_BASIC, range, CassandraModel.CF_METRICS_5M_NAME).getPoints().size()); } @Test public void testCounterRollup() throws IOException { testRolledupMetric(counterLocator, RollupType.COUNTER); } @Test public void testGaugeRollup() throws IOException { testRolledupMetric(gaugeLocator, RollupType.GAUGE); } @Test public void testTimerRollup() throws IOException { testRolledupMetric(timerLocator, RollupType.TIMER); } @Test public void testSetRollup() throws IOException { testRolledupMetric(setLocator, RollupType.SET); } private void testRolledupMetric(Locator locator, RollupType rollupType) throws IOException { System.out.println("testRolledupMetric: for locator = " + locator + ", rollupTYpe=" + rollupType); // full res has 5 samples. Assert.assertEquals(5, preAggrRW.getDataToRollup( locator, rollupType, range, CassandraModel.CF_METRICS_PREAGGREGATED_FULL_NAME).getPoints().size()); // assert nothing in 5m for this locator. Assert.assertEquals(0, preAggrRW.getDataToRollup( locator, rollupType, range, CassandraModel.CF_METRICS_PREAGGREGATED_5M_NAME).getPoints().size()); RollupExecutionContext rec = new RollupExecutionContext(Thread.currentThread()); SingleRollupReadContext rc = new SingleRollupReadContext(locator, range, Granularity.MIN_5); RollupBatchWriter batchWriter = new RollupBatchWriter(new ThreadPoolBuilder().build(), rec); RollupRunnable rr = new RollupRunnable(rec, rc, batchWriter); rr.run(); // assert something in 5m for this locator. while (!rec.doneReading() && !rec.doneWriting()) { batchWriter.drainBatch(); try { Thread.sleep(1000l); } catch (InterruptedException e) { } } Assert.assertEquals(1, preAggrRW.getDataToRollup( locator, rollupType, range, CassandraModel.CF_METRICS_PREAGGREGATED_5M_NAME).getPoints().size()); } }