001/**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019package org.apache.hadoop.hbase.master.assignment;
020
021import java.io.IOException;
022import java.util.ArrayList;
023import java.util.List;
024
025import org.apache.hadoop.conf.Configuration;
026import org.apache.hadoop.hbase.HBaseClassTestRule;
027import org.apache.hadoop.hbase.HBaseTestingUtility;
028import org.apache.hadoop.hbase.HConstants;
029import org.apache.hadoop.hbase.TableName;
030import org.apache.hadoop.hbase.client.RegionInfo;
031import org.apache.hadoop.hbase.client.RegionReplicaTestHelper;
032import org.apache.hadoop.hbase.client.Table;
033import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
034import org.apache.hadoop.hbase.regionserver.HRegionServer;
035import org.apache.hadoop.hbase.regionserver.Region;
036import org.apache.hadoop.hbase.testclassification.LargeTests;
037import org.apache.hadoop.hbase.testclassification.RegionServerTests;
038import org.apache.hadoop.hbase.util.Bytes;
039import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
040import org.apache.hadoop.hbase.util.RegionSplitter;
041import org.junit.AfterClass;
042import org.junit.BeforeClass;
043import org.junit.ClassRule;
044import org.junit.Rule;
045import org.junit.Test;
046import org.junit.experimental.categories.Category;
047import org.junit.rules.TestName;
048import org.slf4j.Logger;
049import org.slf4j.LoggerFactory;
050
051@Category({ RegionServerTests.class, LargeTests.class })
052public class TestRegionReplicaSplit {
053  @ClassRule
054  public static final HBaseClassTestRule CLASS_RULE =
055      HBaseClassTestRule.forClass(TestRegionReplicaSplit.class);
056  private static final Logger LOG = LoggerFactory.getLogger(TestRegionReplicaSplit.class);
057
058  private static final int NB_SERVERS = 4;
059  private static Table table;
060
061  private static final HBaseTestingUtility HTU = new HBaseTestingUtility();
062  private static final byte[] f = HConstants.CATALOG_FAMILY;
063
064  @BeforeClass
065  public static void beforeClass() throws Exception {
066    HTU.getConfiguration().setInt("hbase.master.wait.on.regionservers.mintostart", 3);
067    HTU.startMiniCluster(NB_SERVERS);
068    final TableName tableName = TableName.valueOf(TestRegionReplicaSplit.class.getSimpleName());
069
070    // Create table then get the single region for our new table.
071    createTable(tableName);
072  }
073
074  @Rule
075  public TestName name = new TestName();
076
077  private static void createTable(final TableName tableName) throws IOException {
078    TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName);
079    builder.setRegionReplication(3);
080    // create a table with 3 replication
081    table = HTU.createTable(builder.build(), new byte[][] { f }, getSplits(2),
082      new Configuration(HTU.getConfiguration()));
083  }
084
085  private static byte[][] getSplits(int numRegions) {
086    RegionSplitter.UniformSplit split = new RegionSplitter.UniformSplit();
087    split.setFirstRow(Bytes.toBytes(0L));
088    split.setLastRow(Bytes.toBytes(Long.MAX_VALUE));
089    return split.split(numRegions);
090  }
091
092  @AfterClass
093  public static void afterClass() throws Exception {
094    HRegionServer.TEST_SKIP_REPORTING_TRANSITION = false;
095    table.close();
096    HTU.shutdownMiniCluster();
097  }
098
099  @Test
100  public void testRegionReplicaSplitRegionAssignment() throws Exception {
101    HTU.loadNumericRows(table, f, 0, 3);
102    // split the table
103    List<RegionInfo> regions = new ArrayList<RegionInfo>();
104    for (RegionServerThread rs : HTU.getMiniHBaseCluster().getRegionServerThreads()) {
105      for (Region r : rs.getRegionServer().getRegions(table.getName())) {
106        regions.add(r.getRegionInfo());
107      }
108    }
109    // There are 6 regions before split, 9 regions after split.
110    HTU.getAdmin().split(table.getName(), Bytes.toBytes(1));
111    int count = 0;
112    while (true) {
113      for (RegionServerThread rs : HTU.getMiniHBaseCluster().getRegionServerThreads()) {
114        for (Region r : rs.getRegionServer().getRegions(table.getName())) {
115          count++;
116        }
117      }
118      if (count >= 9) {
119        break;
120      }
121      count = 0;
122    }
123
124    RegionReplicaTestHelper.assertReplicaDistributed(HTU, table);
125  }
126}