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.rsgroup; 019 020import static org.junit.Assert.assertTrue; 021 022import java.io.IOException; 023import java.util.Collections; 024import org.apache.hadoop.conf.Configuration; 025import org.apache.hadoop.hbase.HBaseClassTestRule; 026import org.apache.hadoop.hbase.HBaseTestingUtil; 027import org.apache.hadoop.hbase.HConstants; 028import org.apache.hadoop.hbase.TableName; 029import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 030import org.apache.hadoop.hbase.client.TableDescriptor; 031import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 032import org.apache.hadoop.hbase.master.assignment.AssignmentTestingUtil; 033import org.apache.hadoop.hbase.net.Address; 034import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility; 035import org.apache.hadoop.hbase.testclassification.MediumTests; 036import org.apache.hadoop.hbase.testclassification.RSGroupTests; 037import org.apache.hadoop.hbase.util.Bytes; 038import org.apache.hadoop.hbase.util.JVMClusterUtil; 039import org.apache.hadoop.hbase.util.Threads; 040import org.junit.After; 041import org.junit.AfterClass; 042import org.junit.Before; 043import org.junit.BeforeClass; 044import org.junit.ClassRule; 045import org.junit.Test; 046import org.junit.experimental.categories.Category; 047import org.slf4j.Logger; 048import org.slf4j.LoggerFactory; 049 050@Category({ RSGroupTests.class, MediumTests.class }) 051public class TestRSGroupsFallback extends TestRSGroupsBase { 052 053 @ClassRule 054 public static final HBaseClassTestRule CLASS_RULE = 055 HBaseClassTestRule.forClass(TestRSGroupsFallback.class); 056 057 protected static final Logger LOG = LoggerFactory.getLogger(TestRSGroupsFallback.class); 058 059 private static final String FALLBACK_GROUP = "fallback"; 060 061 @BeforeClass 062 public static void setUp() throws Exception { 063 Configuration conf = TEST_UTIL.getConfiguration(); 064 conf.setBoolean(RSGroupBasedLoadBalancer.FALLBACK_GROUP_ENABLE_KEY, true); 065 conf.setInt(HConstants.HBASE_BALANCER_MAX_BALANCING, 0); 066 setUpTestBeforeClass(); 067 MASTER.balanceSwitch(true); 068 } 069 070 @AfterClass 071 public static void tearDown() throws Exception { 072 tearDownAfterClass(); 073 } 074 075 @Before 076 public void beforeMethod() throws Exception { 077 setUpBeforeMethod(); 078 } 079 080 @After 081 public void afterMethod() throws Exception { 082 tearDownAfterMethod(); 083 } 084 085 @Test 086 public void testFallback() throws Exception { 087 // add fallback group 088 addGroup(FALLBACK_GROUP, 1); 089 // add test group 090 String groupName = getGroupName(name.getMethodName()); 091 addGroup(groupName, 1); 092 TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName) 093 .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("f")).build()) 094 .setRegionServerGroup(groupName).build(); 095 ADMIN.createTable(desc, HBaseTestingUtil.KEYS_FOR_HBA_CREATE_TABLE); 096 TEST_UTIL.waitUntilAllRegionsAssigned(tableName); 097 // server of test group crash, regions move to default group 098 crashRsInGroup(groupName); 099 assertRegionsInGroup(tableName, RSGroupInfo.DEFAULT_GROUP); 100 101 // server of default group crash, regions move to any other group 102 crashRsInGroup(RSGroupInfo.DEFAULT_GROUP); 103 assertRegionsInGroup(tableName, FALLBACK_GROUP); 104 105 // add a new server to default group, regions move to default group 106 TEST_UTIL.getMiniHBaseCluster().startRegionServerAndWait(60000); 107 assertTrue(MASTER.balance().isBalancerRan()); 108 assertRegionsInGroup(tableName, RSGroupInfo.DEFAULT_GROUP); 109 110 // add a new server to test group, regions move back 111 JVMClusterUtil.RegionServerThread t = 112 TEST_UTIL.getMiniHBaseCluster().startRegionServerAndWait(60000); 113 ADMIN.moveServersToRSGroup( 114 Collections.singleton(t.getRegionServer().getServerName().getAddress()), groupName); 115 assertTrue(MASTER.balance().isBalancerRan()); 116 assertRegionsInGroup(tableName, groupName); 117 118 TEST_UTIL.deleteTable(tableName); 119 } 120 121 private void assertRegionsInGroup(TableName table, String group) throws IOException { 122 ProcedureTestingUtility 123 .waitAllProcedures(TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterProcedureExecutor()); 124 RSGroupInfo rsGroup = ADMIN.getRSGroup(group); 125 MASTER.getAssignmentManager().getRegionStates().getRegionsOfTable(table).forEach(region -> { 126 Address regionOnServer = MASTER.getAssignmentManager().getRegionStates() 127 .getRegionAssignments().get(region).getAddress(); 128 assertTrue(rsGroup.getServers().contains(regionOnServer)); 129 }); 130 } 131 132 private void crashRsInGroup(String groupName) throws Exception { 133 for (Address server : ADMIN.getRSGroup(groupName).getServers()) { 134 AssignmentTestingUtil.crashRs(TEST_UTIL, getServerName(server), true); 135 } 136 Threads.sleep(1000); 137 TEST_UTIL.waitUntilNoRegionsInTransition(60000); 138 } 139}