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.quotas;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertNotNull;
022import static org.junit.Assert.assertTrue;
023import static org.mockito.Mockito.mock;
024import static org.mockito.Mockito.when;
025
026import java.util.Arrays;
027import java.util.Collections;
028import java.util.HashSet;
029import java.util.concurrent.TimeUnit;
030import org.apache.hadoop.conf.Configuration;
031import org.apache.hadoop.hbase.HBaseClassTestRule;
032import org.apache.hadoop.hbase.HBaseConfiguration;
033import org.apache.hadoop.hbase.TableName;
034import org.apache.hadoop.hbase.client.RegionInfo;
035import org.apache.hadoop.hbase.client.RegionInfoBuilder;
036import org.apache.hadoop.hbase.regionserver.HRegionServer;
037import org.apache.hadoop.hbase.testclassification.SmallTests;
038import org.apache.hadoop.hbase.util.Bytes;
039import org.junit.ClassRule;
040import org.junit.Test;
041import org.junit.experimental.categories.Category;
042
043@Category({ SmallTests.class })
044public class TestRegionSizeReportingChore {
045  @ClassRule
046  public static final HBaseClassTestRule CLASS_RULE =
047    HBaseClassTestRule.forClass(TestRegionSizeReportingChore.class);
048
049  @Test
050  public void testDefaultConfigurationProperties() {
051    final Configuration conf = getDefaultHBaseConfiguration();
052    final HRegionServer rs = mockRegionServer(conf);
053    RegionSizeReportingChore chore = new RegionSizeReportingChore(rs);
054    assertEquals(RegionSizeReportingChore.REGION_SIZE_REPORTING_CHORE_DELAY_DEFAULT,
055      chore.getInitialDelay());
056    assertEquals(RegionSizeReportingChore.REGION_SIZE_REPORTING_CHORE_PERIOD_DEFAULT,
057      chore.getPeriod());
058    assertEquals(
059      TimeUnit.valueOf(RegionSizeReportingChore.REGION_SIZE_REPORTING_CHORE_TIMEUNIT_DEFAULT),
060      chore.getTimeUnit());
061  }
062
063  @Test
064  public void testNonDefaultConfigurationProperties() {
065    final Configuration conf = getDefaultHBaseConfiguration();
066    final HRegionServer rs = mockRegionServer(conf);
067    final int period = RegionSizeReportingChore.REGION_SIZE_REPORTING_CHORE_PERIOD_DEFAULT + 1;
068    final long delay = RegionSizeReportingChore.REGION_SIZE_REPORTING_CHORE_DELAY_DEFAULT + 1L;
069    final String timeUnit = TimeUnit.SECONDS.name();
070    conf.setInt(RegionSizeReportingChore.REGION_SIZE_REPORTING_CHORE_PERIOD_KEY, period);
071    conf.setLong(RegionSizeReportingChore.REGION_SIZE_REPORTING_CHORE_DELAY_KEY, delay);
072    conf.set(RegionSizeReportingChore.REGION_SIZE_REPORTING_CHORE_TIMEUNIT_KEY, timeUnit);
073    RegionSizeReportingChore chore = new RegionSizeReportingChore(rs);
074    assertEquals(delay, chore.getInitialDelay());
075    assertEquals(period, chore.getPeriod());
076    assertEquals(TimeUnit.valueOf(timeUnit), chore.getTimeUnit());
077  }
078
079  @Test
080  public void testRemovableOfNonOnlineRegions() {
081    final Configuration conf = getDefaultHBaseConfiguration();
082    final HRegionServer rs = mockRegionServer(conf);
083    RegionSizeReportingChore chore = new RegionSizeReportingChore(rs);
084
085    RegionInfo infoA = RegionInfoBuilder.newBuilder(TableName.valueOf("T1"))
086      .setStartKey(Bytes.toBytes("a")).setEndKey(Bytes.toBytes("b")).build();
087    RegionInfo infoB = RegionInfoBuilder.newBuilder(TableName.valueOf("T1"))
088      .setStartKey(Bytes.toBytes("b")).setEndKey(Bytes.toBytes("d")).build();
089    RegionInfo infoC = RegionInfoBuilder.newBuilder(TableName.valueOf("T1"))
090      .setStartKey(Bytes.toBytes("c")).setEndKey(Bytes.toBytes("d")).build();
091
092    RegionSizeStore store = new RegionSizeStoreImpl();
093    store.put(infoA, 1024L);
094    store.put(infoB, 1024L);
095    store.put(infoC, 1024L);
096
097    // If there are no online regions, all entries should be removed.
098    chore.removeNonOnlineRegions(store, Collections.<RegionInfo> emptySet());
099    assertTrue(store.isEmpty());
100
101    store.put(infoA, 1024L);
102    store.put(infoB, 1024L);
103    store.put(infoC, 1024L);
104
105    // Remove a single region
106    chore.removeNonOnlineRegions(store, new HashSet<>(Arrays.asList(infoA, infoC)));
107    assertEquals(2, store.size());
108    assertNotNull(store.getRegionSize(infoA));
109    assertNotNull(store.getRegionSize(infoC));
110  }
111
112  /**
113   * Creates an HBase Configuration object for the default values.
114   */
115  private Configuration getDefaultHBaseConfiguration() {
116    final Configuration conf = HBaseConfiguration.create();
117    conf.addResource("hbase-default.xml");
118    return conf;
119  }
120
121  private HRegionServer mockRegionServer(Configuration conf) {
122    HRegionServer rs = mock(HRegionServer.class);
123    when(rs.getConfiguration()).thenReturn(conf);
124    return rs;
125  }
126}