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.assertTrue; 022 023import java.util.List; 024import java.util.NavigableSet; 025import org.apache.hadoop.conf.Configuration; 026import org.apache.hadoop.hbase.HBaseClassTestRule; 027import org.apache.hadoop.hbase.HBaseConfiguration; 028import org.apache.hadoop.hbase.HBaseTestingUtility; 029import org.apache.hadoop.hbase.MiniHBaseCluster; 030import org.apache.hadoop.hbase.StartMiniClusterOption; 031import org.apache.hadoop.hbase.TableName; 032import org.apache.hadoop.hbase.client.Admin; 033import org.apache.hadoop.hbase.client.RegionLocator; 034import org.apache.hadoop.hbase.client.Table; 035import org.apache.hadoop.hbase.client.TableState; 036import org.apache.hadoop.hbase.testclassification.LargeTests; 037import org.apache.hadoop.hbase.testclassification.MasterTests; 038import org.apache.hadoop.hbase.util.Bytes; 039import org.apache.hadoop.hbase.util.JVMClusterUtil.MasterThread; 040import org.junit.ClassRule; 041import org.junit.Rule; 042import org.junit.Test; 043import org.junit.experimental.categories.Category; 044import org.junit.rules.TestName; 045import org.slf4j.Logger; 046import org.slf4j.LoggerFactory; 047 048@Category({MasterTests.class, LargeTests.class}) 049public class TestMasterRestartAfterDisablingTable { 050 051 @ClassRule 052 public static final HBaseClassTestRule CLASS_RULE = 053 HBaseClassTestRule.forClass(TestMasterRestartAfterDisablingTable.class); 054 055 private static final Logger LOG = 056 LoggerFactory.getLogger(TestMasterRestartAfterDisablingTable.class); 057 058 @Rule 059 public TestName name = new TestName(); 060 061 @Test 062 public void testForCheckingIfEnableAndDisableWorksFineAfterSwitch() 063 throws Exception { 064 final int NUM_MASTERS = 2; 065 final int NUM_REGIONS_TO_CREATE = 4; 066 067 // Start the cluster 068 log("Starting cluster"); 069 Configuration conf = HBaseConfiguration.create(); 070 HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(conf); 071 StartMiniClusterOption option = StartMiniClusterOption.builder() 072 .numMasters(NUM_MASTERS).build(); 073 TEST_UTIL.startMiniCluster(option); 074 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); 075 log("Waiting for active/ready master"); 076 cluster.waitForActiveAndReadyMaster(); 077 078 // Create a table with regions 079 final TableName tableName = TableName.valueOf(name.getMethodName()); 080 byte[] family = Bytes.toBytes("family"); 081 log("Creating table with " + NUM_REGIONS_TO_CREATE + " regions"); 082 Table ht = TEST_UTIL.createMultiRegionTable(tableName, family, NUM_REGIONS_TO_CREATE); 083 int numRegions = -1; 084 try (RegionLocator r = TEST_UTIL.getConnection().getRegionLocator(tableName)) { 085 numRegions = r.getStartKeys().length; 086 } 087 numRegions += 1; // catalogs 088 log("Waiting for no more RIT\n"); 089 TEST_UTIL.waitUntilNoRegionsInTransition(60000); 090 log("Disabling table\n"); 091 TEST_UTIL.getAdmin().disableTable(tableName); 092 093 NavigableSet<String> regions = HBaseTestingUtility.getAllOnlineRegions(cluster); 094 assertEquals( 095 "The number of regions for the table tableRestart should be 0 and only" 096 + "the catalog and namespace tables should be present.", 2, regions.size()); 097 098 List<MasterThread> masterThreads = cluster.getMasterThreads(); 099 MasterThread activeMaster = null; 100 if (masterThreads.get(0).getMaster().isActiveMaster()) { 101 activeMaster = masterThreads.get(0); 102 } else { 103 activeMaster = masterThreads.get(1); 104 } 105 activeMaster.getMaster().stop( 106 "stopping the active master so that the backup can become active"); 107 cluster.hbaseCluster.waitOnMaster(activeMaster); 108 cluster.waitForActiveAndReadyMaster(); 109 110 assertTrue("The table should not be in enabled state", 111 cluster.getMaster().getTableStateManager().isTableState( 112 TableName.valueOf(name.getMethodName()), TableState.State.DISABLED, 113 TableState.State.DISABLING)); 114 log("Enabling table\n"); 115 // Need a new Admin, the previous one is on the old master 116 Admin admin = TEST_UTIL.getAdmin(); 117 admin.enableTable(tableName); 118 admin.close(); 119 log("Waiting for no more RIT\n"); 120 TEST_UTIL.waitUntilNoRegionsInTransition(60000); 121 log("Verifying there are " + numRegions + " assigned on cluster\n"); 122 regions = HBaseTestingUtility.getAllOnlineRegions(cluster); 123 assertEquals("The assigned regions were not onlined after master" 124 + " switch except for the catalog and namespace tables.", 125 6, regions.size()); 126 assertTrue("The table should be in enabled state", 127 cluster.getMaster().getTableStateManager() 128 .isTableState(TableName.valueOf(name.getMethodName()), TableState.State.ENABLED)); 129 ht.close(); 130 TEST_UTIL.shutdownMiniCluster(); 131 } 132 133 private void log(String msg) { 134 LOG.debug("\n\nTRR: " + msg + "\n"); 135 } 136} 137