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.master;
019
020import static org.apache.hadoop.hbase.regionserver.HRegion.warmupHRegion;
021import static org.junit.Assert.assertTrue;
022
023import java.io.IOException;
024import org.apache.hadoop.hbase.HBaseClassTestRule;
025import org.apache.hadoop.hbase.HBaseTestingUtility;
026import org.apache.hadoop.hbase.HTableDescriptor;
027import org.apache.hadoop.hbase.MiniHBaseCluster;
028import org.apache.hadoop.hbase.TableName;
029import org.apache.hadoop.hbase.Waiter;
030import org.apache.hadoop.hbase.client.CompactionState;
031import org.apache.hadoop.hbase.client.Put;
032import org.apache.hadoop.hbase.client.RegionInfo;
033import org.apache.hadoop.hbase.client.Table;
034import org.apache.hadoop.hbase.client.TableDescriptor;
035import org.apache.hadoop.hbase.regionserver.HRegion;
036import org.apache.hadoop.hbase.regionserver.HRegionServer;
037import org.apache.hadoop.hbase.testclassification.LargeTests;
038import org.apache.hadoop.hbase.testclassification.MasterTests;
039import org.apache.hadoop.hbase.util.Bytes;
040import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
041import org.junit.After;
042import org.junit.AfterClass;
043import org.junit.Before;
044import org.junit.BeforeClass;
045import org.junit.ClassRule;
046import org.junit.Test;
047import org.junit.experimental.categories.Category;
048import org.slf4j.Logger;
049import org.slf4j.LoggerFactory;
050
051/**
052 * Run tests that use the HBase clients; {@link org.apache.hadoop.hbase.client.TableBuilder}. Sets
053 * up the HBase mini cluster once at start and runs through all client tests. Each creates a table
054 * named for the method and does its stuff against that.
055 */
056@Category({ MasterTests.class, LargeTests.class })
057public class TestWarmupRegion {
058
059  @ClassRule
060  public static final HBaseClassTestRule CLASS_RULE =
061    HBaseClassTestRule.forClass(TestWarmupRegion.class);
062
063  private static final Logger LOG = LoggerFactory.getLogger(TestWarmupRegion.class);
064  protected TableName TABLENAME = TableName.valueOf("testPurgeFutureDeletes");
065  protected final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
066  private static byte[] ROW = Bytes.toBytes("testRow");
067  private static byte[] FAMILY = Bytes.toBytes("testFamily");
068  private static byte[] VALUE = Bytes.toBytes("testValue");
069  private static byte[] COLUMN = Bytes.toBytes("column");
070  private static int numRows = 10000;
071  protected static int SLAVES = 3;
072  private static MiniHBaseCluster myCluster;
073  private static Table table;
074
075  /**
076   * @throws java.lang.Exception
077   */
078  @BeforeClass
079  public static void setUpBeforeClass() throws Exception {
080    TEST_UTIL.startMiniCluster(SLAVES);
081  }
082
083  /**
084   * @throws java.lang.Exception
085   */
086  @AfterClass
087  public static void tearDownAfterClass() throws Exception {
088    TEST_UTIL.shutdownMiniCluster();
089  }
090
091  /**
092   * @throws java.lang.Exception
093   */
094  @Before
095  public void setUp() throws Exception {
096    table = TEST_UTIL.createTable(TABLENAME, FAMILY);
097
098    // future timestamp
099    for (int i = 0; i < numRows; i++) {
100      long ts = EnvironmentEdgeManager.currentTime() * 2;
101      Put put = new Put(ROW, ts);
102      put.addColumn(FAMILY, COLUMN, VALUE);
103      table.put(put);
104    }
105
106    // major compaction, purged future deletes
107    TEST_UTIL.getAdmin().flush(TABLENAME);
108    TEST_UTIL.getAdmin().majorCompact(TABLENAME);
109
110    // waiting for the major compaction to complete
111    TEST_UTIL.waitFor(6000, new Waiter.Predicate<IOException>() {
112      @Override
113      public boolean evaluate() throws IOException {
114        return TEST_UTIL.getAdmin().getCompactionState(TABLENAME) == CompactionState.NONE;
115      }
116    });
117
118    table.close();
119  }
120
121  /**
122   * @throws java.lang.Exception
123   */
124  @After
125  public void tearDown() throws Exception {
126    TEST_UTIL.deleteTable(TABLENAME);
127  }
128
129  protected void runwarmup() throws InterruptedException {
130    Thread thread = new Thread(new Runnable() {
131      @Override
132      public void run() {
133        HRegionServer rs = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0);
134        HRegion region = TEST_UTIL.getMiniHBaseCluster().getRegions(TABLENAME).get(0);
135        RegionInfo info = region.getRegionInfo();
136
137        try {
138          HTableDescriptor htd = table.getTableDescriptor();
139          for (int i = 0; i < 10; i++) {
140            warmupHRegion(info, htd, rs.getWAL(info), rs.getConfiguration(), rs, null);
141          }
142
143        } catch (IOException ie) {
144          LOG.error("Failed warming up region " + info.getRegionNameAsString(), ie);
145        }
146      }
147    });
148    thread.start();
149    thread.join();
150  }
151
152  /**
153   * Basic client side validation of HBASE-4536
154   */
155  @Test
156  public void testWarmup() throws Exception {
157    int serverid = 0;
158    HRegion region = TEST_UTIL.getMiniHBaseCluster().getRegions(TABLENAME).get(0);
159    RegionInfo info = region.getRegionInfo();
160    runwarmup();
161    for (int i = 0; i < 10; i++) {
162      HRegionServer rs = TEST_UTIL.getMiniHBaseCluster().getRegionServer(serverid);
163      byte[] destName = Bytes.toBytes(rs.getServerName().toString());
164      assertTrue(destName != null);
165      LOG.info("i=" + i);
166      TEST_UTIL.getMiniHBaseCluster().getMaster().move(info.getEncodedNameAsBytes(), destName);
167      serverid = (serverid + 1) % 2;
168    }
169  }
170
171  @Test
172  public void testWarmupAndClose() throws IOException {
173    HRegionServer rs = TEST_UTIL.getMiniHBaseCluster().getRegionServer(0);
174    HRegion region = TEST_UTIL.getMiniHBaseCluster().getRegions(TABLENAME).get(0);
175    RegionInfo info = region.getRegionInfo();
176
177    TableDescriptor htd = table.getDescriptor();
178    HRegion warmedUpRegion =
179      warmupHRegion(info, htd, rs.getWAL(info), rs.getConfiguration(), rs, null);
180    assertTrue(warmedUpRegion.isClosed());
181  }
182}