diff --git a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java index c3f7eef..d5f26c3 100644 --- a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java +++ b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java @@ -246,6 +246,9 @@ public abstract class TestRSGroupsBase { TEST_UTIL.deleteTable(tableName); } + protected String getGroupName(String baseName) { + return groupPrefix+"_"+baseName+"_"+rand.nextInt(Integer.MAX_VALUE); + } @Test public void testSimpleRegionServerMove() throws IOException, @@ -577,154 +580,6 @@ public abstract class TestRSGroupsBase { } @Test - public void testKillRS() throws Exception { - RSGroupInfo appInfo = addGroup("appInfo", 1); - - final TableName tableName = TableName.valueOf(tablePrefix+"_ns", name.getMethodName()); - admin.createNamespace( - NamespaceDescriptor.create(tableName.getNamespaceAsString()) - .addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, appInfo.getName()).build()); - final HTableDescriptor desc = new HTableDescriptor(tableName); - desc.addFamily(new HColumnDescriptor("f")); - admin.createTable(desc); - //wait for created table to be assigned - TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { - @Override - public boolean evaluate() throws Exception { - return getTableRegionMap().get(desc.getTableName()) != null; - } - }); - - ServerName targetServer = ServerName.parseServerName( - appInfo.getServers().iterator().next().toString()); - AdminProtos.AdminService.BlockingInterface targetRS = - ((ClusterConnection) admin.getConnection()).getAdmin(targetServer); - RegionInfo targetRegion = ProtobufUtil.getOnlineRegions(targetRS).get(0); - Assert.assertEquals(1, ProtobufUtil.getOnlineRegions(targetRS).size()); - - try { - //stopping may cause an exception - //due to the connection loss - targetRS.stopServer(null, - AdminProtos.StopServerRequest.newBuilder().setReason("Die").build()); - } catch(Exception e) { - } - assertFalse(cluster.getClusterMetrics().getLiveServerMetrics().containsKey(targetServer)); - - //wait for created table to be assigned - TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { - @Override - public boolean evaluate() throws Exception { - return cluster.getClusterMetrics().getRegionStatesInTransition().isEmpty(); - } - }); - Set
newServers = Sets.newHashSet(); - newServers.add( - rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getServers().iterator().next()); - rsGroupAdmin.moveServers(newServers, appInfo.getName()); - - //Make sure all the table's regions get reassigned - //disabling the table guarantees no conflicting assign/unassign (ie SSH) happens - admin.disableTable(tableName); - admin.enableTable(tableName); - - //wait for region to be assigned - TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { - @Override - public boolean evaluate() throws Exception { - return cluster.getClusterMetrics().getRegionStatesInTransition().isEmpty(); - } - }); - - targetServer = ServerName.parseServerName( - newServers.iterator().next().toString()); - targetRS = - ((ClusterConnection) admin.getConnection()).getAdmin(targetServer); - Assert.assertEquals(1, ProtobufUtil.getOnlineRegions(targetRS).size()); - Assert.assertEquals(tableName, - ProtobufUtil.getOnlineRegions(targetRS).get(0).getTable()); - } - - @Test - public void testValidGroupNames() throws IOException { - String[] badNames = {"foo*","foo@","-"}; - String[] goodNames = {"foo_123"}; - - for(String entry: badNames) { - try { - rsGroupAdmin.addRSGroup(entry); - fail("Expected a constraint exception for: "+entry); - } catch(ConstraintException ex) { - //expected - } - } - - for(String entry: goodNames) { - rsGroupAdmin.addRSGroup(entry); - } - } - - private String getGroupName(String baseName) { - return groupPrefix+"_"+baseName+"_"+rand.nextInt(Integer.MAX_VALUE); - } - - @Test - public void testMultiTableMove() throws Exception { - final TableName tableNameA = TableName.valueOf(tablePrefix + name.getMethodName() + "A"); - final TableName tableNameB = TableName.valueOf(tablePrefix + name.getMethodName() + "B"); - final byte[] familyNameBytes = Bytes.toBytes("f"); - String newGroupName = getGroupName(name.getMethodName()); - final RSGroupInfo newGroup = addGroup(newGroupName, 1); - - TEST_UTIL.createTable(tableNameA, familyNameBytes); - TEST_UTIL.createTable(tableNameB, familyNameBytes); - TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { - @Override - public boolean evaluate() throws Exception { - List regionsA = getTableRegionMap().get(tableNameA); - if (regionsA == null) { - return false; - } - - List regionsB = getTableRegionMap().get(tableNameB); - if (regionsB == null) { - return false; - } - - return getTableRegionMap().get(tableNameA).size() >= 1 - && getTableRegionMap().get(tableNameB).size() >= 1; - } - }); - - RSGroupInfo tableGrpA = rsGroupAdmin.getRSGroupInfoOfTable(tableNameA); - assertTrue(tableGrpA.getName().equals(RSGroupInfo.DEFAULT_GROUP)); - - RSGroupInfo tableGrpB = rsGroupAdmin.getRSGroupInfoOfTable(tableNameB); - assertTrue(tableGrpB.getName().equals(RSGroupInfo.DEFAULT_GROUP)); - //change table's group - LOG.info("Moving table [" + tableNameA + "," + tableNameB + "] to " + newGroup.getName()); - rsGroupAdmin.moveTables(Sets.newHashSet(tableNameA, tableNameB), newGroup.getName()); - - //verify group change - Assert.assertEquals(newGroup.getName(), - rsGroupAdmin.getRSGroupInfoOfTable(tableNameA).getName()); - - Assert.assertEquals(newGroup.getName(), - rsGroupAdmin.getRSGroupInfoOfTable(tableNameB).getName()); - - //verify tables' not exist in old group - Set DefaultTables = rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP) - .getTables(); - assertFalse(DefaultTables.contains(tableNameA)); - assertFalse(DefaultTables.contains(tableNameB)); - - //verify tables' exist in new group - Set newGroupTables = rsGroupAdmin.getRSGroupInfo(newGroupName).getTables(); - assertTrue(newGroupTables.contains(tableNameA)); - assertTrue(newGroupTables.contains(tableNameB)); - } - - @Test public void testDisabledTableMove() throws Exception { final byte[] familyNameBytes = Bytes.toBytes("f"); String newGroupName = getGroupName(name.getMethodName()); @@ -881,110 +736,4 @@ public abstract class TestRSGroupsBase { Assert.assertEquals(5, getTableServerRegionMap().get(tableName).get(targetServer).size()); } - @Test - public void testClearDeadServers() throws Exception { - LOG.info("testClearDeadServers"); - final RSGroupInfo newGroup = addGroup(getGroupName(name.getMethodName()), 3); - - ServerName targetServer = ServerName.parseServerName( - newGroup.getServers().iterator().next().toString()); - AdminProtos.AdminService.BlockingInterface targetRS = - ((ClusterConnection) admin.getConnection()).getAdmin(targetServer); - try { - targetServer = ProtobufUtil.toServerName(targetRS.getServerInfo(null, - GetServerInfoRequest.newBuilder().build()).getServerInfo().getServerName()); - //stopping may cause an exception - //due to the connection loss - targetRS.stopServer(null, - AdminProtos.StopServerRequest.newBuilder().setReason("Die").build()); - } catch(Exception e) { - } - HMaster master = TEST_UTIL.getHBaseCluster().getMaster(); - //wait for stopped regionserver to dead server list - TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { - @Override - public boolean evaluate() throws Exception { - return !master.getServerManager().areDeadServersInProgress() - && cluster.getClusterMetrics().getDeadServerNames().size() > 0; - } - }); - assertFalse(cluster.getClusterMetrics().getLiveServerMetrics().containsKey(targetServer)); - assertTrue(cluster.getClusterMetrics().getDeadServerNames().contains(targetServer)); - assertTrue(newGroup.getServers().contains(targetServer.getAddress())); - - //clear dead servers list - List notClearedServers = admin.clearDeadServers(Lists.newArrayList(targetServer)); - assertEquals(0, notClearedServers.size()); - - Set
newGroupServers = rsGroupAdmin.getRSGroupInfo(newGroup.getName()).getServers(); - assertFalse(newGroupServers.contains(targetServer.getAddress())); - assertEquals(2, newGroupServers.size()); - } - - @Test - public void testRemoveServers() throws Exception { - LOG.info("testRemoveServers"); - final RSGroupInfo newGroup = addGroup(getGroupName(name.getMethodName()), 3); - ServerName targetServer = ServerName.parseServerName( - newGroup.getServers().iterator().next().toString()); - try { - rsGroupAdmin.removeServers(Sets.newHashSet(targetServer.getAddress())); - fail("Online servers shouldn't have been successfully removed."); - } catch(IOException ex) { - String exp = "Server " + targetServer.getAddress() - + " is an online server, not allowed to remove."; - String msg = "Expected '" + exp + "' in exception message: "; - assertTrue(msg + " " + ex.getMessage(), ex.getMessage().contains(exp)); - } - assertTrue(newGroup.getServers().contains(targetServer.getAddress())); - - AdminProtos.AdminService.BlockingInterface targetRS = - ((ClusterConnection) admin.getConnection()).getAdmin(targetServer); - try { - targetServer = ProtobufUtil.toServerName(targetRS.getServerInfo(null, - GetServerInfoRequest.newBuilder().build()).getServerInfo().getServerName()); - //stopping may cause an exception - //due to the connection loss - targetRS.stopServer(null, - AdminProtos.StopServerRequest.newBuilder().setReason("Die").build()); - } catch(Exception e) { - } - - HMaster master = TEST_UTIL.getHBaseCluster().getMaster(); - //wait for stopped regionserver to dead server list - TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { - @Override - public boolean evaluate() throws Exception { - return !master.getServerManager().areDeadServersInProgress() - && cluster.getClusterMetrics().getDeadServerNames().size() > 0; - } - }); - - try { - rsGroupAdmin.removeServers(Sets.newHashSet(targetServer.getAddress())); - fail("Dead servers shouldn't have been successfully removed."); - } catch(IOException ex) { - String exp = "Server " + targetServer.getAddress() + " is on the dead servers list," - + " Maybe it will come back again, not allowed to remove."; - String msg = "Expected '" + exp + "' in exception message: "; - assertTrue(msg + " " + ex.getMessage(), ex.getMessage().contains(exp)); - } - assertTrue(newGroup.getServers().contains(targetServer.getAddress())); - - ServerName sn = TEST_UTIL.getHBaseClusterInterface().getClusterMetrics().getMasterName(); - TEST_UTIL.getHBaseClusterInterface().stopMaster(sn); - TEST_UTIL.getHBaseClusterInterface().waitForMasterToStop(sn, 60000); - TEST_UTIL.getHBaseClusterInterface().startMaster(sn.getHostname(), 0); - TEST_UTIL.getHBaseClusterInterface().waitForActiveAndReadyMaster(60000); - - assertEquals(3, cluster.getClusterMetrics().getLiveServerMetrics().size()); - assertFalse(cluster.getClusterMetrics().getLiveServerMetrics().containsKey(targetServer)); - assertFalse(cluster.getClusterMetrics().getDeadServerNames().contains(targetServer)); - assertTrue(newGroup.getServers().contains(targetServer.getAddress())); - - rsGroupAdmin.removeServers(Sets.newHashSet(targetServer.getAddress())); - Set
newGroupServers = rsGroupAdmin.getRSGroupInfo(newGroup.getName()).getServers(); - assertFalse(newGroupServers.contains(targetServer.getAddress())); - assertEquals(2, newGroupServers.size()); - } } diff --git a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroups2.java b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroups2.java new file mode 100644 index 0000000..c8b7696 --- /dev/null +++ b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroups2.java @@ -0,0 +1,415 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.rsgroup; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.hadoop.hbase.HBaseClassTestRule; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.MiniHBaseCluster; +import org.apache.hadoop.hbase.NamespaceDescriptor; +import org.apache.hadoop.hbase.ServerName; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.Waiter; +import org.apache.hadoop.hbase.Waiter.Predicate; +import org.apache.hadoop.hbase.client.ClusterConnection; +import org.apache.hadoop.hbase.client.RegionInfo; +import org.apache.hadoop.hbase.constraint.ConstraintException; +import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; +import org.apache.hadoop.hbase.master.HMaster; +import org.apache.hadoop.hbase.master.ServerManager; +import org.apache.hadoop.hbase.master.snapshot.SnapshotManager; +import org.apache.hadoop.hbase.net.Address; +import org.apache.hadoop.hbase.testclassification.LargeTests; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.hbase.thirdparty.com.google.common.collect.Lists; +import org.apache.hbase.thirdparty.com.google.common.collect.Sets; + +import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; +import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos; +import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetServerInfoRequest; + +@Category({LargeTests.class}) +public class TestRSGroups2 extends TestRSGroupsBase { + + @ClassRule + public static final HBaseClassTestRule CLASS_RULE = + HBaseClassTestRule.forClass(TestRSGroups2.class); + + protected static final Logger LOG = LoggerFactory.getLogger(TestRSGroups2.class); + private static HMaster master; + private static boolean INIT = false; + private static RSGroupAdminEndpoint rsGroupAdminEndpoint; + + + @BeforeClass + public static void setUp() throws Exception { + TEST_UTIL = new HBaseTestingUtility(); + TEST_UTIL.getConfiguration().setFloat( + "hbase.master.balancer.stochastic.tableSkewCost", 6000); + TEST_UTIL.getConfiguration().set( + HConstants.HBASE_MASTER_LOADBALANCER_CLASS, + RSGroupBasedLoadBalancer.class.getName()); + TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, + RSGroupAdminEndpoint.class.getName()); + TEST_UTIL.startMiniCluster(NUM_SLAVES_BASE - 1); + TEST_UTIL.getConfiguration().setInt( + ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, + NUM_SLAVES_BASE - 1); + TEST_UTIL.getConfiguration().setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true); + + admin = TEST_UTIL.getAdmin(); + cluster = TEST_UTIL.getHBaseCluster(); + master = ((MiniHBaseCluster)cluster).getMaster(); + + //wait for balancer to come online + TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { + @Override + public boolean evaluate() throws Exception { + return master.isInitialized() && + ((RSGroupBasedLoadBalancer) master.getLoadBalancer()).isOnline(); + } + }); + admin.setBalancerRunning(false,true); + rsGroupAdmin = new VerifyingRSGroupAdminClient( + new RSGroupAdminClient(TEST_UTIL.getConnection()), TEST_UTIL.getConfiguration()); + rsGroupAdminEndpoint = (RSGroupAdminEndpoint) + master.getMasterCoprocessorHost().findCoprocessor(RSGroupAdminEndpoint.class.getName()); + } + + @AfterClass + public static void tearDown() throws Exception { + TEST_UTIL.shutdownMiniCluster(); + } + + @Before + public void beforeMethod() throws Exception { + if (!INIT) { + INIT = true; + afterMethod(); + } + + } + + @After + public void afterMethod() throws Exception { + deleteTableIfNecessary(); + deleteNamespaceIfNecessary(); + deleteGroups(); + + int missing = NUM_SLAVES_BASE - getNumServers(); + LOG.info("Restoring servers: "+missing); + for(int i=0; i() { + @Override + public boolean evaluate() throws Exception { + LOG.info("Waiting for cleanup to finish " + rsGroupAdmin.listRSGroups()); + //Might be greater since moving servers back to default + //is after starting a server + + return rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getServers().size() + == NUM_SLAVES_BASE; + } + }); + } + + @Test + public void testKillRS() throws Exception { + RSGroupInfo appInfo = addGroup("appInfo", 1); + + final TableName tableName = TableName.valueOf(tablePrefix+"_ns", name.getMethodName()); + admin.createNamespace( + NamespaceDescriptor.create(tableName.getNamespaceAsString()) + .addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, appInfo.getName()).build()); + final HTableDescriptor desc = new HTableDescriptor(tableName); + desc.addFamily(new HColumnDescriptor("f")); + admin.createTable(desc); + //wait for created table to be assigned + TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { + @Override + public boolean evaluate() throws Exception { + return getTableRegionMap().get(desc.getTableName()) != null; + } + }); + + ServerName targetServer = ServerName.parseServerName( + appInfo.getServers().iterator().next().toString()); + AdminProtos.AdminService.BlockingInterface targetRS = + ((ClusterConnection) admin.getConnection()).getAdmin(targetServer); + RegionInfo targetRegion = ProtobufUtil.getOnlineRegions(targetRS).get(0); + Assert.assertEquals(1, ProtobufUtil.getOnlineRegions(targetRS).size()); + + try { + //stopping may cause an exception + //due to the connection loss + targetRS.stopServer(null, + AdminProtos.StopServerRequest.newBuilder().setReason("Die").build()); + } catch(Exception e) { + } + assertFalse(cluster.getClusterMetrics().getLiveServerMetrics().containsKey(targetServer)); + + //wait for created table to be assigned + TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { + @Override + public boolean evaluate() throws Exception { + return cluster.getClusterMetrics().getRegionStatesInTransition().isEmpty(); + } + }); + Set
newServers = Sets.newHashSet(); + newServers.add( + rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getServers().iterator().next()); + rsGroupAdmin.moveServers(newServers, appInfo.getName()); + + //Make sure all the table's regions get reassigned + //disabling the table guarantees no conflicting assign/unassign (ie SSH) happens + admin.disableTable(tableName); + admin.enableTable(tableName); + + //wait for region to be assigned + TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { + @Override + public boolean evaluate() throws Exception { + return cluster.getClusterMetrics().getRegionStatesInTransition().isEmpty(); + } + }); + + targetServer = ServerName.parseServerName( + newServers.iterator().next().toString()); + targetRS = + ((ClusterConnection) admin.getConnection()).getAdmin(targetServer); + Assert.assertEquals(1, ProtobufUtil.getOnlineRegions(targetRS).size()); + Assert.assertEquals(tableName, + ProtobufUtil.getOnlineRegions(targetRS).get(0).getTable()); + } + + @Test + public void testValidGroupNames() throws IOException { + String[] badNames = {"foo*","foo@","-"}; + String[] goodNames = {"foo_123"}; + + for(String entry: badNames) { + try { + rsGroupAdmin.addRSGroup(entry); + fail("Expected a constraint exception for: "+entry); + } catch(ConstraintException ex) { + //expected + } + } + + for(String entry: goodNames) { + rsGroupAdmin.addRSGroup(entry); + } + } + + @Test + public void testMultiTableMove() throws Exception { + final TableName tableNameA = TableName.valueOf(tablePrefix + name.getMethodName() + "A"); + final TableName tableNameB = TableName.valueOf(tablePrefix + name.getMethodName() + "B"); + final byte[] familyNameBytes = Bytes.toBytes("f"); + String newGroupName = getGroupName(name.getMethodName()); + final RSGroupInfo newGroup = addGroup(newGroupName, 1); + + TEST_UTIL.createTable(tableNameA, familyNameBytes); + TEST_UTIL.createTable(tableNameB, familyNameBytes); + TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { + @Override + public boolean evaluate() throws Exception { + List regionsA = getTableRegionMap().get(tableNameA); + if (regionsA == null) { + return false; + } + + List regionsB = getTableRegionMap().get(tableNameB); + if (regionsB == null) { + return false; + } + + return getTableRegionMap().get(tableNameA).size() >= 1 + && getTableRegionMap().get(tableNameB).size() >= 1; + } + }); + + RSGroupInfo tableGrpA = rsGroupAdmin.getRSGroupInfoOfTable(tableNameA); + assertTrue(tableGrpA.getName().equals(RSGroupInfo.DEFAULT_GROUP)); + + RSGroupInfo tableGrpB = rsGroupAdmin.getRSGroupInfoOfTable(tableNameB); + assertTrue(tableGrpB.getName().equals(RSGroupInfo.DEFAULT_GROUP)); + //change table's group + LOG.info("Moving table [" + tableNameA + "," + tableNameB + "] to " + newGroup.getName()); + rsGroupAdmin.moveTables(Sets.newHashSet(tableNameA, tableNameB), newGroup.getName()); + + //verify group change + Assert.assertEquals(newGroup.getName(), + rsGroupAdmin.getRSGroupInfoOfTable(tableNameA).getName()); + + Assert.assertEquals(newGroup.getName(), + rsGroupAdmin.getRSGroupInfoOfTable(tableNameB).getName()); + + //verify tables' not exist in old group + Set DefaultTables = rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP) + .getTables(); + assertFalse(DefaultTables.contains(tableNameA)); + assertFalse(DefaultTables.contains(tableNameB)); + + //verify tables' exist in new group + Set newGroupTables = rsGroupAdmin.getRSGroupInfo(newGroupName).getTables(); + assertTrue(newGroupTables.contains(tableNameA)); + assertTrue(newGroupTables.contains(tableNameB)); + } + + @Test + public void testRemoveServers() throws Exception { + LOG.info("testRemoveServers"); + final RSGroupInfo newGroup = addGroup(getGroupName(name.getMethodName()), 3); + ServerName targetServer = ServerName.parseServerName( + newGroup.getServers().iterator().next().toString()); + try { + rsGroupAdmin.removeServers(Sets.newHashSet(targetServer.getAddress())); + fail("Online servers shouldn't have been successfully removed."); + } catch(IOException ex) { + String exp = "Server " + targetServer.getAddress() + + " is an online server, not allowed to remove."; + String msg = "Expected '" + exp + "' in exception message: "; + assertTrue(msg + " " + ex.getMessage(), ex.getMessage().contains(exp)); + } + assertTrue(newGroup.getServers().contains(targetServer.getAddress())); + + AdminProtos.AdminService.BlockingInterface targetRS = + ((ClusterConnection) admin.getConnection()).getAdmin(targetServer); + try { + targetServer = ProtobufUtil.toServerName(targetRS.getServerInfo(null, + GetServerInfoRequest.newBuilder().build()).getServerInfo().getServerName()); + //stopping may cause an exception + //due to the connection loss + targetRS.stopServer(null, + AdminProtos.StopServerRequest.newBuilder().setReason("Die").build()); + } catch(Exception e) { + } + + HMaster master = TEST_UTIL.getHBaseCluster().getMaster(); + //wait for stopped regionserver to dead server list + TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { + @Override + public boolean evaluate() throws Exception { + return !master.getServerManager().areDeadServersInProgress() + && cluster.getClusterMetrics().getDeadServerNames().size() > 0; + } + }); + + try { + rsGroupAdmin.removeServers(Sets.newHashSet(targetServer.getAddress())); + fail("Dead servers shouldn't have been successfully removed."); + } catch(IOException ex) { + String exp = "Server " + targetServer.getAddress() + " is on the dead servers list," + + " Maybe it will come back again, not allowed to remove."; + String msg = "Expected '" + exp + "' in exception message: "; + assertTrue(msg + " " + ex.getMessage(), ex.getMessage().contains(exp)); + } + assertTrue(newGroup.getServers().contains(targetServer.getAddress())); + + ServerName sn = TEST_UTIL.getHBaseClusterInterface().getClusterMetrics().getMasterName(); + TEST_UTIL.getHBaseClusterInterface().stopMaster(sn); + TEST_UTIL.getHBaseClusterInterface().waitForMasterToStop(sn, 60000); + TEST_UTIL.getHBaseClusterInterface().startMaster(sn.getHostname(), 0); + TEST_UTIL.getHBaseClusterInterface().waitForActiveAndReadyMaster(60000); + + assertEquals(3, cluster.getClusterMetrics().getLiveServerMetrics().size()); + assertFalse(cluster.getClusterMetrics().getLiveServerMetrics().containsKey(targetServer)); + assertFalse(cluster.getClusterMetrics().getDeadServerNames().contains(targetServer)); + assertTrue(newGroup.getServers().contains(targetServer.getAddress())); + + rsGroupAdmin.removeServers(Sets.newHashSet(targetServer.getAddress())); + Set
newGroupServers = rsGroupAdmin.getRSGroupInfo(newGroup.getName()).getServers(); + assertFalse(newGroupServers.contains(targetServer.getAddress())); + assertEquals(2, newGroupServers.size()); + } + + @Test + public void testClearDeadServers() throws Exception { + LOG.info("testClearDeadServers"); + final RSGroupInfo newGroup = addGroup(getGroupName(name.getMethodName()), 3); + + ServerName targetServer = ServerName.parseServerName( + newGroup.getServers().iterator().next().toString()); + AdminProtos.AdminService.BlockingInterface targetRS = + ((ClusterConnection) admin.getConnection()).getAdmin(targetServer); + try { + targetServer = ProtobufUtil.toServerName(targetRS.getServerInfo(null, + GetServerInfoRequest.newBuilder().build()).getServerInfo().getServerName()); + //stopping may cause an exception + //due to the connection loss + targetRS.stopServer(null, + AdminProtos.StopServerRequest.newBuilder().setReason("Die").build()); + } catch(Exception e) { + } + HMaster master = TEST_UTIL.getHBaseCluster().getMaster(); + //wait for stopped regionserver to dead server list + TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate() { + @Override + public boolean evaluate() throws Exception { + return !master.getServerManager().areDeadServersInProgress() + && cluster.getClusterMetrics().getDeadServerNames().size() > 0; + } + }); + assertFalse(cluster.getClusterMetrics().getLiveServerMetrics().containsKey(targetServer)); + assertTrue(cluster.getClusterMetrics().getDeadServerNames().contains(targetServer)); + assertTrue(newGroup.getServers().contains(targetServer.getAddress())); + + //clear dead servers list + List notClearedServers = admin.clearDeadServers(Lists.newArrayList(targetServer)); + assertEquals(0, notClearedServers.size()); + + Set
newGroupServers = rsGroupAdmin.getRSGroupInfo(newGroup.getName()).getServers(); + assertFalse(newGroupServers.contains(targetServer.getAddress())); + assertEquals(2, newGroupServers.size()); + } +}