Index: src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java =================================================================== --- src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java (revision 1345504) +++ src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java (working copy) @@ -25,6 +25,7 @@ import static org.junit.Assert.assertFalse; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; @@ -38,6 +39,7 @@ import org.apache.hadoop.hbase.executor.RegionTransitionData; import org.apache.hadoop.hbase.master.HMaster; import org.apache.hadoop.hbase.master.handler.SplitRegionHandler; +import org.apache.hadoop.hbase.regionserver.SplitTransaction.JournalEntry; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread; import org.apache.hadoop.hbase.util.Threads; @@ -52,6 +54,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; +import org.mockito.internal.util.reflection.Whitebox; /** * Like {@link TestSplitTransaction} in that we're testing {@link SplitTransaction} @@ -586,6 +589,80 @@ } } + @Test + public void testPartialSplit() throws Exception { + final byte[] tableName = Bytes + .toBytes("testPartialSplit"); + + HBaseAdmin admin = new HBaseAdmin(TESTING_UTIL.getConfiguration()); + try { + // Create table then get the single region for our new table. + HTableDescriptor htd = new HTableDescriptor(tableName); + htd.addFamily(new HColumnDescriptor("cf")); + admin.createTable(htd); + + List regions = cluster.getRegions(tableName); + int regionServerIndex = cluster.getServerWith(regions.get(0) + .getRegionName()); + + int size = regions.size(); + LOG.info("No of regions "+regions.size()); + HRegionServer regionServer = cluster.getRegionServer(regionServerIndex); + List journal = new ArrayList(); + journal.add(JournalEntry.STARTED_SPLITTING); + journal.add(JournalEntry.SET_SPLITTING_IN_ZK); + journal.add(JournalEntry.CREATE_SPLIT_DIR); + journal.add(JournalEntry.CLOSED_PARENT_REGION); + journal.add(JournalEntry.OFFLINED_PARENT); + createNodeSplitting(regionServer.getZooKeeperWatcher(), regions.get(0) + .getRegionInfo(), regionServer.getServerName()); + SplitTransaction st = null; + st = new MockedSplitTransaction(regions.get(0), null); + Whitebox.setInternalState(st, "journal", journal); + + try { + st.rollback(regionServer, regionServer); + } catch (IOException e) { + } + Thread.sleep(3000); + List regionsOfTable = cluster.getMaster().getAssignmentManager().getRegionsOfTable(tableName); + assertEquals(size, regionsOfTable.size()); + + } finally { + if (admin.isTableAvailable(tableName) && admin.isTableEnabled(tableName)) { + admin.disableTable(tableName); + admin.deleteTable(tableName); + } + } + + } + + private static int createNodeSplitting(final ZooKeeperWatcher zkw, + final HRegionInfo region, final ServerName serverName) + throws KeeperException, IOException { + RegionTransitionData data = + new RegionTransitionData(EventType.RS_ZK_REGION_SPLITTING, + region.getRegionName(), serverName); + + String node = ZKAssign.getNodeName(zkw, region.getEncodedName()); + if (!ZKUtil.createEphemeralNodeAndWatch(zkw, node, data.getBytes())) { + throw new IOException("Failed create of ephemeral " + node); + } + // Transition node from SPLITTING to SPLITTING and pick up version so we + // can be sure this znode is ours; version is needed deleting. + return transitionNodeSplitting(zkw, region, serverName, -1); + } + + // Copied from SplitTransaction rather than open the method over there in + // the regionserver package. + private static int transitionNodeSplitting(final ZooKeeperWatcher zkw, + final HRegionInfo parent, + final ServerName serverName, final int version) + throws KeeperException, IOException { + return ZKAssign.transitionNode(zkw, parent, serverName, + EventType.RS_ZK_REGION_SPLITTING, EventType.RS_ZK_REGION_SPLITTING, version); + } + public static class MockedSplitTransaction extends SplitTransaction { public MockedSplitTransaction(HRegion r, byte[] splitrow) {