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