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;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertNotNull;
022import static org.junit.Assert.assertTrue;
023
024import java.util.List;
025import org.apache.hadoop.hbase.HBaseClassTestRule;
026import org.apache.hadoop.hbase.HConstants;
027import org.apache.hadoop.hbase.MiniHBaseCluster;
028import org.apache.hadoop.hbase.ServerName;
029import org.apache.hadoop.hbase.TableName;
030import org.apache.hadoop.hbase.client.RegionInfo;
031import org.apache.hadoop.hbase.testclassification.MasterTests;
032import org.apache.hadoop.hbase.testclassification.MediumTests;
033import org.apache.hadoop.hbase.util.JVMClusterUtil;
034import org.junit.ClassRule;
035import org.junit.Test;
036import org.junit.experimental.categories.Category;
037import org.slf4j.Logger;
038import org.slf4j.LoggerFactory;
039
040@Category({ MasterTests.class, MediumTests.class })
041public class TestRoundRobinAssignmentOnRestart extends AbstractTestRestartCluster {
042
043  @ClassRule
044  public static final HBaseClassTestRule CLASS_RULE =
045    HBaseClassTestRule.forClass(TestRoundRobinAssignmentOnRestart.class);
046
047  private static final Logger LOG =
048    LoggerFactory.getLogger(TestRoundRobinAssignmentOnRestart.class);
049
050  @Override
051  protected boolean splitWALCoordinatedByZk() {
052    return true;
053  }
054
055  private final int regionNum = 10;
056  private final int rsNum = 2;
057
058  /**
059   * This tests retaining assignments on a cluster restart
060   */
061  @Test
062  public void test() throws Exception {
063    UTIL.startMiniCluster(rsNum);
064    // Turn off balancer
065    UTIL.getMiniHBaseCluster().getMaster().getMasterRpcServices().synchronousBalanceSwitch(false);
066    LOG.info("\n\nCreating tables");
067    for (TableName TABLE : TABLES) {
068      UTIL.createMultiRegionTable(TABLE, FAMILY, regionNum);
069    }
070    // Wait until all regions are assigned
071    for (TableName TABLE : TABLES) {
072      UTIL.waitTableEnabled(TABLE);
073    }
074    UTIL.waitUntilNoRegionsInTransition(60000);
075
076    MiniHBaseCluster cluster = UTIL.getHBaseCluster();
077    List<JVMClusterUtil.RegionServerThread> threads = cluster.getLiveRegionServerThreads();
078    assertEquals(2, threads.size());
079
080    ServerName testServer = threads.get(0).getRegionServer().getServerName();
081    int port = testServer.getPort();
082    List<RegionInfo> regionInfos =
083      cluster.getMaster().getAssignmentManager().getRegionsOnServer(testServer);
084    LOG.debug("RegionServer {} has {} regions", testServer, regionInfos.size());
085    assertTrue(regionInfos.size() >= (TABLES.length * regionNum / rsNum));
086
087    // Restart 1 regionserver
088    cluster.stopRegionServer(testServer);
089    cluster.waitForRegionServerToStop(testServer, 60000);
090    cluster.getConf().setInt(HConstants.REGIONSERVER_PORT, port);
091    cluster.startRegionServer();
092
093    HMaster master = UTIL.getMiniHBaseCluster().getMaster();
094    List<ServerName> localServers = master.getServerManager().getOnlineServersList();
095    ServerName newTestServer = null;
096    for (ServerName serverName : localServers) {
097      if (serverName.getAddress().equals(testServer.getAddress())) {
098        newTestServer = serverName;
099        break;
100      }
101    }
102    assertNotNull(newTestServer);
103
104    // Wait until all regions are assigned
105    for (TableName TABLE : TABLES) {
106      UTIL.waitTableAvailable(TABLE);
107    }
108    UTIL.waitUntilNoRegionsInTransition(60000);
109
110    List<RegionInfo> newRegionInfos =
111      cluster.getMaster().getAssignmentManager().getRegionsOnServer(newTestServer);
112    LOG.debug("RegionServer {} has {} regions", newTestServer, newRegionInfos.size());
113    assertTrue("Should not retain all regions when restart",
114      newRegionInfos.size() < regionInfos.size());
115  }
116}