Author: tedyu
Date: Sat Jul 16 01:47:10 2011
New Revision: 1147354
URL: http://svn.apache.org/viewvc?rev=1147354&view=rev
Log:
HBASE-4052 Enabling a table after master switch does not allow table scan,
throwing NotServingRegionException. Add unit test
Added:
hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterRestartAfterDisablingTable.java
Added:
hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterRestartAfterDisablingTable.java
URL:
http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterRestartAfterDisablingTable.java?rev=1147354&view=auto
==============================================================================
---
hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterRestartAfterDisablingTable.java
(added)
+++
hbase/trunk/src/test/java/org/apache/hadoop/hbase/master/TestMasterRestartAfterDisablingTable.java
Sat Jul 16 01:47:10 2011
@@ -0,0 +1,185 @@
+/**
+ * Copyright 2011 The Apache Software Foundation
+ *
+ * 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.master;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.NavigableSet;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.MiniHBaseCluster;
+import org.apache.hadoop.hbase.NotServingRegionException;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.JVMClusterUtil.MasterThread;
+import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
+import org.apache.hadoop.hbase.zookeeper.ZKAssign;
+import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
+import org.apache.zookeeper.KeeperException;
+import org.junit.Test;
+
+public class TestMasterRestartAfterDisablingTable {
+
+ private static final Log LOG = LogFactory.getLog(TestRollingRestart.class);
+
+ @Test
+ public void testForCheckingIfEnableAndDisableWorksFineAfterSwitch()
+ throws Exception {
+ final int NUM_MASTERS = 2;
+ final int NUM_RS = 1;
+ final int NUM_REGIONS_TO_CREATE = 4;
+
+ int expectedNumRS = 1;
+
+ // Start the cluster
+ log("Starting cluster");
+ Configuration conf = HBaseConfiguration.create();
+ conf.setInt("hbase.master.assignment.timeoutmonitor.period", 2000);
+ conf.setInt("hbase.master.assignment.timeoutmonitor.timeout", 5000);
+ HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(conf);
+ TEST_UTIL.startMiniCluster(NUM_MASTERS, NUM_RS);
+ MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
+ log("Waiting for active/ready master");
+ cluster.waitForActiveAndReadyMaster();
+ ZooKeeperWatcher zkw = new ZooKeeperWatcher(conf, "testmasterRestart",
+ null);
+ HMaster master = cluster.getMaster();
+
+ // Create a table with regions
+ byte[] table = Bytes.toBytes("tableRestart");
+ byte[] family = Bytes.toBytes("family");
+ log("Creating table with " + NUM_REGIONS_TO_CREATE + " regions");
+ HTable ht = TEST_UTIL.createTable(table, family);
+ int numRegions = TEST_UTIL.createMultiRegions(conf, ht, family,
+ NUM_REGIONS_TO_CREATE);
+ numRegions += 2; // catalogs
+ log("Waiting for no more RIT\n");
+ blockUntilNoRIT(zkw, master);
+ log("Disabling table\n");
+ TEST_UTIL.getHBaseAdmin().disableTable(table);
+
+ NavigableSet<String> regions = getAllOnlineRegions(cluster);
+ assertEquals("The number of regions for the table tableRestart should be 0
and only" +
+ "the catalog tables should be present.", 2, regions.size());
+
+ List<MasterThread> masterThreads = cluster.getMasterThreads();
+ MasterThread activeMaster = null;
+ if (masterThreads.get(0).getMaster().isActiveMaster()) {
+ activeMaster = masterThreads.get(0);
+ } else {
+ activeMaster = masterThreads.get(1);
+ }
+ activeMaster.getMaster().stop(
+ "stopping the active master so that the backup can become active");
+ cluster.hbaseCluster.waitOnMaster(activeMaster);
+
+ log("Enabling table\n");
+ TEST_UTIL.getHBaseAdmin().enableTable(table);
+ log("Waiting for no more RIT\n");
+ blockUntilNoRIT(zkw, master);
+ log("Verifying there are " + numRegions + " assigned on cluster\n");
+ try {
+ Scan s = new Scan();
+ ht.getScanner(s);
+ } catch (NotServingRegionException e) {
+ fail("NotServingRegionException should not be thrown after enabling the
table. Hence failing"
+ + "the test case");
+ }
+ regions = getAllOnlineRegions(cluster);
+ assertRegionsAssigned(cluster, regions);
+ assertEquals("All the regions are not onlined.",expectedNumRS,
cluster.getRegionServerThreads().size());
+ }
+
+ private void log(String msg) {
+ LOG.debug("\n\nTRR: " + msg + "\n");
+ }
+
+ private void blockUntilNoRIT(ZooKeeperWatcher zkw, HMaster master)
+ throws KeeperException, InterruptedException {
+ ZKAssign.blockUntilNoRIT(zkw);
+ master.assignmentManager.waitUntilNoRegionsInTransition(60000);
+ }
+
+ private void assertRegionsAssigned(MiniHBaseCluster cluster,
+ Set<String> expectedRegions) throws IOException {
+ int numFound = 0;
+ for (RegionServerThread rst : cluster.getLiveRegionServerThreads()) {
+ numFound += rst.getRegionServer().getNumberOfOnlineRegions();
+ }
+ if (expectedRegions.size() > numFound) {
+ log("Expected to find " + expectedRegions.size() + " but only found"
+ + " " + numFound);
+ NavigableSet<String> foundRegions = getAllOnlineRegions(cluster);
+ for (String region : expectedRegions) {
+ if (!foundRegions.contains(region)) {
+ log("Missing region: " + region);
+ }
+ }
+ assertEquals(expectedRegions.size(), numFound);
+ } else if (expectedRegions.size() < numFound) {
+ int doubled = numFound - expectedRegions.size();
+ log("Expected to find " + expectedRegions.size() + " but found" + " "
+ + numFound + " (" + doubled + " double assignments?)");
+ NavigableSet<String> doubleRegions = getDoubleAssignedRegions(cluster);
+ for (String region : doubleRegions) {
+ log("Region is double assigned: " + region);
+ }
+ assertEquals(expectedRegions.size(), numFound);
+ } else {
+ log("Success! Found expected number of " + numFound + " regions");
+ }
+ }
+
+ private NavigableSet<String> getDoubleAssignedRegions(MiniHBaseCluster
cluster)
+ throws IOException {
+ NavigableSet<String> online = new TreeSet<String>();
+ NavigableSet<String> doubled = new TreeSet<String>();
+ for (RegionServerThread rst : cluster.getLiveRegionServerThreads()) {
+ for (HRegionInfo region : rst.getRegionServer().getOnlineRegions()) {
+ if (!online.add(region.getRegionNameAsString())) {
+ doubled.add(region.getRegionNameAsString());
+ }
+ }
+ }
+ return doubled;
+ }
+
+ private NavigableSet<String> getAllOnlineRegions(MiniHBaseCluster cluster)
+ throws IOException {
+ NavigableSet<String> online = new TreeSet<String>();
+ for (RegionServerThread rst : cluster.getLiveRegionServerThreads()) {
+ for (HRegionInfo region : rst.getRegionServer().getOnlineRegions()) {
+ online.add(region.getRegionNameAsString());
+ }
+ }
+ return online;
+ }
+}