/* This file is part of VoltDB.
* Copyright (C) 2008-2017 VoltDB Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package org.voltdb.regressionsuites.statistics;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import junit.framework.Test;
import org.voltdb.VoltTable;
import org.voltdb.VoltTable.ColumnInfo;
import org.voltdb.VoltType;
import org.voltdb.client.Client;
import org.voltdb.regressionsuites.StatisticsTestSuiteBase;
public class TestStatisticsSuitePlannerStats extends StatisticsTestSuiteBase {
public TestStatisticsSuitePlannerStats(String name) {
super(name);
}
//
// planner statistics
//
public void testPlannerStatistics() throws Exception {
System.out.println("\n\nTESTING PLANNER STATS\n\n\n");
Client client = getClient();
ColumnInfo[] expectedSchema = new ColumnInfo[14];
expectedSchema[0] = new ColumnInfo("TIMESTAMP", VoltType.BIGINT);
expectedSchema[1] = new ColumnInfo("HOST_ID", VoltType.INTEGER);
expectedSchema[2] = new ColumnInfo("HOSTNAME", VoltType.STRING);
expectedSchema[3] = new ColumnInfo("SITE_ID", VoltType.INTEGER);
expectedSchema[4] = new ColumnInfo("PARTITION_ID", VoltType.INTEGER);
expectedSchema[5] = new ColumnInfo("CACHE1_LEVEL", VoltType.INTEGER);
expectedSchema[6] = new ColumnInfo("CACHE2_LEVEL", VoltType.INTEGER);
expectedSchema[7] = new ColumnInfo("CACHE1_HITS", VoltType.BIGINT);
expectedSchema[8] = new ColumnInfo("CACHE2_HITS", VoltType.BIGINT);
expectedSchema[9] = new ColumnInfo("CACHE_MISSES", VoltType.BIGINT);
expectedSchema[10] = new ColumnInfo("PLAN_TIME_MIN", VoltType.BIGINT);
expectedSchema[11] = new ColumnInfo("PLAN_TIME_MAX", VoltType.BIGINT);
expectedSchema[12] = new ColumnInfo("PLAN_TIME_AVG", VoltType.BIGINT);
expectedSchema[13] = new ColumnInfo("FAILURES", VoltType.BIGINT);
VoltTable expectedTable = new VoltTable(expectedSchema);
VoltTable[] results = null;
// Clear the interval statistics
results = client.callProcedure("@Statistics", "planner", 1).getResults();
assertEquals(1, results.length);
// Invoke a few select queries a few times to get some cache hits and misses,
// and to exceed the sampling frequency.
// This does not use level 2 cache (parameterization) or trigger failures.
for (String query : new String[] {
"select * from warehouse",
"select * from new_order",
"select * from item",
}) {
for (int i = 0; i < 10; i++) {
client.callProcedure("@AdHoc", query).getResults();
assertEquals(1, results.length);
}
}
// Get the final interval statistics
results = client.callProcedure("@Statistics", "planner", 1).getResults();
assertEquals(1, results.length);
System.out.println("Test planner table: " + results[0].toString());
validateSchema(results[0], expectedTable);
VoltTable stats = results[0];
// Sample the statistics
List<Long> siteIds = new ArrayList<Long>();
int cache1_level = 0;
int cache2_level = 0;
int cache1_hits = 0;
int cache2_hits = 0;
int cache_misses = 0;
long plan_time_min_min = Long.MAX_VALUE;
long plan_time_max_max = Long.MIN_VALUE;
long plan_time_avg_tot = 0;
int failures = 0;
while (stats.advanceRow()) {
cache1_level += (Integer)stats.get("CACHE1_LEVEL", VoltType.INTEGER);
cache2_level += (Integer)stats.get("CACHE2_LEVEL", VoltType.INTEGER);
cache1_hits += (Integer)stats.get("CACHE1_HITS", VoltType.INTEGER);
cache2_hits += (Integer)stats.get("CACHE2_HITS", VoltType.INTEGER);
cache_misses += (Integer)stats.get("CACHE_MISSES", VoltType.INTEGER);
plan_time_min_min = Math.min(plan_time_min_min, (Long)stats.get("PLAN_TIME_MIN", VoltType.BIGINT));
plan_time_max_max = Math.max(plan_time_max_max, (Long)stats.get("PLAN_TIME_MAX", VoltType.BIGINT));
plan_time_avg_tot += (Long)stats.get("PLAN_TIME_AVG", VoltType.BIGINT);
failures += (Integer)stats.get("FAILURES", VoltType.INTEGER);
siteIds.add((Long)stats.get("SITE_ID", VoltType.BIGINT));
}
// Check for reasonable results
int globalPlanners = 0;
assertTrue("Failed siteIds count >= 2", siteIds.size() >= 2);
for (long siteId : siteIds) {
if (siteId == -1) {
globalPlanners++;
}
}
assertTrue("Global planner sites not 1, value was: " + globalPlanners, globalPlanners == 1);
assertTrue("Failed total CACHE1_LEVEL > 0, value was: " + cache1_level, cache1_level > 0);
assertTrue("Failed total CACHE1_LEVEL < 1,000,000, value was: " + cache1_level, cache1_level < 1000000);
assertTrue("Failed total CACHE2_LEVEL >= 0, value was: " + cache2_level, cache2_level >= 0);
assertTrue("Failed total CACHE2_LEVEL < 1,000,000, value was: " + cache2_level, cache2_level < 1000000);
assertTrue("Failed total CACHE1_HITS > 0, value was: " + cache1_hits, cache1_hits > 0);
assertTrue("Failed total CACHE1_HITS < 1,000,000, value was: " + cache1_hits, cache1_hits < 1000000);
assertTrue("Failed total CACHE2_HITS == 0, value was: " + cache2_hits, cache2_hits == 0);
assertTrue("Failed total CACHE2_HITS < 1,000,000, value was: " + cache2_hits, cache2_hits < 1000000);
assertTrue("Failed total CACHE_MISSES > 0, value was: " + cache_misses, cache_misses > 0);
assertTrue("Failed total CACHE_MISSES < 1,000,000, value was: " + cache_misses, cache_misses < 1000000);
assertTrue("Failed min PLAN_TIME_MIN > 0, value was: " + plan_time_min_min, plan_time_min_min > 0);
assertTrue("Failed total PLAN_TIME_MIN < 100,000,000,000, value was: " + plan_time_min_min, plan_time_min_min < 100000000000L);
assertTrue("Failed max PLAN_TIME_MAX > 0, value was: " + plan_time_max_max, plan_time_max_max > 0);
assertTrue("Failed total PLAN_TIME_MAX < 100,000,000,000, value was: " + plan_time_max_max, plan_time_max_max < 100000000000L);
assertTrue("Failed total PLAN_TIME_AVG > 0, value was: " + plan_time_avg_tot, plan_time_avg_tot > 0);
assertTrue("Failed total FAILURES == 0, value was: " + failures, failures == 0);
}
//
// Build a list of the tests to be run. Use the regression suite
// helpers to allow multiple backends.
// JUnit magic that uses the regression suite helper classes.
//
static public Test suite() throws IOException {
return StatisticsTestSuiteBase.suite(TestStatisticsSuitePlannerStats.class, false);
}
}