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}