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