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