[jira] [Updated] (HBASE-17300) Concurrently calling checkAndPut with expected value as null returns true unexpectedly
[ https://issues.apache.org/jira/browse/HBASE-17300?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Andrew Purtell updated HBASE-17300: --- Attachment: HBASE-17300.patch Refactored test for master. I move the table creation out of the callables because we should be testing for concurrent checkAndPut failure not if operations are racing with table creation. Check your code otherwise [~samarthjain] . Test passes on master. Will come back to this soon to see if it flaps on master, and will port back to branch-1 and 0.98 to check those too. > 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 >Affects Versions: 0.98.23, 1.2.4 >Reporter: Samarth Jain > Attachments: HBASE-17300.patch > > > 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. > 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 (HBaseAdmin admin = TEST_UTIL.getHBaseAdmin()) { > Callable c1 = new CheckAndPutCallable(); > Callable c2 = new CheckAndPutCallable(); > ExecutorService e = Executors.newFixedThreadPool(5); > Future f1 = e.submit(c1); > Future f2 = e.submit(c2); > assertTrue(f1.get() || f2.get()); > assertFalse(f1.get() && f2.get()); > } > } > } > > > private static final class CheckAndPutCallable implements > Callable { > @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 (HBaseAdmin admin = TEST_UTIL.getHBaseAdmin()) { > 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)
[jira] [Updated] (HBASE-17300) Concurrently calling checkAndPut with expected value as null returns true unexpectedly
[ https://issues.apache.org/jira/browse/HBASE-17300?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Samarth Jain updated HBASE-17300: - Description: 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. 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 (HBaseAdmin admin = TEST_UTIL.getHBaseAdmin()) { Callable c1 = new CheckAndPutCallable(); Callable c2 = new CheckAndPutCallable(); ExecutorService e = Executors.newFixedThreadPool(5); Future f1 = e.submit(c1); Future f2 = e.submit(c2); assertTrue(f1.get() || f2.get()); assertFalse(f1.get() && f2.get()); } } } private static final class CheckAndPutCallable implements Callable { @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 (HBaseAdmin admin = TEST_UTIL.getHBaseAdmin()) { 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]. was: 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 c1 = new CheckAndPutCallable(); Callable c2 = new CheckAndPutCallable(); ExecutorService e = Executors.newFixedThreadPool(5); Future f1 = e.submit(c1); Future f2 = e.submit(c2); assertTrue(f1.get() || f2.get()); assertFalse(f1.get() && f2.get()); } } } private static final class CheckAndPutCallable implements Callable { @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()) {
[jira] [Updated] (HBASE-17300) Concurrently calling checkAndPut with expected value as null returns true unexpectedly
[ https://issues.apache.org/jira/browse/HBASE-17300?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Andrew Purtell updated HBASE-17300: --- Affects Version/s: 0.98.23 1.2.4 Set fix versions as reported. Let me see as part of 0.98.24 work if a port of this to HBase API only will repro the issue. If so, if an earlier version worked correctly (0.98.17 perhaps?). If so, what commit broke things. > 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 >Affects Versions: 0.98.23, 1.2.4 >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 c1 = new CheckAndPutCallable(); > Callable c2 = new CheckAndPutCallable(); > ExecutorService e = Executors.newFixedThreadPool(5); > Future f1 = e.submit(c1); > Future f2 = e.submit(c2); > assertTrue(f1.get() || f2.get()); > assertFalse(f1.get() && f2.get()); > } > } > } > > > private static final class CheckAndPutCallable implements > Callable { > @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)