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.assertNotNull; 022 023import java.io.IOException; 024import java.util.Set; 025import org.apache.hadoop.hbase.HBaseTestingUtility; 026import org.apache.hadoop.hbase.ServerName; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.Waiter; 029import org.apache.hadoop.hbase.Waiter.ExplainingPredicate; 030import org.apache.hadoop.hbase.client.Put; 031import org.apache.hadoop.hbase.client.RegionInfo; 032import org.apache.hadoop.hbase.client.Table; 033import org.apache.hadoop.hbase.master.HMaster; 034import org.apache.hadoop.hbase.master.RegionState.State; 035import org.apache.hadoop.hbase.master.procedure.ProcedureSyncWait; 036import org.apache.hadoop.hbase.util.Bytes; 037import org.apache.hadoop.hbase.util.Threads; 038import org.apache.yetus.audience.InterfaceAudience; 039import org.apache.yetus.audience.InterfaceStability; 040import org.slf4j.Logger; 041import org.slf4j.LoggerFactory; 042 043@InterfaceAudience.Private 044@InterfaceStability.Evolving 045public final class AssignmentTestingUtil { 046 private static final Logger LOG = LoggerFactory.getLogger(AssignmentTestingUtil.class); 047 048 private AssignmentTestingUtil() { 049 } 050 051 public static void waitForRegionToBeInTransition(final HBaseTestingUtility util, 052 final RegionInfo hri) throws Exception { 053 while (!getMaster(util).getAssignmentManager().getRegionStates().isRegionInTransition(hri)) { 054 Threads.sleep(10); 055 } 056 } 057 058 public static void waitForRsToBeDead(final HBaseTestingUtility util, final ServerName serverName) 059 throws Exception { 060 util.waitFor(60000, new ExplainingPredicate<Exception>() { 061 @Override 062 public boolean evaluate() { 063 return getMaster(util).getServerManager().isServerDead(serverName); 064 } 065 066 @Override 067 public String explainFailure() { 068 return "Server " + serverName + " is not dead"; 069 } 070 }); 071 } 072 073 public static void stopRs(final HBaseTestingUtility util, final ServerName serverName) 074 throws Exception { 075 LOG.info("STOP REGION SERVER " + serverName); 076 util.getMiniHBaseCluster().stopRegionServer(serverName); 077 waitForRsToBeDead(util, serverName); 078 } 079 080 public static void killRs(final HBaseTestingUtility util, final ServerName serverName) 081 throws Exception { 082 LOG.info("KILL REGION SERVER " + serverName); 083 util.getMiniHBaseCluster().killRegionServer(serverName); 084 waitForRsToBeDead(util, serverName); 085 } 086 087 public static void crashRs(final HBaseTestingUtility util, final ServerName serverName, 088 final boolean kill) throws Exception { 089 if (kill) { 090 killRs(util, serverName); 091 } else { 092 stopRs(util, serverName); 093 } 094 } 095 096 public static ServerName crashRsWithRegion(final HBaseTestingUtility util, final RegionInfo hri, 097 final boolean kill) throws Exception { 098 ServerName serverName = getServerHoldingRegion(util, hri); 099 crashRs(util, serverName, kill); 100 return serverName; 101 } 102 103 public static ServerName getServerHoldingRegion(final HBaseTestingUtility util, 104 final RegionInfo hri) throws Exception { 105 ServerName serverName = 106 util.getMiniHBaseCluster().getServerHoldingRegion(hri.getTable(), hri.getRegionName()); 107 ServerName amServerName = 108 getMaster(util).getAssignmentManager().getRegionStates().getRegionServerOfRegion(hri); 109 110 // Make sure AM and MiniCluster agrees on the Server holding the region 111 // and that the server is online. 112 assertEquals(amServerName, serverName); 113 assertEquals(true, getMaster(util).getServerManager().isServerOnline(serverName)); 114 return serverName; 115 } 116 117 public static boolean isServerHoldingMeta(final HBaseTestingUtility util, 118 final ServerName serverName) throws Exception { 119 for (RegionInfo hri : getMetaRegions(util)) { 120 if (serverName.equals(getServerHoldingRegion(util, hri))) { 121 return true; 122 } 123 } 124 return false; 125 } 126 127 public static Set<RegionInfo> getMetaRegions(final HBaseTestingUtility util) { 128 return getMaster(util).getAssignmentManager().getMetaRegionSet(); 129 } 130 131 private static HMaster getMaster(final HBaseTestingUtility util) { 132 return util.getMiniHBaseCluster().getMaster(); 133 } 134 135 public static boolean waitForAssignment(AssignmentManager am, RegionInfo regionInfo) 136 throws IOException { 137 // This method can be called before the regionInfo has made it into the regionStateMap 138 // so wait around here a while. 139 Waiter.waitFor(am.getConfiguration(), 10000, 140 () -> am.getRegionStates().getRegionStateNode(regionInfo) != null); 141 RegionStateNode regionNode = am.getRegionStates().getRegionStateNode(regionInfo); 142 // Wait until the region has already been open, or we have a TRSP along with it. 143 Waiter.waitFor(am.getConfiguration(), 30000, 144 () -> regionNode.isInState(State.OPEN) || regionNode.isInTransition()); 145 TransitRegionStateProcedure proc = regionNode.getProcedure(); 146 regionNode.lock(); 147 try { 148 if (regionNode.isInState(State.OPEN)) { 149 return true; 150 } 151 proc = regionNode.getProcedure(); 152 } finally { 153 regionNode.unlock(); 154 } 155 assertNotNull(proc); 156 ProcedureSyncWait.waitForProcedureToCompleteIOE(am.getMaster().getMasterProcedureExecutor(), 157 proc, 5L * 60 * 1000); 158 return true; 159 } 160 161 public static void insertData(final HBaseTestingUtility UTIL, final TableName tableName, 162 int rowCount, int startRowNum, String... cfs) throws IOException { 163 insertData(UTIL, tableName, rowCount, startRowNum, false, cfs); 164 } 165 166 public static void insertData(final HBaseTestingUtility UTIL, final TableName tableName, 167 int rowCount, int startRowNum, boolean flushOnce, String... cfs) throws IOException { 168 Table t = UTIL.getConnection().getTable(tableName); 169 Put p; 170 for (int i = 0; i < rowCount / 2; i++) { 171 p = new Put(Bytes.toBytes("" + (startRowNum + i))); 172 for (String cf : cfs) { 173 p.addColumn(Bytes.toBytes(cf), Bytes.toBytes("q"), Bytes.toBytes(i)); 174 } 175 t.put(p); 176 p = new Put(Bytes.toBytes("" + (startRowNum + rowCount - i - 1))); 177 for (String cf : cfs) { 178 p.addColumn(Bytes.toBytes(cf), Bytes.toBytes("q"), Bytes.toBytes(i)); 179 } 180 t.put(p); 181 if (i % 5 == 0 && !flushOnce) { 182 UTIL.getAdmin().flush(tableName); 183 } 184 } 185 if (flushOnce) { 186 UTIL.getAdmin().flush(tableName); 187 } 188 } 189}