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.client; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertTrue; 023import static org.junit.Assert.fail; 024 025import java.io.IOException; 026import java.util.List; 027import java.util.concurrent.ExecutionException; 028import java.util.concurrent.Future; 029import java.util.concurrent.TimeUnit; 030import org.apache.hadoop.hbase.HBaseClassTestRule; 031import org.apache.hadoop.hbase.HBaseTestingUtility; 032import org.apache.hadoop.hbase.HRegionInfo; 033import org.apache.hadoop.hbase.TableName; 034import org.apache.hadoop.hbase.testclassification.ClientTests; 035import org.apache.hadoop.hbase.testclassification.MediumTests; 036import org.apache.hadoop.hbase.util.Bytes; 037import org.apache.hadoop.hbase.util.Threads; 038import org.junit.AfterClass; 039import org.junit.BeforeClass; 040import org.junit.ClassRule; 041import org.junit.Ignore; 042import org.junit.Rule; 043import org.junit.Test; 044import org.junit.experimental.categories.Category; 045import org.junit.rules.TestName; 046 047@Category({MediumTests.class, ClientTests.class}) 048public class TestSplitOrMergeStatus { 049 050 @ClassRule 051 public static final HBaseClassTestRule CLASS_RULE = 052 HBaseClassTestRule.forClass(TestSplitOrMergeStatus.class); 053 054 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 055 private static byte [] FAMILY = Bytes.toBytes("testFamily"); 056 057 @Rule 058 public TestName name = new TestName(); 059 060 /** 061 * @throws java.lang.Exception 062 */ 063 @BeforeClass 064 public static void setUpBeforeClass() throws Exception { 065 TEST_UTIL.startMiniCluster(2); 066 } 067 068 /** 069 * @throws java.lang.Exception 070 */ 071 @AfterClass 072 public static void tearDownAfterClass() throws Exception { 073 TEST_UTIL.shutdownMiniCluster(); 074 } 075 076 @Test 077 public void testSplitSwitch() throws Exception { 078 final TableName tableName = TableName.valueOf(name.getMethodName()); 079 Table t = TEST_UTIL.createTable(tableName, FAMILY); 080 TEST_UTIL.loadTable(t, FAMILY, false); 081 082 RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(t.getName()); 083 int originalCount = locator.getAllRegionLocations().size(); 084 085 Admin admin = TEST_UTIL.getAdmin(); 086 initSwitchStatus(admin); 087 boolean[] results = admin.setSplitOrMergeEnabled(false, false, MasterSwitchType.SPLIT); 088 assertEquals(1, results.length); 089 assertTrue(results[0]); 090 admin.split(t.getName()); 091 int count = admin.getTableRegions(tableName).size(); 092 assertTrue(originalCount == count); 093 results = admin.setSplitOrMergeEnabled(true, false, MasterSwitchType.SPLIT); 094 assertEquals(1, results.length); 095 assertFalse(results[0]); 096 admin.split(t.getName()); 097 while ((count = admin.getTableRegions(tableName).size()) == originalCount) { 098 Threads.sleep(1);; 099 } 100 count = admin.getTableRegions(tableName).size(); 101 assertTrue(originalCount < count); 102 admin.close(); 103 } 104 105 106 @Ignore @Test 107 public void testMergeSwitch() throws Exception { 108 final TableName tableName = TableName.valueOf(name.getMethodName()); 109 Table t = TEST_UTIL.createTable(tableName, FAMILY); 110 TEST_UTIL.loadTable(t, FAMILY, false); 111 112 Admin admin = TEST_UTIL.getAdmin(); 113 int originalCount = admin.getTableRegions(tableName).size(); 114 initSwitchStatus(admin); 115 admin.split(t.getName()); 116 int postSplitCount = -1; 117 while ((postSplitCount = admin.getTableRegions(tableName).size()) == originalCount) { 118 Threads.sleep(1);; 119 } 120 assertTrue("originalCount=" + originalCount + ", newCount=" + postSplitCount, 121 originalCount != postSplitCount); 122 123 // Merge switch is off so merge should NOT succeed. 124 boolean[] results = admin.setSplitOrMergeEnabled(false, false, MasterSwitchType.MERGE); 125 assertEquals(1, results.length); 126 assertTrue(results[0]); 127 List<HRegionInfo> regions = admin.getTableRegions(t.getName()); 128 assertTrue(regions.size() > 1); 129 Future<?> f = admin.mergeRegionsAsync(regions.get(0).getEncodedNameAsBytes(), 130 regions.get(1).getEncodedNameAsBytes(), true); 131 try { 132 f.get(10, TimeUnit.SECONDS); 133 fail("Should not get here."); 134 } catch (ExecutionException ee) { 135 // Expected. 136 } 137 int count = admin.getTableRegions(tableName).size(); 138 assertTrue("newCount=" + postSplitCount + ", count=" + count, postSplitCount == count); 139 140 results = admin.setSplitOrMergeEnabled(true, false, MasterSwitchType.MERGE); 141 regions = admin.getTableRegions(t.getName()); 142 assertEquals(1, results.length); 143 assertFalse(results[0]); 144 f = admin.mergeRegionsAsync(regions.get(0).getEncodedNameAsBytes(), 145 regions.get(1).getEncodedNameAsBytes(), true); 146 f.get(10, TimeUnit.SECONDS); 147 count = admin.getTableRegions(tableName).size(); 148 assertTrue((postSplitCount / 2 /*Merge*/) == count); 149 admin.close(); 150 } 151 152 @Test 153 public void testMultiSwitches() throws IOException { 154 Admin admin = TEST_UTIL.getAdmin(); 155 boolean[] switches = admin.setSplitOrMergeEnabled(false, false, 156 MasterSwitchType.SPLIT, MasterSwitchType.MERGE); 157 for (boolean s : switches){ 158 assertTrue(s); 159 } 160 assertFalse(admin.isSplitOrMergeEnabled(MasterSwitchType.SPLIT)); 161 assertFalse(admin.isSplitOrMergeEnabled(MasterSwitchType.MERGE)); 162 admin.close(); 163 } 164 165 private void initSwitchStatus(Admin admin) throws IOException { 166 if (!admin.isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) { 167 admin.setSplitOrMergeEnabled(true, false, MasterSwitchType.SPLIT); 168 } 169 if (!admin.isSplitOrMergeEnabled(MasterSwitchType.MERGE)) { 170 admin.setSplitOrMergeEnabled(true, false, MasterSwitchType.MERGE); 171 } 172 assertTrue(admin.isSplitOrMergeEnabled(MasterSwitchType.SPLIT)); 173 assertTrue(admin.isSplitOrMergeEnabled(MasterSwitchType.MERGE)); 174 } 175}