Index: hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHBase7071.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHBase7071.java (revision 0) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHBase7071.java (working copy) @@ -0,0 +1,175 @@ +package org.apache.hadoop.hbase.regionserver; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.HRegionInfo; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Mutation; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.filter.BinaryComparator; +import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; +import org.apache.hadoop.hbase.io.HeapSize; +import org.apache.hadoop.hbase.regionserver.wal.HLog; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.Pair; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.google.common.collect.Lists; + +public class TestHBase7071 { + + private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); + private static volatile boolean putCompleted = false; + private static CountDownLatch latch = new CountDownLatch(1); + private boolean checkAndPutCompleted = false; + private static int count = 0; + + @BeforeClass + public static void setUp() throws Exception { + // final int NUM_MASTERS = 1; + // final int NUM_RS = 3; + // TEST_UTIL.startMiniCluster(NUM_MASTERS, NUM_RS); + + } + + @Test + public void testPutAndCheckAndPut() throws Exception { + + final String tableName = "testPutAndCheckAndPut"; + final String family = "f1"; + Configuration conf = HBaseConfiguration.create(); + conf.setClass(HConstants.REGION_IMPL, MockHRegion.class, HeapSize.class); + final MockHRegion region = (MockHRegion) TestHRegion.initHRegion(Bytes.toBytes(tableName), + tableName, conf, Bytes.toBytes(family)); + + List> putsAndLocks = Lists.newArrayList(); + Put[] puts = new Put[1]; + Put put = new Put(Bytes.toBytes("r1")); + put.add(Bytes.toBytes(family), Bytes.toBytes("q1"), Bytes.toBytes("10")); + puts[0] = put; + Pair pair = new Pair(puts[0], null); + + putsAndLocks.add(pair); + + count++; + region.batchMutate(putsAndLocks.toArray(new Pair[0])); + new Thread() { + + public void run() { + Put[] puts = new Put[1]; + Put put = new Put(Bytes.toBytes("r1")); + put.add(Bytes.toBytes(family), Bytes.toBytes("q1"), Bytes.toBytes("11")); + puts[0] = put; + try { + while (putCompleted == false) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + count++; + region.checkAndMutate(Bytes.toBytes("r1"), Bytes.toBytes(family), Bytes.toBytes("q1"), + CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("10")), put, null, true); + checkAndPutCompleted = true; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }.start(); + + new Thread() { + public void run() { + List> putsAndLocks = Lists.newArrayList(); + Put[] puts = new Put[1]; + Put put = new Put(Bytes.toBytes("r1")); + put.add(Bytes.toBytes(family), Bytes.toBytes("q1"), Bytes.toBytes("50")); + puts[0] = put; + try { + + Pair pair = new Pair(puts[0], null); + + putsAndLocks.add(pair); + + count++; + region.batchMutate(putsAndLocks.toArray(new Pair[0])); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }.start(); + while (!checkAndPutCompleted) { + Thread.sleep(100); + } + Scan s = new Scan(); + RegionScanner scanner = region.getScanner(s); + List results = new ArrayList(); + scanner.next(results, 2); + for (KeyValue keyValue : results) { + System.out.println(Bytes.toString(keyValue.getValue())); + } + + } + + public static class MockHRegion extends HRegion { + + public MockHRegion(Path tableDir, HLog log, FileSystem fs, Configuration conf, + final HRegionInfo regionInfo, final HTableDescriptor htd, RegionServerServices rsServices) { + super(tableDir, log, fs, conf, regionInfo, htd, rsServices); + } + + @Override + public void releaseRowLock(Integer lockId) { + if (count == 1) { + super.releaseRowLock(lockId); + return; + } + + if (count == 2) { + try { + putCompleted = true; + super.releaseRowLock(lockId); + latch.await(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + if (count == 3) { + super.releaseRowLock(lockId); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + latch.countDown(); + } + } + + @Override + public Integer getLock(Integer lockid, byte[] row, boolean waitForLock) throws IOException { + if (count == 3) { + latch.countDown(); + } + return super.getLock(lockid, row, waitForLock); + } + + } + +} Index: hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java (revision 1403629) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java (working copy) @@ -3724,7 +3724,7 @@ * @throws IOException * @return A region on which you must call {@link HRegion#closeHRegion(HRegion)} when done. */ - private static HRegion initHRegion (byte [] tableName, String callingMethod, + public static HRegion initHRegion (byte [] tableName, String callingMethod, Configuration conf, byte [] ... families) throws IOException{ return initHRegion(tableName, null, null, callingMethod, conf, families);