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.assignment; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertTrue; 022import java.io.IOException; 023import org.apache.hadoop.conf.Configuration; 024import org.apache.hadoop.hbase.HBaseClassTestRule; 025import org.apache.hadoop.hbase.HBaseTestingUtility; 026import org.apache.hadoop.hbase.StartMiniClusterOption; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.client.Put; 029import org.apache.hadoop.hbase.client.RegionInfo; 030import org.apache.hadoop.hbase.client.Table; 031import org.apache.hadoop.hbase.client.TableDescriptor; 032import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv; 033import org.apache.hadoop.hbase.master.procedure.MasterProcedureTestingUtility; 034import org.apache.hadoop.hbase.procedure2.ProcedureExecutor; 035import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility; 036import org.apache.hadoop.hbase.testclassification.MasterTests; 037import org.apache.hadoop.hbase.testclassification.MediumTests; 038import org.apache.hadoop.hbase.util.Bytes; 039import org.apache.hadoop.hbase.util.JVMClusterUtil; 040import org.junit.After; 041import org.junit.AfterClass; 042import org.junit.Before; 043import org.junit.BeforeClass; 044import org.junit.ClassRule; 045import org.junit.Rule; 046import org.junit.Test; 047import org.junit.experimental.categories.Category; 048import org.junit.rules.TestName; 049import org.slf4j.Logger; 050import org.slf4j.LoggerFactory; 051 052@Category({MasterTests.class, MediumTests.class}) 053public class TestRegionSplit { 054 055 @ClassRule 056 public static final HBaseClassTestRule CLASS_RULE = 057 HBaseClassTestRule.forClass(TestRegionSplit.class); 058 059 private static final Logger LOG = LoggerFactory.getLogger(TestRegionSplit.class); 060 061 protected static final HBaseTestingUtility UTIL = new HBaseTestingUtility(); 062 063 private static String ColumnFamilyName = "cf"; 064 065 private static final int startRowNum = 11; 066 private static final int rowCount = 60; 067 068 @Rule 069 public TestName name = new TestName(); 070 071 private static void setupConf(Configuration conf) { 072 } 073 074 @BeforeClass 075 public static void setupCluster() throws Exception { 076 setupConf(UTIL.getConfiguration()); 077 StartMiniClusterOption option = 078 StartMiniClusterOption.builder().numMasters(1).numRegionServers(3).numDataNodes(3).build(); 079 UTIL.startMiniCluster(option); 080 } 081 082 @AfterClass 083 public static void cleanupTest() throws Exception { 084 try { 085 UTIL.shutdownMiniCluster(); 086 } catch (Exception e) { 087 LOG.warn("failure shutting down cluster", e); 088 } 089 } 090 091 @Before 092 public void setup() throws Exception { 093 // Turn off the meta scanner so it don't remove parent on us. 094 UTIL.getHBaseCluster().getMaster().setCatalogJanitorEnabled(false); 095 // Disable compaction. 096 for (int i = 0; i < UTIL.getHBaseCluster().getLiveRegionServerThreads().size(); i++) { 097 UTIL.getHBaseCluster().getRegionServer(i).getCompactSplitThread().switchCompaction(false); 098 } 099 } 100 101 @After 102 public void tearDown() throws Exception { 103 for (TableDescriptor htd : UTIL.getAdmin().listTableDescriptors()) { 104 UTIL.deleteTable(htd.getTableName()); 105 } 106 } 107 108 @Test 109 public void testSplitTableRegion() throws Exception { 110 final TableName tableName = TableName.valueOf(name.getMethodName()); 111 final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor(); 112 113 RegionInfo[] regions = 114 MasterProcedureTestingUtility.createTable(procExec, tableName, null, ColumnFamilyName); 115 insertData(tableName); 116 int splitRowNum = startRowNum + rowCount / 2; 117 byte[] splitKey = Bytes.toBytes("" + splitRowNum); 118 119 assertTrue("not able to find a splittable region", regions != null); 120 assertTrue("not able to find a splittable region", regions.length == 1); 121 122 // Split region of the table 123 long procId = procExec.submitProcedure( 124 new SplitTableRegionProcedure(procExec.getEnvironment(), regions[0], splitKey)); 125 // Wait the completion 126 ProcedureTestingUtility.waitProcedure(procExec, procId); 127 ProcedureTestingUtility.assertProcNotFailed(procExec, procId); 128 129 assertTrue("not able to split table", UTIL.getHBaseCluster().getRegions(tableName).size() == 2); 130 131 //disable table 132 UTIL.getAdmin().disableTable(tableName); 133 Thread.sleep(500); 134 135 //stop master 136 UTIL.getHBaseCluster().stopMaster(0); 137 UTIL.getHBaseCluster().waitOnMaster(0); 138 Thread.sleep(500); 139 140 //restart master 141 JVMClusterUtil.MasterThread t = UTIL.getHBaseCluster().startMaster(); 142 Thread.sleep(500); 143 144 UTIL.invalidateConnection(); 145 // enable table 146 UTIL.getAdmin().enableTable(tableName); 147 Thread.sleep(500); 148 149 assertEquals("Table region not correct.", 2, 150 UTIL.getHBaseCluster().getRegions(tableName).size()); 151 } 152 153 private void insertData(final TableName tableName) throws IOException { 154 Table t = UTIL.getConnection().getTable(tableName); 155 Put p; 156 for (int i = 0; i < rowCount / 2; i++) { 157 p = new Put(Bytes.toBytes("" + (startRowNum + i))); 158 p.addColumn(Bytes.toBytes(ColumnFamilyName), Bytes.toBytes("q1"), Bytes.toBytes(i)); 159 t.put(p); 160 p = new Put(Bytes.toBytes("" + (startRowNum + rowCount - i - 1))); 161 p.addColumn(Bytes.toBytes(ColumnFamilyName), Bytes.toBytes("q1"), Bytes.toBytes(i)); 162 t.put(p); 163 } 164 UTIL.getAdmin().flush(tableName); 165 } 166 167 private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() { 168 return UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor(); 169 } 170}