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.regionserver; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertTrue; 023 024import java.io.IOException; 025import java.util.ArrayList; 026import java.util.Collection; 027 028import org.apache.hadoop.conf.Configuration; 029import org.apache.hadoop.hbase.HBaseClassTestRule; 030import org.apache.hadoop.hbase.HBaseTestingUtility; 031import org.apache.hadoop.hbase.HConstants; 032import org.apache.hadoop.hbase.ServerName; 033import org.apache.hadoop.hbase.TableName; 034import org.apache.hadoop.hbase.client.RegionInfo; 035import org.apache.hadoop.hbase.client.RegionReplicaUtil; 036import org.apache.hadoop.hbase.client.Table; 037import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 038import org.apache.hadoop.hbase.testclassification.MediumTests; 039import org.apache.hadoop.hbase.testclassification.RegionServerTests; 040import org.apache.hadoop.hbase.util.Bytes; 041import org.apache.hadoop.hbase.util.RegionSplitter; 042import org.junit.After; 043import org.junit.AfterClass; 044import org.junit.Before; 045import org.junit.BeforeClass; 046import org.junit.ClassRule; 047import org.junit.Rule; 048import org.junit.Test; 049import org.junit.experimental.categories.Category; 050import org.junit.rules.TestName; 051import org.slf4j.Logger; 052import org.slf4j.LoggerFactory; 053 054@Category({RegionServerTests.class, MediumTests.class}) 055public class TestRegionReplicasWithRestartScenarios { 056 057 @ClassRule 058 public static final HBaseClassTestRule CLASS_RULE = 059 HBaseClassTestRule.forClass(TestRegionReplicasWithRestartScenarios.class); 060 061 private static final Logger LOG = 062 LoggerFactory.getLogger(TestRegionReplicasWithRestartScenarios.class); 063 064 @Rule public TestName name = new TestName(); 065 066 private static final int NB_SERVERS = 3; 067 private Table table; 068 private TableName tableName; 069 070 private static final HBaseTestingUtility HTU = new HBaseTestingUtility(); 071 private static final byte[] f = HConstants.CATALOG_FAMILY; 072 073 @BeforeClass 074 public static void beforeClass() throws Exception { 075 HTU.getConfiguration().setInt("hbase.master.wait.on.regionservers.mintostart", NB_SERVERS); 076 HTU.startMiniCluster(NB_SERVERS); 077 } 078 079 @Before 080 public void before() throws IOException { 081 this.tableName = TableName.valueOf(this.name.getMethodName()); 082 this.table = createTableDirectlyFromHTD(this.tableName); 083 } 084 085 @After 086 public void after() throws IOException { 087 this.table.close(); 088 HTU.deleteTable(this.tableName); 089 } 090 091 private static Table createTableDirectlyFromHTD(final TableName tableName) throws IOException { 092 TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName); 093 builder.setRegionReplication(3); 094 return HTU.createTable(builder.build(), new byte[][] { f }, getSplits(20), 095 new Configuration(HTU.getConfiguration())); 096 } 097 098 private static byte[][] getSplits(int numRegions) { 099 RegionSplitter.UniformSplit split = new RegionSplitter.UniformSplit(); 100 split.setFirstRow(Bytes.toBytes(0L)); 101 split.setLastRow(Bytes.toBytes(Long.MAX_VALUE)); 102 return split.split(numRegions); 103 } 104 105 @AfterClass 106 public static void afterClass() throws Exception { 107 HRegionServer.TEST_SKIP_REPORTING_TRANSITION = false; 108 HTU.shutdownMiniCluster(); 109 } 110 111 private HRegionServer getRS() { 112 return HTU.getMiniHBaseCluster().getRegionServer(0); 113 } 114 115 private HRegionServer getSecondaryRS() { 116 return HTU.getMiniHBaseCluster().getRegionServer(1); 117 } 118 119 private HRegionServer getTertiaryRS() { 120 return HTU.getMiniHBaseCluster().getRegionServer(2); 121 } 122 123 @Test 124 public void testRegionReplicasCreated() throws Exception { 125 assertReplicaDistributed(); 126 } 127 128 @Test 129 public void testWhenRestart() throws Exception { 130 ServerName serverName = getRS().getServerName(); 131 HTU.getHBaseCluster().stopRegionServer(serverName); 132 HTU.getHBaseCluster().waitForRegionServerToStop(serverName, 60000); 133 HTU.getHBaseCluster().startRegionServerAndWait(60000); 134 HTU.waitTableAvailable(this.tableName); 135 assertReplicaDistributed(); 136 } 137 138 private void assertReplicaDistributed() throws Exception { 139 Collection<HRegion> onlineRegions = getRS().getOnlineRegionsLocalContext(); 140 boolean res = checkDuplicates(onlineRegions); 141 assertFalse(res); 142 Collection<HRegion> onlineRegions2 = getSecondaryRS().getOnlineRegionsLocalContext(); 143 res = checkDuplicates(onlineRegions2); 144 assertFalse(res); 145 Collection<HRegion> onlineRegions3 = getTertiaryRS().getOnlineRegionsLocalContext(); 146 checkDuplicates(onlineRegions3); 147 assertFalse(res); 148 int totalRegions = onlineRegions.size() + onlineRegions2.size() + onlineRegions3.size(); 149 assertEquals(62, totalRegions); 150 } 151 152 private boolean checkDuplicates(Collection<HRegion> onlineRegions3) throws Exception { 153 ArrayList<Region> copyOfRegion = new ArrayList<Region>(onlineRegions3); 154 for (Region region : copyOfRegion) { 155 RegionInfo regionInfo = region.getRegionInfo(); 156 RegionInfo regionInfoForReplica = 157 RegionReplicaUtil.getRegionInfoForDefaultReplica(regionInfo); 158 int i = 0; 159 for (Region actualRegion : onlineRegions3) { 160 if (regionInfoForReplica.equals( 161 RegionReplicaUtil.getRegionInfoForDefaultReplica(actualRegion.getRegionInfo()))) { 162 i++; 163 if (i > 1) { 164 LOG.warn("Duplicate found {} and {}", actualRegion.getRegionInfo(), 165 region.getRegionInfo()); 166 assertTrue(Bytes.equals(region.getRegionInfo().getStartKey(), 167 actualRegion.getRegionInfo().getStartKey())); 168 assertTrue(Bytes.equals(region.getRegionInfo().getEndKey(), 169 actualRegion.getRegionInfo().getEndKey())); 170 return true; 171 } 172 } 173 } 174 } 175 return false; 176 } 177}