001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.regionserver;
019
020import static org.junit.jupiter.api.Assertions.assertEquals;
021import static org.mockito.Mockito.mock;
022import static org.mockito.Mockito.when;
023
024import java.io.IOException;
025import java.util.List;
026import java.util.OptionalDouble;
027import java.util.OptionalLong;
028import org.apache.hadoop.conf.Configuration;
029import org.apache.hadoop.hbase.HBaseConfiguration;
030import org.apache.hadoop.hbase.HConstants;
031import org.apache.hadoop.hbase.TableName;
032import org.apache.hadoop.hbase.client.TableDescriptor;
033import org.apache.hadoop.hbase.testclassification.RegionServerTests;
034import org.apache.hadoop.hbase.testclassification.SmallTests;
035import org.junit.jupiter.api.Tag;
036import org.junit.jupiter.api.Test;
037
038import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
039
040@Tag(SmallTests.TAG)
041@Tag(RegionServerTests.TAG)
042public class TestMetricsTableWrapperAggregate {
043
044  private static final TableName TABLE = TableName.valueOf("table1");
045
046  @Test
047  public void testAvgStoreFileAgeAccumulatesAcrossStores() throws IOException {
048    // Two regions of the same table, three stores in total; per store: (count, avg, max, min).
049    HStore storeA = getMockedStore("cf1", 2, 10.0, 15, 5);
050    HStore storeB = getMockedStore("cf2", 3, 20.0, 30, 1);
051    HStore storeC = getMockedStore("cf3", 5, 4.0, 8, 2);
052
053    HRegion region1 = getMockedRegion(Lists.newArrayList(storeA, storeB));
054    HRegion region2 = getMockedRegion(Lists.newArrayList(storeC));
055    List<HRegion> regions = Lists.newArrayList(region1, region2);
056
057    Configuration conf = HBaseConfiguration.create();
058    // Long period so the scheduled task never fires; we drive the aggregation manually.
059    conf.setLong(HConstants.REGIONSERVER_METRICS_PERIOD, 600 * 1000);
060
061    HRegionServer regionServer = mock(HRegionServer.class);
062    when(regionServer.getConfiguration()).thenReturn(conf);
063    when(regionServer.getOnlineRegionsLocalContext()).thenReturn(regions);
064
065    MetricsTableWrapperAggregateImpl wrapper = new MetricsTableWrapperAggregateImpl(regionServer);
066    try {
067      MetricsTableWrapperAggregateImpl.TableMetricsWrapperRunnable runnable =
068        wrapper.new TableMetricsWrapperRunnable();
069      runnable.run();
070
071      String table = TABLE.getNameAsString();
072      // avg = (10*2 + 20*3 + 4*5) / (2 + 3 + 5) = 100 / 10 = 10.
073      assertEquals(10, wrapper.getAvgStoreFileAge(table));
074      assertEquals(10, wrapper.getNumStoreFiles(table));
075      assertEquals(30, wrapper.getMaxStoreFileAge(table));
076      assertEquals(1, wrapper.getMinStoreFileAge(table));
077      assertEquals(3, wrapper.getNumStores(table));
078      assertEquals(2, wrapper.getNumRegions(table));
079    } finally {
080      wrapper.close();
081    }
082  }
083
084  private HRegion getMockedRegion(List<HStore> stores) {
085    TableDescriptor descriptor = mock(TableDescriptor.class);
086    when(descriptor.getTableName()).thenReturn(TABLE);
087    HRegion region = mock(HRegion.class);
088    when(region.getTableDescriptor()).thenReturn(descriptor);
089    when(region.getStores()).thenReturn(stores);
090    return region;
091  }
092
093  private HStore getMockedStore(String family, int storeFileCount, double avgStoreFileAge,
094    long maxStoreFileAge, long minStoreFileAge) {
095    HStore store = mock(HStore.class);
096    when(store.getColumnFamilyName()).thenReturn(family);
097    when(store.getStorefilesCount()).thenReturn(storeFileCount);
098    when(store.getAvgStoreFileAge()).thenReturn(OptionalDouble.of(avgStoreFileAge));
099    when(store.getMaxStoreFileAge()).thenReturn(OptionalLong.of(maxStoreFileAge));
100    when(store.getMinStoreFileAge()).thenReturn(OptionalLong.of(minStoreFileAge));
101    when(store.getMemStoreSize()).thenReturn(mock(MemStoreSize.class));
102    return store;
103  }
104}