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