blob: 8ef0ea3c94a1daf2d427cf0a531807d293fbe198 [file] [log] [blame]
/*
* 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.cassandra.tools.nodetool.stats;
import java.util.ArrayList;
import java.util.List;
import org.junit.BeforeClass;
/**
* Create a test vector for unit testing of TableStats features.
*/
public class TableStatsTestBase
{
/**
* A test vector of StatsKeyspace and StatsTable objects loaded with human readable stats.
*/
protected static List<StatsKeyspace> humanReadableKeyspaces;
/**
* A test vector of StatsTable objects loaded with human readable statistics.
*/
protected static List<StatsTable> humanReadableTables;
/**
* A test vector of StatsKeyspace and StatsTable objects.
*/
protected static List<StatsKeyspace> testKeyspaces;
/**
* A test vector of StatsTable objects.
*/
protected static List<StatsTable> testTables;
/**
* @return StatsKeyspace an instance of StatsKeyspace preset with values for use in a test vector
*/
private static StatsKeyspace createStatsKeyspaceTemplate(String keyspaceName)
{
return new StatsKeyspace(null, keyspaceName);
}
/**
* @return StatsTable an instance of StatsTable preset with values for use in a test vector
*/
private static StatsTable createStatsTableTemplate(String keyspaceName, String tableName)
{
StatsTable template = new StatsTable();
template.fullName = keyspaceName + "." + tableName;
template.keyspaceName = keyspaceName;
template.tableName = tableName;
template.isIndex = false;
template.sstableCount = 0L;
template.oldSSTableCount = 0L;
template.spaceUsedLive = "0";
template.spaceUsedTotal = "0";
template.spaceUsedBySnapshotsTotal = "0";
template.percentRepaired = 1.0D;
template.bytesRepaired = 0L;
template.bytesUnrepaired = 0L;
template.bytesPendingRepair = 0L;
template.sstableCompressionRatio = -1.0D;
template.numberOfPartitionsEstimate = 0L;
template.memtableCellCount = 0L;
template.memtableDataSize = "0";
template.memtableSwitchCount = 0L;
template.localReadCount =0L;
template.localReadLatencyMs = Double.NaN;
template.localWriteCount = 0L;
template.localWriteLatencyMs = 0D;
template.pendingFlushes = 0L;
template.bloomFilterFalsePositives = 0L;
template.bloomFilterFalseRatio = 0D;
template.bloomFilterSpaceUsed = "0";
template.indexSummaryOffHeapMemoryUsed = "0";
template.compressionMetadataOffHeapMemoryUsed = "0";
template.compactedPartitionMinimumBytes = 0L;
template.compactedPartitionMaximumBytes = 0L;
template.compactedPartitionMeanBytes = 0L;
template.averageLiveCellsPerSliceLastFiveMinutes = Double.NaN;
template.maximumLiveCellsPerSliceLastFiveMinutes = 0L;
template.averageTombstonesPerSliceLastFiveMinutes = Double.NaN;
template.maximumTombstonesPerSliceLastFiveMinutes = 0L;
template.droppedMutations = "0";
return template;
}
@BeforeClass
public static void createTestVector()
{
// create test tables from templates
StatsTable table1 = createStatsTableTemplate("keyspace1", "table1");
StatsTable table2 = createStatsTableTemplate("keyspace1", "table2");
StatsTable table3 = createStatsTableTemplate("keyspace1", "table3");
StatsTable table4 = createStatsTableTemplate("keyspace2", "table4");
StatsTable table5 = createStatsTableTemplate("keyspace2", "table5");
StatsTable table6 = createStatsTableTemplate("keyspace3", "table6");
// average live cells: 1 > 6 > 2 > 5 > 3 > 4
table1.averageLiveCellsPerSliceLastFiveMinutes = 6D;
table2.averageLiveCellsPerSliceLastFiveMinutes = 4.01D;
table3.averageLiveCellsPerSliceLastFiveMinutes = 0D;
table4.averageLiveCellsPerSliceLastFiveMinutes = Double.NaN;
table5.averageLiveCellsPerSliceLastFiveMinutes = 4D;
table6.averageLiveCellsPerSliceLastFiveMinutes = 5D;
// average tombstones: 6 > 1 > 5 > 2 > 3 > 4
table1.averageTombstonesPerSliceLastFiveMinutes = 5D;
table2.averageTombstonesPerSliceLastFiveMinutes = 4.001D;
table3.averageTombstonesPerSliceLastFiveMinutes = Double.NaN;
table4.averageTombstonesPerSliceLastFiveMinutes = 0D;
table5.averageTombstonesPerSliceLastFiveMinutes = 4.01D;
table6.averageTombstonesPerSliceLastFiveMinutes = 6D;
// bloom filter false positives: 2 > 4 > 6 > 1 > 3 > 5
table1.bloomFilterFalsePositives = 30L;
table2.bloomFilterFalsePositives = 600L;
table3.bloomFilterFalsePositives = 20L;
table4.bloomFilterFalsePositives = 500L;
table5.bloomFilterFalsePositives = 10L;
table6.bloomFilterFalsePositives = 400L;
// bloom filter false positive ratio: 5 > 3 > 1 > 6 > 4 > 2
table1.bloomFilterFalseRatio = 0.40D;
table2.bloomFilterFalseRatio = 0.01D;
table3.bloomFilterFalseRatio = 0.50D;
table4.bloomFilterFalseRatio = 0.02D;
table5.bloomFilterFalseRatio = 0.60D;
table6.bloomFilterFalseRatio = 0.03D;
// bloom filter space used: 2 > 4 > 6 > 1 > 3 > 5
table1.bloomFilterSpaceUsed = "789";
table2.bloomFilterSpaceUsed = "161718";
table3.bloomFilterSpaceUsed = "456";
table4.bloomFilterSpaceUsed = "131415";
table5.bloomFilterSpaceUsed = "123";
table6.bloomFilterSpaceUsed = "101112";
// compacted partition maximum bytes: 1 > 3 > 5 > 2 > 4 = 6
table1.compactedPartitionMaximumBytes = 60L;
table2.compactedPartitionMaximumBytes = 30L;
table3.compactedPartitionMaximumBytes = 50L;
table4.compactedPartitionMaximumBytes = 20L;
table5.compactedPartitionMaximumBytes = 40L;
table6.compactedPartitionMaximumBytes = 20L;
// compacted partition mean bytes: 1 > 3 > 2 = 4 = 5 > 6
table1.compactedPartitionMeanBytes = 6L;
table2.compactedPartitionMeanBytes = 4L;
table3.compactedPartitionMeanBytes = 5L;
table4.compactedPartitionMeanBytes = 4L;
table5.compactedPartitionMeanBytes = 4L;
table6.compactedPartitionMeanBytes = 3L;
// compacted partition minimum bytes: 6 > 4 > 2 > 5 > 1 = 3
table1.compactedPartitionMinimumBytes = 2L;
table2.compactedPartitionMinimumBytes = 4L;
table3.compactedPartitionMinimumBytes = 2L;
table4.compactedPartitionMinimumBytes = 5L;
table5.compactedPartitionMinimumBytes = 3L;
table6.compactedPartitionMinimumBytes = 6L;
// dropped mutations: 6 > 3 > 4 > 2 > 1 = 5
table1.droppedMutations = "0";
table2.droppedMutations = "222";
table3.droppedMutations = "33333";
table4.droppedMutations = "4444";
table5.droppedMutations = "0";
table6.droppedMutations = "666666";
// local reads: 6 > 5 > 4 > 3 > 2 > 1
table1.localReadCount = 0L;
table2.localReadCount = 1L;
table3.localReadCount = 2L;
table4.localReadCount = 3L;
table5.localReadCount = 4L;
table6.localReadCount = 5L;
// local read latency: 3 > 2 > 1 > 6 > 4 > 5
table1.localReadLatencyMs = 2D;
table2.localReadLatencyMs = 3D;
table3.localReadLatencyMs = 4D;
table4.localReadLatencyMs = Double.NaN;
table5.localReadLatencyMs = 0D;
table6.localReadLatencyMs = 1D;
// local writes: 1 > 2 > 3 > 4 > 5 > 6
table1.localWriteCount = 5L;
table2.localWriteCount = 4L;
table3.localWriteCount = 3L;
table4.localWriteCount = 2L;
table5.localWriteCount = 1L;
table6.localWriteCount = 0L;
// local write latency: 4 > 5 > 6 > 1 > 2 > 3
table1.localWriteLatencyMs = 0.05D;
table2.localWriteLatencyMs = 0D;
table3.localWriteLatencyMs = Double.NaN;
table4.localWriteLatencyMs = 2D;
table5.localWriteLatencyMs = 1D;
table6.localWriteLatencyMs = 0.5D;
// maximum live cells last five minutes: 1 > 2 = 3 > 4 = 5 > 6
table1.maximumLiveCellsPerSliceLastFiveMinutes = 6L;
table2.maximumLiveCellsPerSliceLastFiveMinutes = 5L;
table3.maximumLiveCellsPerSliceLastFiveMinutes = 5L;
table4.maximumLiveCellsPerSliceLastFiveMinutes = 3L;
table5.maximumLiveCellsPerSliceLastFiveMinutes = 3L;
table6.maximumLiveCellsPerSliceLastFiveMinutes = 2L;
// maximum tombstones last five minutes: 6 > 5 > 3 = 4 > 2 > 1
table1.maximumTombstonesPerSliceLastFiveMinutes = 1L;
table2.maximumTombstonesPerSliceLastFiveMinutes = 2L;
table3.maximumTombstonesPerSliceLastFiveMinutes = 3L;
table4.maximumTombstonesPerSliceLastFiveMinutes = 3L;
table5.maximumTombstonesPerSliceLastFiveMinutes = 5L;
table6.maximumTombstonesPerSliceLastFiveMinutes = 6L;
// memtable cell count: 3 > 5 > 6 > 1 > 2 > 4
table1.memtableCellCount = 111L;
table2.memtableCellCount = 22L;
table3.memtableCellCount = 333333L;
table4.memtableCellCount = 4L;
table5.memtableCellCount = 55555L;
table6.memtableCellCount = 6666L;
// memtable data size: 6 > 5 > 4 > 3 > 2 > 1
table1.memtableDataSize = "0";
table2.memtableDataSize = "900";
table3.memtableDataSize = "1999";
table4.memtableDataSize = "3000";
table5.memtableDataSize = "20000";
table6.memtableDataSize = "1000000";
// memtable switch count: 4 > 2 > 3 > 6 > 5 > 1
table1.memtableSwitchCount = 1L;
table2.memtableSwitchCount = 22222L;
table3.memtableSwitchCount = 3333L;
table4.memtableSwitchCount = 444444L;
table5.memtableSwitchCount = 5L;
table6.memtableSwitchCount = 6L;
// number of partitions estimate: 1 > 2 > 3 > 4 > 5 > 6
table1.numberOfPartitionsEstimate = 111111L;
table2.numberOfPartitionsEstimate = 22222L;
table3.numberOfPartitionsEstimate = 3333L;
table4.numberOfPartitionsEstimate = 444L;
table5.numberOfPartitionsEstimate = 55L;
table6.numberOfPartitionsEstimate = 6L;
// pending flushes: 2 > 1 > 4 > 3 > 6 > 5
table1.pendingFlushes = 11111L;
table2.pendingFlushes = 222222L;
table3.pendingFlushes = 333L;
table4.pendingFlushes = 4444L;
table5.pendingFlushes = 5L;
table6.pendingFlushes = 66L;
// percent repaired: 1 > 2 > 3 > 5 > 4 > 6
table1.percentRepaired = 100.0D;
table2.percentRepaired = 99.9D;
table3.percentRepaired = 99.8D;
table4.percentRepaired = 50.0D;
table5.percentRepaired = 93.0D;
table6.percentRepaired = 0.0D;
// space used by snapshots: 5 > 1 > 2 > 4 > 3 = 6
table1.spaceUsedBySnapshotsTotal = "1111";
table2.spaceUsedBySnapshotsTotal = "222";
table3.spaceUsedBySnapshotsTotal = "0";
table4.spaceUsedBySnapshotsTotal = "44";
table5.spaceUsedBySnapshotsTotal = "55555";
table6.spaceUsedBySnapshotsTotal = "0";
// space used live: 6 > 5 > 4 > 2 > 1 = 3
table1.spaceUsedLive = "0";
table2.spaceUsedLive = "22";
table3.spaceUsedLive = "0";
table4.spaceUsedLive = "4444";
table5.spaceUsedLive = "55555";
table6.spaceUsedLive = "666666";
// space used total: 1 > 2 > 3 > 4 > 5 > 6
table1.spaceUsedTotal = "9001";
table2.spaceUsedTotal = "1024";
table3.spaceUsedTotal = "512";
table4.spaceUsedTotal = "256";
table5.spaceUsedTotal = "64";
table6.spaceUsedTotal = "0";
// sstable compression ratio: 5 > 4 > 1 = 2 = 6 > 3
table1.sstableCompressionRatio = 0.68D;
table2.sstableCompressionRatio = 0.68D;
table3.sstableCompressionRatio = 0.32D;
table4.sstableCompressionRatio = 0.95D;
table5.sstableCompressionRatio = 0.99D;
table6.sstableCompressionRatio = 0.68D;
// sstable count: 1 > 3 > 5 > 2 > 4 > 6
table1.sstableCount = 60000;
table2.sstableCount = 3000;
table3.sstableCount = 50000;
table4.sstableCount = 2000;
table5.sstableCount = 40000;
table6.sstableCount = 1000;
// Droppable Tombstone ratio
table1.droppableTombstoneRatio = 0;
table2.droppableTombstoneRatio = 0.222222;
table3.droppableTombstoneRatio = 0.333333;
table4.droppableTombstoneRatio = 0.444444;
table5.droppableTombstoneRatio = 0.555555;
table6.droppableTombstoneRatio = 0.666666;
// set even numbered tables to have some offheap usage
table2.offHeapUsed = true;
table4.offHeapUsed = true;
table6.offHeapUsed = true;
table2.memtableOffHeapUsed = true;
table4.memtableOffHeapUsed = true;
table6.memtableOffHeapUsed = true;
table2.bloomFilterOffHeapUsed = true;
table4.bloomFilterOffHeapUsed = true;
table6.bloomFilterOffHeapUsed = true;
table2.compressionMetadataOffHeapUsed = true;
table4.compressionMetadataOffHeapUsed = true;
table6.compressionMetadataOffHeapUsed = true;
table2.indexSummaryOffHeapUsed = true;
table4.indexSummaryOffHeapUsed = true;
table6.indexSummaryOffHeapUsed = true;
// offheap memory total: 4 > 2 > 6 > 1 = 3 = 5
table2.offHeapMemoryUsedTotal = "314159367";
table4.offHeapMemoryUsedTotal = "441213818";
table6.offHeapMemoryUsedTotal = "162470810";
// bloom filter offheap: 4 > 6 > 2 > 1 = 3 = 5
table2.bloomFilterOffHeapMemoryUsed = "98";
table4.bloomFilterOffHeapMemoryUsed = "299792458";
table6.bloomFilterOffHeapMemoryUsed = "667408";
// compression metadata offheap: 2 > 4 > 6 > 1 = 3 = 5
table2.compressionMetadataOffHeapMemoryUsed = "3";
table4.compressionMetadataOffHeapMemoryUsed = "2";
table6.compressionMetadataOffHeapMemoryUsed = "1";
// index summary offheap: 6 > 4 > 2 > 1 = 3 = 5
table2.indexSummaryOffHeapMemoryUsed = "1";
table4.indexSummaryOffHeapMemoryUsed = "2";
table6.indexSummaryOffHeapMemoryUsed = "3";
// memtable offheap: 2 > 6 > 4 > 1 = 3 = 5
table2.memtableOffHeapMemoryUsed = "314159265";
table4.memtableOffHeapMemoryUsed = "141421356";
table6.memtableOffHeapMemoryUsed = "161803398";
// create test keyspaces from templates
testKeyspaces = new ArrayList<>();
StatsKeyspace keyspace1 = createStatsKeyspaceTemplate("keyspace1");
StatsKeyspace keyspace2 = createStatsKeyspaceTemplate("keyspace2");
StatsKeyspace keyspace3 = createStatsKeyspaceTemplate("keyspace3");
// populate StatsKeyspace tables lists
keyspace1.tables.add(table1);
keyspace1.tables.add(table2);
keyspace1.tables.add(table3);
keyspace2.tables.add(table4);
keyspace2.tables.add(table5);
keyspace3.tables.add(table6);
// populate testKeyspaces test vector
testKeyspaces.add(keyspace1);
testKeyspaces.add(keyspace2);
testKeyspaces.add(keyspace3);
// compute keyspace statistics from relevant table metrics
for (int i = 0; i < testKeyspaces.size(); i++)
{
StatsKeyspace ks = testKeyspaces.get(i);
for (StatsTable st : ks.tables)
{
ks.readCount += st.localReadCount;
ks.writeCount += st.localWriteCount;
ks.pendingFlushes += (long) st.pendingFlushes;
}
testKeyspaces.set(i, ks);
}
// populate testTables test vector
testTables = new ArrayList<>();
testTables.add(table1);
testTables.add(table2);
testTables.add(table3);
testTables.add(table4);
testTables.add(table5);
testTables.add(table6);
//
// create test vector for human readable case
StatsTable humanReadableTable1 = createStatsTableTemplate("keyspace1", "table1");
StatsTable humanReadableTable2 = createStatsTableTemplate("keyspace1", "table2");
StatsTable humanReadableTable3 = createStatsTableTemplate("keyspace1", "table3");
StatsTable humanReadableTable4 = createStatsTableTemplate("keyspace2", "table4");
StatsTable humanReadableTable5 = createStatsTableTemplate("keyspace2", "table5");
StatsTable humanReadableTable6 = createStatsTableTemplate("keyspace3", "table6");
// human readable space used total: 6 > 5 > 4 > 3 > 2 > 1
humanReadableTable1.spaceUsedTotal = "999 bytes";
humanReadableTable2.spaceUsedTotal = "5 KiB";
humanReadableTable3.spaceUsedTotal = "40 KiB";
humanReadableTable4.spaceUsedTotal = "3 MiB";
humanReadableTable5.spaceUsedTotal = "2 GiB";
humanReadableTable6.spaceUsedTotal = "1 TiB";
// human readable memtable data size: 1 > 3 > 5 > 2 > 4 > 6
humanReadableTable1.memtableDataSize = "1.21 TiB";
humanReadableTable2.memtableDataSize = "42 KiB";
humanReadableTable3.memtableDataSize = "2.71 GiB";
humanReadableTable4.memtableDataSize = "999 bytes";
humanReadableTable5.memtableDataSize = "3.14 MiB";
humanReadableTable6.memtableDataSize = "0 bytes";
// create human readable keyspaces from template
humanReadableKeyspaces = new ArrayList<>();
StatsKeyspace humanReadableKeyspace1 = createStatsKeyspaceTemplate("keyspace1");
StatsKeyspace humanReadableKeyspace2 = createStatsKeyspaceTemplate("keyspace2");
StatsKeyspace humanReadableKeyspace3 = createStatsKeyspaceTemplate("keyspace3");
// populate human readable StatsKeyspace tables lists
humanReadableKeyspace1.tables.add(humanReadableTable1);
humanReadableKeyspace1.tables.add(humanReadableTable2);
humanReadableKeyspace1.tables.add(humanReadableTable3);
humanReadableKeyspace2.tables.add(humanReadableTable4);
humanReadableKeyspace2.tables.add(humanReadableTable5);
humanReadableKeyspace3.tables.add(humanReadableTable6);
// populate human readable keyspaces test vector
humanReadableKeyspaces.add(humanReadableKeyspace1);
humanReadableKeyspaces.add(humanReadableKeyspace2);
humanReadableKeyspaces.add(humanReadableKeyspace3);
// compute human readable keyspace statistics from relevant table metrics
for (int i = 0; i < humanReadableKeyspaces.size(); i++)
{
StatsKeyspace ks = humanReadableKeyspaces.get(i);
for (StatsTable st : ks.tables)
{
ks.readCount += st.localReadCount;
ks.writeCount += st.localWriteCount;
ks.pendingFlushes += (long) st.pendingFlushes;
}
humanReadableKeyspaces.set(i, ks);
}
// populate human readable tables test vector
humanReadableTables = new ArrayList<>();
humanReadableTables.add(humanReadableTable1);
humanReadableTables.add(humanReadableTable2);
humanReadableTables.add(humanReadableTable3);
humanReadableTables.add(humanReadableTable4);
humanReadableTables.add(humanReadableTable5);
humanReadableTables.add(humanReadableTable6);
}
}