[ 
https://issues.apache.org/jira/browse/HBASE-17300?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15743886#comment-15743886
 ] 

Andrew Purtell commented on HBASE-17300:
----------------------------------------

bq. I am using a bit of Phoenix API to get hold of HBaseAdmin. But it should be 
fairly straightforward to adopt it for HBase IT tests. 
You're more likely to get engagement from the HBase community if the repro case 
just works with the HBase API. FWIW

> Concurrently calling checkAndPut with expected value as null returns true 
> unexpectedly
> --------------------------------------------------------------------------------------
>
>                 Key: HBASE-17300
>                 URL: https://issues.apache.org/jira/browse/HBASE-17300
>             Project: HBase
>          Issue Type: Bug
>            Reporter: Samarth Jain
>
> Attached is the test case. I have added some comments so hopefully the test 
> makes sense. It actually is causing test failures on the Phoenix branches.
> PS - I am using a bit of Phoenix API to get hold of HBaseAdmin. But it should 
> be fairly straightforward to adopt it for HBase IT tests. 
> The test fails consistently using HBase-0.98.23. It exhibits flappy behavior 
> with the 1.2 branch (failed twice in 5 tries). 
> {code}
> @Test
>     public void testNullCheckAndPut() throws Exception {
>          try (Connection conn = DriverManager.getConnection(getUrl())) {
>             try (HBaseAdmin admin = 
> conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
>                 Callable<Boolean> c1 = new CheckAndPutCallable();
>                 Callable<Boolean> c2 = new CheckAndPutCallable();
>                 ExecutorService e = Executors.newFixedThreadPool(5);
>                 Future<Boolean> f1 = e.submit(c1);
>                 Future<Boolean> f2 = e.submit(c2);
>                 assertTrue(f1.get() || f2.get());
>                 assertFalse(f1.get() && f2.get());
>             }    
>         }
>     }
>     
>     
>     private static final class CheckAndPutCallable implements 
> Callable<Boolean> {
>         @Override
>         public Boolean call() throws Exception {
>             byte[] rowToLock = "ROW".getBytes();
>             byte[] colFamily = "COLUMN_FAMILY".getBytes();
>             byte[] column = "COLUMN".getBytes();
>             byte[] newValue = "NEW_VALUE".getBytes();
>             byte[] oldValue = "OLD_VALUE".getBytes();
>             byte[] tableName = "table".getBytes();
>             boolean acquired = false;
>             try (Connection conn = DriverManager.getConnection(getUrl())) {
>                 try (HBaseAdmin admin = 
> conn.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
>                     HTableDescriptor tableDesc = new 
> HTableDescriptor(TableName.valueOf(tableName));
>                     HColumnDescriptor columnDesc = new 
> HColumnDescriptor(colFamily);
>                     columnDesc.setTimeToLive(600);
>                     tableDesc.addFamily(columnDesc);
>                     try {
>                         admin.createTable(tableDesc);
>                     } catch (TableExistsException e) {
>                         // ignore
>                     }
>                     try (HTableInterface table = 
> admin.getConnection().getTable(tableName)) {
>                         Put put = new Put(rowToLock);
>                         put.add(colFamily, column, oldValue); // add a row 
> with column set to oldValue
>                         table.put(put);
>                         put = new Put(rowToLock);
>                         put.add(colFamily, column, newValue);
>                         // only one of the threads should be able to get 
> return value of true for the expected value of oldValue
>                         acquired = table.checkAndPut(rowToLock, colFamily, 
> column, oldValue, put); 
>                         if (!acquired) {
>                            // if a thread didn't get true before, then it 
> shouldn't get true this time either
>                            // because the column DOES exist
>                            acquired = table.checkAndPut(rowToLock, colFamily, 
> column, null, put);
>                         }
>                     }
>                 }
>             }  
>             return acquired;
>         }
>     }
> {code}
> cc [~apurtell], [~jamestaylor], [~lhofhansl]. 



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to