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.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertTrue; 023 024import java.io.IOException; 025import java.util.List; 026import java.util.Set; 027import org.apache.hadoop.hbase.HBaseClassTestRule; 028import org.apache.hadoop.hbase.NamespaceDescriptor; 029import org.apache.hadoop.hbase.ServerName; 030import org.apache.hadoop.hbase.TableName; 031import org.apache.hadoop.hbase.Waiter; 032import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 033import org.apache.hadoop.hbase.client.TableDescriptor; 034import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 035import org.apache.hadoop.hbase.net.Address; 036import org.apache.hadoop.hbase.quotas.QuotaTableUtil; 037import org.apache.hadoop.hbase.testclassification.MediumTests; 038import org.apache.hadoop.hbase.testclassification.RSGroupTests; 039import org.apache.hadoop.hbase.util.Bytes; 040import org.junit.After; 041import org.junit.AfterClass; 042import org.junit.Assert; 043import org.junit.Before; 044import org.junit.BeforeClass; 045import org.junit.ClassRule; 046import org.junit.Test; 047import org.junit.experimental.categories.Category; 048import org.slf4j.Logger; 049import org.slf4j.LoggerFactory; 050 051import org.apache.hbase.thirdparty.com.google.common.collect.Lists; 052 053@Category({ RSGroupTests.class, MediumTests.class }) 054public class TestRSGroupsBasics extends TestRSGroupsBase { 055 056 @ClassRule 057 public static final HBaseClassTestRule CLASS_RULE = 058 HBaseClassTestRule.forClass(TestRSGroupsBasics.class); 059 060 protected static final Logger LOG = LoggerFactory.getLogger(TestRSGroupsBasics.class); 061 062 @BeforeClass 063 public static void setUp() throws Exception { 064 setUpTestBeforeClass(); 065 } 066 067 @AfterClass 068 public static void tearDown() throws Exception { 069 tearDownAfterClass(); 070 } 071 072 @Before 073 public void beforeMethod() throws Exception { 074 setUpBeforeMethod(); 075 } 076 077 @After 078 public void afterMethod() throws Exception { 079 tearDownAfterMethod(); 080 } 081 082 @Test 083 public void testBasicStartUp() throws IOException { 084 RSGroupInfo defaultInfo = ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP); 085 assertEquals(NUM_SLAVES_BASE, defaultInfo.getServers().size()); 086 // Assignment of meta and rsgroup regions. 087 int count = MASTER.getAssignmentManager().getRegionStates().getRegionAssignments().size(); 088 LOG.info("regions assignments are" 089 + MASTER.getAssignmentManager().getRegionStates().getRegionAssignments().toString()); 090 // 2 (meta and rsgroup) 091 assertEquals(2, count); 092 } 093 094 @Test 095 public void testCreateAndDrop() throws Exception { 096 TEST_UTIL.createTable(tableName, Bytes.toBytes("cf")); 097 // wait for created table to be assigned 098 TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() { 099 @Override 100 public boolean evaluate() throws Exception { 101 return getTableRegionMap().get(tableName) != null; 102 } 103 }); 104 TEST_UTIL.deleteTable(tableName); 105 } 106 107 @Test 108 public void testCreateMultiRegion() throws IOException { 109 byte[] end = { 1, 3, 5, 7, 9 }; 110 byte[] start = { 0, 2, 4, 6, 8 }; 111 byte[][] f = { Bytes.toBytes("f") }; 112 TEST_UTIL.createTable(tableName, f, 1, start, end, 10); 113 } 114 115 @Test 116 public void testNamespaceCreateAndAssign() throws Exception { 117 LOG.info("testNamespaceCreateAndAssign"); 118 String nsName = TABLE_PREFIX + "_foo"; 119 final TableName tableName = TableName.valueOf(nsName, TABLE_PREFIX + "_testCreateAndAssign"); 120 RSGroupInfo appInfo = addGroup("appInfo", 1); 121 ADMIN.createNamespace(NamespaceDescriptor.create(nsName) 122 .addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, "appInfo").build()); 123 final TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName) 124 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("f")).build(); 125 ADMIN.createTable(desc); 126 // wait for created table to be assigned 127 TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() { 128 @Override 129 public boolean evaluate() throws Exception { 130 return getTableRegionMap().get(desc.getTableName()) != null; 131 } 132 }); 133 ServerName targetServer = getServerName(appInfo.getServers().iterator().next()); 134 // verify it was assigned to the right group 135 Assert.assertEquals(1, ADMIN.getRegions(targetServer).size()); 136 } 137 138 @Test 139 public void testDefaultNamespaceCreateAndAssign() throws Exception { 140 LOG.info("testDefaultNamespaceCreateAndAssign"); 141 String tableName = TABLE_PREFIX + "_testCreateAndAssign"; 142 ADMIN.modifyNamespace(NamespaceDescriptor.create("default") 143 .addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, "default").build()); 144 final TableDescriptor desc = TableDescriptorBuilder.newBuilder(TableName.valueOf(tableName)) 145 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("f")).build(); 146 ADMIN.createTable(desc); 147 // wait for created table to be assigned 148 TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() { 149 @Override 150 public boolean evaluate() throws Exception { 151 return getTableRegionMap().get(desc.getTableName()) != null; 152 } 153 }); 154 } 155 156 @Test 157 public void testCloneSnapshot() throws Exception { 158 byte[] FAMILY = Bytes.toBytes("test"); 159 String snapshotName = tableName.getNameAsString() + "_snap"; 160 TableName clonedTableName = TableName.valueOf(tableName.getNameAsString() + "_clone"); 161 162 // create base table 163 TEST_UTIL.createTable(tableName, FAMILY); 164 165 // create snapshot 166 ADMIN.snapshot(snapshotName, tableName); 167 168 // clone 169 ADMIN.cloneSnapshot(snapshotName, clonedTableName); 170 ADMIN.deleteSnapshot(snapshotName); 171 } 172 173 @Test 174 public void testClearDeadServers() throws Exception { 175 LOG.info("testClearDeadServers"); 176 177 // move region servers from default group to new group 178 final int serverCountToMoveToNewGroup = 3; 179 final RSGroupInfo newGroup = 180 addGroup(getGroupName(name.getMethodName()), serverCountToMoveToNewGroup); 181 182 // get the existing dead servers 183 NUM_DEAD_SERVERS = CLUSTER.getClusterMetrics().getDeadServerNames().size(); 184 185 // stop 1 region server in new group 186 ServerName serverToStop = getServerName(newGroup.getServers().iterator().next()); 187 try { 188 // stopping may cause an exception 189 // due to the connection loss 190 ADMIN.stopRegionServer(serverToStop.getAddress().toString()); 191 NUM_DEAD_SERVERS++; 192 } catch (Exception e) { 193 } 194 195 // wait for stopped regionserver to dead server list 196 TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() { 197 @Override 198 public boolean evaluate() throws Exception { 199 return CLUSTER.getClusterMetrics().getDeadServerNames().size() == NUM_DEAD_SERVERS 200 && !MASTER.getServerManager().areDeadServersInProgress(); 201 } 202 }); 203 assertFalse(CLUSTER.getClusterMetrics().getLiveServerMetrics().containsKey(serverToStop)); 204 assertTrue(CLUSTER.getClusterMetrics().getDeadServerNames().contains(serverToStop)); 205 assertTrue(newGroup.getServers().contains(serverToStop.getAddress())); 206 207 // clear dead servers list 208 List<ServerName> notClearedServers = ADMIN.clearDeadServers(Lists.newArrayList(serverToStop)); 209 assertEquals(0, notClearedServers.size()); 210 211 // the stopped region server gets cleared and removed from the group 212 Set<Address> newGroupServers = ADMIN.getRSGroup(newGroup.getName()).getServers(); 213 assertFalse(newGroupServers.contains(serverToStop.getAddress())); 214 assertEquals(serverCountToMoveToNewGroup - 1 /* 1 stopped */, newGroupServers.size()); 215 } 216 217 @Test 218 public void testClearNotProcessedDeadServer() throws Exception { 219 LOG.info("testClearNotProcessedDeadServer"); 220 221 // get the existing dead servers 222 NUM_DEAD_SERVERS = CLUSTER.getClusterMetrics().getDeadServerNames().size(); 223 224 // move region servers from default group to "dead server" group 225 final int serverCountToMoveToDeadServerGroup = 1; 226 RSGroupInfo deadServerGroup = addGroup("deadServerGroup", serverCountToMoveToDeadServerGroup); 227 228 // stop 1 region servers in "dead server" group 229 ServerName serverToStop = getServerName(deadServerGroup.getServers().iterator().next()); 230 try { 231 // stopping may cause an exception 232 // due to the connection loss 233 ADMIN.stopRegionServer(serverToStop.getAddress().toString()); 234 NUM_DEAD_SERVERS++; 235 } catch (Exception e) { 236 } 237 TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() { 238 @Override 239 public boolean evaluate() throws Exception { 240 return CLUSTER.getClusterMetrics().getDeadServerNames().size() == NUM_DEAD_SERVERS; 241 } 242 }); 243 244 Set<Address> ServersInDeadServerGroup = 245 ADMIN.getRSGroup(deadServerGroup.getName()).getServers(); 246 assertEquals(serverCountToMoveToDeadServerGroup, ServersInDeadServerGroup.size()); 247 assertTrue(ServersInDeadServerGroup.contains(serverToStop.getAddress())); 248 } 249 250 @Test 251 public void testRSGroupsWithHBaseQuota() throws Exception { 252 toggleQuotaCheckAndRestartMiniCluster(true); 253 TEST_UTIL.waitFor(90000, new Waiter.Predicate<Exception>() { 254 @Override 255 public boolean evaluate() throws Exception { 256 return ADMIN.isTableAvailable(QuotaTableUtil.QUOTA_TABLE_NAME); 257 } 258 }); 259 toggleQuotaCheckAndRestartMiniCluster(false); 260 } 261}