diff --git src/test/java/org/apache/hadoop/hbase/master/Mocking.java src/test/java/org/apache/hadoop/hbase/master/Mocking.java
new file mode 100644
index 0000000..187e07d
--- /dev/null
+++ src/test/java/org/apache/hadoop/hbase/master/Mocking.java
@@ -0,0 +1,46 @@
+/**
+ * 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 org.apache.hadoop.hbase.master.AssignmentManager.RegionState;
+
+/**
+ * Package scoped mocking utility.
+ */
+public class Mocking {
+
+ static void waitForRegionPendingOpenInRIT(AssignmentManager am, String encodedName)
+ throws InterruptedException {
+ // We used to do a check like this:
+ //!Mocking.verifyRegionState(this.watcher, REGIONINFO, EventType.M_ZK_REGION_OFFLINE)) {
+ // There is a race condition with this: because we may do the transition to
+ // RS_ZK_REGION_OPENING before the RIT is internally updated. We need to wait for the
+ // RIT to be as we need it to be instead. This cannot happen in a real cluster as we
+ // update the RIT before sending the openRegion request.
+
+ boolean wait = true;
+ while (wait) {
+ RegionState state = am.getRegionsInTransition().get(encodedName);
+ if (state != null && state.isPendingOpen()){
+ wait = false;
+ } else {
+ Thread.sleep(1);
+ }
+ }
+ }
+}
diff --git src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java
index ba46069..19e7dfa 100644
--- src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java
+++ src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java
@@ -36,9 +36,9 @@ import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HServerLoad;
import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.MediumTests;
import org.apache.hadoop.hbase.Server;
import org.apache.hadoop.hbase.ServerName;
-import org.apache.hadoop.hbase.SmallTests;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.catalog.CatalogTracker;
import org.apache.hadoop.hbase.client.Get;
@@ -61,12 +61,12 @@ import org.apache.hadoop.hbase.util.Threads;
import org.apache.hadoop.hbase.util.Writables;
import org.apache.hadoop.hbase.zookeeper.RecoverableZooKeeper;
import org.apache.hadoop.hbase.zookeeper.ZKAssign;
+import org.apache.hadoop.hbase.zookeeper.ZKTable.TableState;
import org.apache.hadoop.hbase.zookeeper.ZKUtil;
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
-import org.apache.hadoop.hbase.zookeeper.ZKTable.TableState;
import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.KeeperException.NodeExistsException;
+import org.apache.zookeeper.Watcher;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@@ -82,7 +82,7 @@ import com.google.protobuf.ServiceException;
/**
* Test {@link AssignmentManager}
*/
-@Category(SmallTests.class)
+@Category(MediumTests.class)
public class TestAssignmentManager {
private static final HBaseTestingUtility HTU = new HBaseTestingUtility();
private static final ServerName SERVERNAME_A =
@@ -162,7 +162,7 @@ public class TestAssignmentManager {
/**
* Test a balance going on at same time as a master failover
- *
+ *
* @throws IOException
* @throws KeeperException
* @throws InterruptedException
@@ -313,10 +313,11 @@ public class TestAssignmentManager {
* from one server to another mocking regionserver responding over zk.
* @throws IOException
* @throws KeeperException
+ * @throws InterruptedException
*/
- @Test
+ @Test(timeout = 10000)
public void testBalance()
- throws IOException, KeeperException {
+ throws IOException, KeeperException, InterruptedException {
// Create and startup an executor. This is used by AssignmentManager
// handling zk callbacks.
ExecutorService executor = startupMasterExecutor("testBalanceExecutor");
@@ -350,11 +351,9 @@ public class TestAssignmentManager {
// AM is going to notice above CLOSED and queue up a new assign. The
// assign will go to open the region in the new location set by the
// balancer. The zk node will be OFFLINE waiting for regionserver to
- // transition it through OPENING, OPENED. Wait till we see the OFFLINE
- // zk node before we proceed.
- while (!ZKAssign.verifyRegionState(this.watcher, REGIONINFO, EventType.M_ZK_REGION_OFFLINE)) {
- Threads.sleep(1);
- }
+ // transition it through OPENING, OPENED. Wait till we see the RIT
+ // before we proceed.
+ Mocking.waitForRegionPendingOpenInRIT(am, REGIONINFO.getEncodedName());
// Get current versionid else will fail on transition from OFFLINE to OPENING below
versionid = ZKAssign.getVersion(this.watcher, REGIONINFO);
assertNotSame(-1, versionid);
@@ -407,7 +406,7 @@ public class TestAssignmentManager {
/**
* To test closed region handler to remove rit and delete corresponding znode if region in pending
- * close or closing while processing shutdown of a region server.(HBASE-5927).
+ * close or closing while processing shutdown of a region server.(HBASE-5927).
* @throws KeeperException
* @throws IOException
*/
@@ -417,7 +416,7 @@ public class TestAssignmentManager {
testCaseWithPartiallyDisabledState(TableState.DISABLING);
testCaseWithPartiallyDisabledState(TableState.DISABLED);
}
-
+
/**
* To test if the split region is removed from RIT if the region was in SPLITTING state
* but the RS has actually completed the splitting in META but went down. See HBASE-6070
@@ -451,7 +450,7 @@ public class TestAssignmentManager {
am.regionsInTransition.put(REGIONINFO.getEncodedName(), new RegionState(REGIONINFO,
State.SPLITTING, System.currentTimeMillis(), SERVERNAME_A));
am.getZKTable().setEnabledTable(REGIONINFO.getTableNameAsString());
-
+
RegionTransitionData data = new RegionTransitionData(EventType.RS_ZK_REGION_SPLITTING,
REGIONINFO.getRegionName(), SERVERNAME_A);
String node = ZKAssign.getNodeName(this.watcher, REGIONINFO.getEncodedName());
@@ -459,11 +458,11 @@ public class TestAssignmentManager {
ZKUtil.createAndWatch(this.watcher, node, data.getBytes());
try {
-
+
processServerShutdownHandler(ct, am, regionSplitDone);
// check znode deleted or not.
// In both cases the znode should be deleted.
-
+
if(regionSplitDone){
assertTrue("Region state of region in SPLITTING should be removed from rit.",
am.regionsInTransition.isEmpty());
@@ -506,7 +505,7 @@ public class TestAssignmentManager {
} else {
am.getZKTable().setDisabledTable(REGIONINFO.getTableNameAsString());
}
-
+
RegionTransitionData data = new RegionTransitionData(EventType.M_ZK_REGION_CLOSING,
REGIONINFO.getRegionName(), SERVERNAME_A);
String node = ZKAssign.getNodeName(this.watcher, REGIONINFO.getEncodedName());
@@ -581,7 +580,7 @@ public class TestAssignmentManager {
* @param hri Region to serialize into HRegionInfo
* @return A mocked up Result that fakes a Get on a row in the
* .META. table.
- * @throws IOException
+ * @throws IOException
*/
private Result getMetaTableRowResult(final HRegionInfo hri,
final ServerName sn)
@@ -600,13 +599,13 @@ public class TestAssignmentManager {
Bytes.toBytes(sn.getStartcode())));
return new Result(kvs);
}
-
+
/**
* @param sn ServerName to use making startcode and server in meta
* @param hri Region to serialize into HRegionInfo
* @return A mocked up Result that fakes a Get on a row in the
* .META. table.
- * @throws IOException
+ * @throws IOException
*/
private Result getMetaTableRowResultAsSplitRegion(final HRegionInfo hri, final ServerName sn)
throws IOException {
@@ -668,12 +667,12 @@ public class TestAssignmentManager {
am.shutdown();
}
}
-
+
/**
* Tests the processDeadServersAndRegionsInTransition should not fail with NPE
* when it failed to get the children. Let's abort the system in this
* situation
- * @throws ServiceException
+ * @throws ServiceException
*/
@Test(timeout = 5000)
public void testProcessDeadServersAndRegionsInTransitionShouldNotFailWithNPE()
@@ -713,8 +712,8 @@ public class TestAssignmentManager {
* @param region region to be created as offline
* @param serverName server event originates from
* @return Version of znode created.
- * @throws KeeperException
- * @throws IOException
+ * @throws KeeperException
+ * @throws IOException
*/
// Copied from SplitTransaction rather than open the method over there in
// the regionserver package.
@@ -807,9 +806,9 @@ public class TestAssignmentManager {
server, manager, ct, balancer, executor);
return am;
}
-
+
/**
- * TestCase verifies that the regionPlan is updated whenever a region fails to open
+ * TestCase verifies that the regionPlan is updated whenever a region fails to open
* and the master tries to process RS_ZK_FAILED_OPEN state.(HBASE-5546).
*/
@Test
@@ -863,11 +862,11 @@ public class TestAssignmentManager {
am.shutdown();
}
}
-
+
/**
* Test verifies whether assignment is skipped for regions of tables in DISABLING state during
* clean cluster startup. See HBASE-6281.
- *
+ *
* @throws KeeperException
* @throws IOException
* @throws Exception
@@ -973,7 +972,7 @@ public class TestAssignmentManager {
this.gate.set(true);
return randomServerName;
}
-
+
@Override
public Map> retainAssignment(
Map regions, List servers) {