You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2016/10/03 16:49:10 UTC

[1/3] phoenix git commit: PHOENIX-3253 Make changes to tests to support method level parallelization

Repository: phoenix
Updated Branches:
  refs/heads/4.x-HBase-0.98 fc01284b1 -> 1cce661b8


PHOENIX-3253 Make changes to tests to support method level parallelization


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/1cce661b
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/1cce661b
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/1cce661b

Branch: refs/heads/4.x-HBase-0.98
Commit: 1cce661b8eefde5cc7b5d7799ba5e148a91516a7
Parents: d5b3bce
Author: James Taylor <ja...@apache.org>
Authored: Sun Oct 2 12:47:34 2016 -0700
Committer: James Taylor <ja...@apache.org>
Committed: Mon Oct 3 09:51:06 2016 -0700

----------------------------------------------------------------------
 .../apache/phoenix/end2end/AlterTableIT.java    | 49 ----------
 .../phoenix/end2end/FlappingAlterTableIT.java   | 97 ++++++++++++++++++++
 pom.xml                                         | 28 +++---
 3 files changed, 114 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/1cce661b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
index 0125a63..48f4217 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/AlterTableIT.java
@@ -1083,30 +1083,6 @@ public class AlterTableIT extends ParallelStatsDisabledIT {
     }
 
     @Test
-    public void testAddColumnForNewColumnFamily() throws Exception {
-        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
-        String ddl = "CREATE TABLE " + dataTableFullName + " (\n"
-                +"ID1 VARCHAR(15) NOT NULL,\n"
-                +"ID2 VARCHAR(15) NOT NULL,\n"
-                +"CREATED_DATE DATE,\n"
-                +"CREATION_TIME BIGINT,\n"
-                +"LAST_USED DATE,\n"
-                +"CONSTRAINT PK PRIMARY KEY (ID1, ID2)) SALT_BUCKETS = 8";
-        Connection conn1 = DriverManager.getConnection(getUrl(), props);
-        conn1.createStatement().execute(ddl);
-        ddl = "ALTER TABLE " + dataTableFullName + " ADD CF.STRING VARCHAR";
-        conn1.createStatement().execute(ddl);
-        try (HBaseAdmin admin = conn1.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
-            HColumnDescriptor[] columnFamilies = admin.getTableDescriptor(Bytes.toBytes(dataTableFullName)).getColumnFamilies();
-            assertEquals(2, columnFamilies.length);
-            assertEquals("0", columnFamilies[0].getNameAsString());
-            assertEquals(HColumnDescriptor.DEFAULT_TTL, columnFamilies[0].getTimeToLive());
-            assertEquals("CF", columnFamilies[1].getNameAsString());
-            assertEquals(HColumnDescriptor.DEFAULT_TTL, columnFamilies[1].getTimeToLive());
-        }
-    }
-
-    @Test
     public void testSetHColumnProperties() throws Exception {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         String ddl = "CREATE TABLE " + dataTableFullName + " (\n"
@@ -1414,31 +1390,6 @@ public class AlterTableIT extends ParallelStatsDisabledIT {
         }
     }
 
-    @Test
-    public void testNewColumnFamilyInheritsTTLOfEmptyCF() throws Exception {
-        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
-        String ddl = "CREATE TABLE " + dataTableFullName + " (\n"
-                +"ID1 VARCHAR(15) NOT NULL,\n"
-                +"ID2 VARCHAR(15) NOT NULL,\n"
-                +"CREATED_DATE DATE,\n"
-                +"CREATION_TIME BIGINT,\n"
-                +"LAST_USED DATE,\n"
-                +"CONSTRAINT PK PRIMARY KEY (ID1, ID2)) SALT_BUCKETS = 8, TTL = 1000";
-        Connection conn1 = DriverManager.getConnection(getUrl(), props);
-        conn1.createStatement().execute(ddl);
-        ddl = "ALTER TABLE " + dataTableFullName + " ADD CF.STRING VARCHAR";
-        conn1.createStatement().execute(ddl);
-        try (HBaseAdmin admin = conn1.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
-            HTableDescriptor tableDesc = admin.getTableDescriptor(Bytes.toBytes(dataTableFullName));
-            HColumnDescriptor[] columnFamilies = tableDesc.getColumnFamilies();
-            assertEquals(2, columnFamilies.length);
-            assertEquals("0", columnFamilies[0].getNameAsString());
-            assertEquals(1000, columnFamilies[0].getTimeToLive());
-            assertEquals("CF", columnFamilies[1].getNameAsString());
-            assertEquals(1000, columnFamilies[1].getTimeToLive());
-        }
-    }
-
     private static void assertImmutableRows(Connection conn, String fullTableName, boolean expectedValue) throws SQLException {
         PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
         assertEquals(expectedValue, pconn.getTable(new PTableKey(pconn.getTenantId(), fullTableName)).isImmutableRows());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/1cce661b/phoenix-core/src/it/java/org/apache/phoenix/end2end/FlappingAlterTableIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/FlappingAlterTableIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/FlappingAlterTableIT.java
new file mode 100644
index 0000000..a57088a
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/FlappingAlterTableIT.java
@@ -0,0 +1,97 @@
+/*
+ * 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.phoenix.end2end;
+
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+import static org.junit.Assert.assertEquals;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.SchemaUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+public class FlappingAlterTableIT extends ParallelStatsDisabledIT {
+    private String dataTableFullName;
+    
+    @Before
+    public void setupTableNames() throws Exception {
+        String schemaName = "";
+        String dataTableName = generateUniqueName();
+        dataTableFullName = SchemaUtil.getTableName(schemaName, dataTableName);
+    }
+
+    @Test
+    public void testAddColumnForNewColumnFamily() throws Exception {
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        String ddl = "CREATE TABLE " + dataTableFullName + " (\n"
+                +"ID1 VARCHAR(15) NOT NULL,\n"
+                +"ID2 VARCHAR(15) NOT NULL,\n"
+                +"CREATED_DATE DATE,\n"
+                +"CREATION_TIME BIGINT,\n"
+                +"LAST_USED DATE,\n"
+                +"CONSTRAINT PK PRIMARY KEY (ID1, ID2)) SALT_BUCKETS = 8";
+        Connection conn1 = DriverManager.getConnection(getUrl(), props);
+        conn1.createStatement().execute(ddl);
+        ddl = "ALTER TABLE " + dataTableFullName + " ADD CF.STRING VARCHAR";
+        conn1.createStatement().execute(ddl);
+        try (HBaseAdmin admin = conn1.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
+            HColumnDescriptor[] columnFamilies = admin.getTableDescriptor(Bytes.toBytes(dataTableFullName)).getColumnFamilies();
+            assertEquals(2, columnFamilies.length);
+            assertEquals("0", columnFamilies[0].getNameAsString());
+            assertEquals(HColumnDescriptor.DEFAULT_TTL, columnFamilies[0].getTimeToLive());
+            assertEquals("CF", columnFamilies[1].getNameAsString());
+            assertEquals(HColumnDescriptor.DEFAULT_TTL, columnFamilies[1].getTimeToLive());
+        }
+    }
+
+    @Test
+    public void testNewColumnFamilyInheritsTTLOfEmptyCF() throws Exception {
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        String ddl = "CREATE TABLE " + dataTableFullName + " (\n"
+                +"ID1 VARCHAR(15) NOT NULL,\n"
+                +"ID2 VARCHAR(15) NOT NULL,\n"
+                +"CREATED_DATE DATE,\n"
+                +"CREATION_TIME BIGINT,\n"
+                +"LAST_USED DATE,\n"
+                +"CONSTRAINT PK PRIMARY KEY (ID1, ID2)) SALT_BUCKETS = 8, TTL = 1000";
+        Connection conn1 = DriverManager.getConnection(getUrl(), props);
+        conn1.createStatement().execute(ddl);
+        ddl = "ALTER TABLE " + dataTableFullName + " ADD CF.STRING VARCHAR";
+        conn1.createStatement().execute(ddl);
+        try (HBaseAdmin admin = conn1.unwrap(PhoenixConnection.class).getQueryServices().getAdmin()) {
+            HTableDescriptor tableDesc = admin.getTableDescriptor(Bytes.toBytes(dataTableFullName));
+            HColumnDescriptor[] columnFamilies = tableDesc.getColumnFamilies();
+            assertEquals(2, columnFamilies.length);
+            assertEquals("0", columnFamilies[0].getNameAsString());
+            assertEquals(1000, columnFamilies[0].getTimeToLive());
+            assertEquals("CF", columnFamilies[1].getNameAsString());
+            assertEquals(1000, columnFamilies[1].getTimeToLive());
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/1cce661b/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index bc6159f..81f239a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -235,9 +235,8 @@
                 <reuseForks>true</reuseForks>
                 <runOrder>alphabetical</runOrder>
                 <!--parallel>methods</parallel>
-                <threadCount>20</threadCount>
-		<enableAssertions>false</enableAssertions-->
-                <argLine>-Xmx2000m -XX:MaxPermSize=256m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}" -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled -XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68</argLine>
+                <threadCount>20</threadCount-->
+                <argLine>-Xmx2000m -XX:MaxPermSize=256m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}" -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled -XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./target/</argLine>
                 <redirectTestOutputToFile>${test.output.tofile}</redirectTestOutputToFile>
                 <shutdown>kill</shutdown>
                 <testSourceDirectory>${basedir}/src/it/java</testSourceDirectory>
@@ -263,9 +262,16 @@
                 <reuseForks>true</reuseForks>
                 <runOrder>alphabetical</runOrder>
                 <!--parallel>methods</parallel>
-                <threadCount>20</threadCount>
-		<enableAssertions>false</enableAssertions-->
-                <argLine>-Xmx2000m -XX:MaxPermSize=256m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}" -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled -XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68</argLine>
+                <threadCount>20</threadCount-->
+                <!-- We're intermittantly hitting this assertion:
+                     Caused by: java.lang.AssertionError: we should never remove a different context
+	                 at org.apache.hadoop.hbase.regionserver.HRegion$RowLockContext.cleanUp(HRegion.java:5206)
+	                 at org.apache.hadoop.hbase.regionserver.HRegion$RowLockImpl.release(HRegion.java:5246)
+	                 at org.apache.phoenix.coprocessor.MetaDataEndpointImpl.doGetTable(MetaDataEndpointImpl.java:2898)
+	                 at org.apache.phoenix.coprocessor.MetaDataEndpointImpl.doGetTable(MetaDataEndpointImpl.java:2835)
+	                 at org.apache.phoenix.coprocessor.MetaDataEndpointImpl.getTable(MetaDataEndpointImpl.java:490) -->
+		<!--enableAssertions>false</enableAssertions-->
+                <argLine>-Xmx2000m -XX:MaxPermSize=256m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}" -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled -XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./target/</argLine>
                 <redirectTestOutputToFile>${test.output.tofile}</redirectTestOutputToFile>
                 <shutdown>kill</shutdown>
                 <testSourceDirectory>${basedir}/src/it/java</testSourceDirectory>
@@ -289,7 +295,7 @@
                 <forkCount>${numForkedIT}</forkCount>
                 <runOrder>alphabetical</runOrder>
                 <reuseForks>true</reuseForks>
-                <argLine>-enableassertions -Xmx2000m -XX:MaxPermSize=128m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}"</argLine>
+                <argLine>-enableassertions -Xmx2000m -XX:MaxPermSize=128m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}" -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./target/</argLine>
                 <redirectTestOutputToFile>${test.output.tofile}</redirectTestOutputToFile>
                 <testSourceDirectory>${basedir}/src/it/java</testSourceDirectory>
                 <groups>org.apache.phoenix.end2end.ClientManagedTimeTest</groups>
@@ -313,7 +319,7 @@
                 <forkCount>${numForkedIT}</forkCount>
                 <runOrder>alphabetical</runOrder>
                 <reuseForks>true</reuseForks>
-                <argLine>-enableassertions -Xmx3072m -XX:MaxPermSize=256m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}" -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled -XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68</argLine>
+                <argLine>-enableassertions -Xmx2000m -XX:MaxPermSize=128m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}" -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./target/</argLine>
                 <redirectTestOutputToFile>${test.output.tofile}</redirectTestOutputToFile>
                 <testSourceDirectory>${basedir}/src/it/java</testSourceDirectory>
                 <groups>org.apache.phoenix.end2end.HBaseManagedTimeTest</groups>
@@ -331,7 +337,7 @@
                  <forkCount>${numForkedIT}</forkCount>
                  <runOrder>alphabetical</runOrder>
                  <reuseForks>false</reuseForks>
-                 <argLine>-enableassertions -Xmx2000m -XX:MaxPermSize=256m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}"</argLine>
+                 <argLine>-enableassertions -Xmx2000m -XX:MaxPermSize=256m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}" -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./target/</argLine>
                  <redirectTestOutputToFile>${test.output.tofile}</redirectTestOutputToFile>
                  <testSourceDirectory>${basedir}/src/it/java</testSourceDirectory>
                  <groups>org.apache.phoenix.end2end.NeedsOwnMiniClusterTest</groups>
@@ -446,8 +452,8 @@
         <configuration>
           <forkCount>${numForkedUT}</forkCount>
           <reuseForks>true</reuseForks>
-          <argLine>-enableassertions -Xmx2250m -XX:MaxPermSize=128m 
-            -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}"</argLine>
+          <argLine>-enableassertions -Xmx2250m -XX:MaxPermSize=128m
+            -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}" -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./target/</argLine>
           <redirectTestOutputToFile>${test.output.tofile}</redirectTestOutputToFile>
           <shutdown>kill</shutdown>
         </configuration>


[3/3] phoenix git commit: PHOENIX-3338 Move flapping test into test class marked as NotThreadSafe

Posted by ja...@apache.org.
PHOENIX-3338 Move flapping test into test class marked as NotThreadSafe


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/577a6dee
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/577a6dee
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/577a6dee

Branch: refs/heads/4.x-HBase-0.98
Commit: 577a6dee5846c53acb22c4b742e4b780b442df6b
Parents: fc01284
Author: James Taylor <ja...@apache.org>
Authored: Thu Sep 29 17:30:37 2016 -0700
Committer: James Taylor <ja...@apache.org>
Committed: Mon Oct 3 09:51:06 2016 -0700

----------------------------------------------------------------------
 .../phoenix/tx/NotThreadSafeTransactionIT.java  | 138 +++++++++++++++++++
 .../org/apache/phoenix/tx/TransactionIT.java    | 126 -----------------
 2 files changed, 138 insertions(+), 126 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/577a6dee/phoenix-core/src/it/java/org/apache/phoenix/tx/NotThreadSafeTransactionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/tx/NotThreadSafeTransactionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/tx/NotThreadSafeTransactionIT.java
index b50f424..404bb9e 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/tx/NotThreadSafeTransactionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/tx/NotThreadSafeTransactionIT.java
@@ -18,21 +18,38 @@
 package org.apache.phoenix.tx;
 
 import static org.apache.phoenix.util.TestUtil.INDEX_DATA_SCHEMA;
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
 import static org.apache.phoenix.util.TestUtil.createTransactionalTable;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
 
 import javax.annotation.concurrent.NotThreadSafe;
 
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.HTableInterface;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.end2end.ParallelStatsDisabledIT;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.util.PropertiesUtil;
 import org.apache.phoenix.util.TestUtil;
+import org.apache.tephra.TransactionContext;
+import org.apache.tephra.TransactionSystemClient;
+import org.apache.tephra.TxConstants;
+import org.apache.tephra.hbase.TransactionAwareHTable;
 import org.junit.Test;
 
 /**
@@ -190,4 +207,125 @@ public class NotThreadSafeTransactionIT extends ParallelStatsDisabledIT {
         }
     }
 
+    @Test
+    public void testExternalTxContext() throws Exception {
+        ResultSet rs;
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(false);
+        String fullTableName = generateUniqueName();
+        PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
+        
+        TransactionSystemClient txServiceClient = pconn.getQueryServices().getTransactionSystemClient();
+
+        Statement stmt = conn.createStatement();
+        stmt.execute("CREATE TABLE " + fullTableName + "(K VARCHAR PRIMARY KEY, V1 VARCHAR, V2 VARCHAR) TRANSACTIONAL=true");
+        HTableInterface htable = pconn.getQueryServices().getTable(Bytes.toBytes(fullTableName));
+        stmt.executeUpdate("upsert into " + fullTableName + " values('x', 'a', 'a')");
+        conn.commit();
+
+        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
+            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(1,rs.getInt(1));
+        }
+
+        // Use HBase level Tephra APIs to start a new transaction
+        TransactionAwareHTable txAware = new TransactionAwareHTable(htable, TxConstants.ConflictDetection.ROW);
+        TransactionContext txContext = new TransactionContext(txServiceClient, txAware);
+        txContext.start();
+        
+        // Use HBase APIs to add a new row
+        Put put = new Put(Bytes.toBytes("z"));
+        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
+        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, Bytes.toBytes("V1"), Bytes.toBytes("b"));
+        txAware.put(put);
+        
+        // Use Phoenix APIs to add new row (sharing the transaction context)
+        pconn.setTransactionContext(txContext);
+        conn.createStatement().executeUpdate("upsert into " + fullTableName + " values('y', 'c', 'c')");
+
+        // New connection should not see data as it hasn't been committed yet
+        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
+            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(1,rs.getInt(1));
+        }
+        
+        // Use new connection to create a row with a conflict
+        Connection connWithConflict = DriverManager.getConnection(getUrl(), props);
+        connWithConflict.createStatement().execute("upsert into " + fullTableName + " values('z', 'd', 'd')");
+        
+        // Existing connection should see data even though it hasn't been committed yet
+        rs = conn.createStatement().executeQuery("select count(*) from " + fullTableName);
+        assertTrue(rs.next());
+        assertEquals(3,rs.getInt(1));
+        
+        // Use Tephra APIs directly to finish (i.e. commit) the transaction
+        txContext.finish();
+        
+        // Confirm that attempt to commit row with conflict fails
+        try {
+            connWithConflict.commit();
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.TRANSACTION_CONFLICT_EXCEPTION.getErrorCode(), e.getErrorCode());
+        } finally {
+            connWithConflict.close();
+        }
+        
+        // New connection should now see data as it has been committed
+        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
+            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(3,rs.getInt(1));
+        }
+        
+        // Repeat the same as above, but this time abort the transaction
+        txContext = new TransactionContext(txServiceClient, txAware);
+        txContext.start();
+        
+        // Use HBase APIs to add a new row
+        put = new Put(Bytes.toBytes("j"));
+        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
+        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, Bytes.toBytes("V1"), Bytes.toBytes("e"));
+        txAware.put(put);
+        
+        // Use Phoenix APIs to add new row (sharing the transaction context)
+        pconn.setTransactionContext(txContext);
+        conn.createStatement().executeUpdate("upsert into " + fullTableName + " values('k', 'f', 'f')");
+        
+        // Existing connection should see data even though it hasn't been committed yet
+        rs = conn.createStatement().executeQuery("select count(*) from " + fullTableName);
+        assertTrue(rs.next());
+        assertEquals(5,rs.getInt(1));
+
+        connWithConflict.createStatement().execute("upsert into " + fullTableName + " values('k', 'g', 'g')");
+        rs = connWithConflict.createStatement().executeQuery("select count(*) from " + fullTableName);
+        assertTrue(rs.next());
+        assertEquals(4,rs.getInt(1));
+
+        // Use Tephra APIs directly to abort (i.e. rollback) the transaction
+        txContext.abort();
+        
+        rs = conn.createStatement().executeQuery("select count(*) from " + fullTableName);
+        assertTrue(rs.next());
+        assertEquals(3,rs.getInt(1));
+
+        // Should succeed since conflicting row was aborted
+        connWithConflict.commit();
+
+        // New connection should now see data as it has been committed
+        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
+            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(4,rs.getInt(1));
+        }
+        
+        // Even using HBase APIs directly, we shouldn't find 'j' since a delete marker would have been
+        // written to hide it.
+        Result result = htable.get(new Get(Bytes.toBytes("j")));
+        assertTrue(result.isEmpty());
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/577a6dee/phoenix-core/src/it/java/org/apache/phoenix/tx/TransactionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/tx/TransactionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/tx/TransactionIT.java
index 8c3ad7f..2e45d5a 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/tx/TransactionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/tx/TransactionIT.java
@@ -38,11 +38,9 @@ import java.util.Properties;
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.TableName;
-import org.apache.hadoop.hbase.client.Get;
 import org.apache.hadoop.hbase.client.HBaseAdmin;
 import org.apache.hadoop.hbase.client.HTableInterface;
 import org.apache.hadoop.hbase.client.Put;
-import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.coprocessor.PhoenixTransactionalProcessor;
 import org.apache.phoenix.end2end.ParallelStatsDisabledIT;
@@ -59,10 +57,7 @@ import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.PropertiesUtil;
 import org.apache.phoenix.util.StringUtil;
 import org.apache.phoenix.util.TestUtil;
-import org.apache.tephra.TransactionContext;
-import org.apache.tephra.TransactionSystemClient;
 import org.apache.tephra.TxConstants;
-import org.apache.tephra.hbase.TransactionAwareHTable;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -562,127 +557,6 @@ public class TransactionIT extends ParallelStatsDisabledIT {
     }
     
     @Test
-    public void testExternalTxContext() throws Exception {
-        ResultSet rs;
-        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        conn.setAutoCommit(false);
-        String fullTableName = generateUniqueName();
-        PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
-        
-        TransactionSystemClient txServiceClient = pconn.getQueryServices().getTransactionSystemClient();
-
-        Statement stmt = conn.createStatement();
-        stmt.execute("CREATE TABLE " + fullTableName + "(K VARCHAR PRIMARY KEY, V1 VARCHAR, V2 VARCHAR) TRANSACTIONAL=true");
-        HTableInterface htable = pconn.getQueryServices().getTable(Bytes.toBytes(fullTableName));
-        stmt.executeUpdate("upsert into " + fullTableName + " values('x', 'a', 'a')");
-        conn.commit();
-
-        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
-            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(1,rs.getInt(1));
-        }
-
-        // Use HBase level Tephra APIs to start a new transaction
-        TransactionAwareHTable txAware = new TransactionAwareHTable(htable, TxConstants.ConflictDetection.ROW);
-        TransactionContext txContext = new TransactionContext(txServiceClient, txAware);
-        txContext.start();
-        
-        // Use HBase APIs to add a new row
-        Put put = new Put(Bytes.toBytes("z"));
-        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
-        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, Bytes.toBytes("V1"), Bytes.toBytes("b"));
-        txAware.put(put);
-        
-        // Use Phoenix APIs to add new row (sharing the transaction context)
-        pconn.setTransactionContext(txContext);
-        conn.createStatement().executeUpdate("upsert into " + fullTableName + " values('y', 'c', 'c')");
-
-        // New connection should not see data as it hasn't been committed yet
-        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
-            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(1,rs.getInt(1));
-        }
-        
-        // Use new connection to create a row with a conflict
-        Connection connWithConflict = DriverManager.getConnection(getUrl(), props);
-        connWithConflict.createStatement().execute("upsert into " + fullTableName + " values('z', 'd', 'd')");
-        
-        // Existing connection should see data even though it hasn't been committed yet
-        rs = conn.createStatement().executeQuery("select count(*) from " + fullTableName);
-        assertTrue(rs.next());
-        assertEquals(3,rs.getInt(1));
-        
-        // Use Tephra APIs directly to finish (i.e. commit) the transaction
-        txContext.finish();
-        
-        // Confirm that attempt to commit row with conflict fails
-        try {
-            connWithConflict.commit();
-            fail();
-        } catch (SQLException e) {
-            assertEquals(SQLExceptionCode.TRANSACTION_CONFLICT_EXCEPTION.getErrorCode(), e.getErrorCode());
-        } finally {
-            connWithConflict.close();
-        }
-        
-        // New connection should now see data as it has been committed
-        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
-            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(3,rs.getInt(1));
-        }
-        
-        // Repeat the same as above, but this time abort the transaction
-        txContext = new TransactionContext(txServiceClient, txAware);
-        txContext.start();
-        
-        // Use HBase APIs to add a new row
-        put = new Put(Bytes.toBytes("j"));
-        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
-        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, Bytes.toBytes("V1"), Bytes.toBytes("e"));
-        txAware.put(put);
-        
-        // Use Phoenix APIs to add new row (sharing the transaction context)
-        pconn.setTransactionContext(txContext);
-        conn.createStatement().executeUpdate("upsert into " + fullTableName + " values('k', 'f', 'f')");
-        
-        // Existing connection should see data even though it hasn't been committed yet
-        rs = conn.createStatement().executeQuery("select count(*) from " + fullTableName);
-        assertTrue(rs.next());
-        assertEquals(5,rs.getInt(1));
-
-        connWithConflict.createStatement().execute("upsert into " + fullTableName + " values('k', 'g', 'g')");
-        rs = connWithConflict.createStatement().executeQuery("select count(*) from " + fullTableName);
-        assertTrue(rs.next());
-        assertEquals(4,rs.getInt(1));
-
-        // Use Tephra APIs directly to abort (i.e. rollback) the transaction
-        txContext.abort();
-        
-        rs = conn.createStatement().executeQuery("select count(*) from " + fullTableName);
-        assertTrue(rs.next());
-        assertEquals(3,rs.getInt(1));
-
-        // Should succeed since conflicting row was aborted
-        connWithConflict.commit();
-
-        // New connection should now see data as it has been committed
-        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
-            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(4,rs.getInt(1));
-        }
-        
-        // Even using HBase APIs directly, we shouldn't find 'j' since a delete marker would have been
-        // written to hide it.
-        Result result = htable.get(new Get(Bytes.toBytes("j")));
-        assertTrue(result.isEmpty());
-    }
-
-    @Test
     public void testCheckpointAndRollback() throws Exception {
         Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
         Connection conn = DriverManager.getConnection(getUrl(), props);


[2/3] phoenix git commit: PHOENIX-3253 Make changes to tests to support method level parallelization

Posted by ja...@apache.org.
PHOENIX-3253 Make changes to tests to support method level parallelization


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/d5b3bced
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/d5b3bced
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/d5b3bced

Branch: refs/heads/4.x-HBase-0.98
Commit: d5b3bcedf34e716a54038410e29dafb21ac05ccf
Parents: 577a6de
Author: James Taylor <ja...@apache.org>
Authored: Sun Oct 2 11:10:14 2016 -0700
Committer: James Taylor <ja...@apache.org>
Committed: Mon Oct 3 09:51:06 2016 -0700

----------------------------------------------------------------------
 .../phoenix/end2end/FlappingLocalIndexIT.java   | 300 +++++++++++++++++
 .../phoenix/end2end/index/BaseLocalIndexIT.java |  80 +++++
 .../phoenix/end2end/index/LocalIndexIT.java     | 299 +----------------
 .../phoenix/tx/FlappingTransactionIT.java       | 328 ++++++++++++++++++
 .../phoenix/tx/NotThreadSafeTransactionIT.java  | 331 -------------------
 pom.xml                                         |   4 +-
 6 files changed, 712 insertions(+), 630 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/d5b3bced/phoenix-core/src/it/java/org/apache/phoenix/end2end/FlappingLocalIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/FlappingLocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/FlappingLocalIndexIT.java
new file mode 100644
index 0000000..7509997
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/FlappingLocalIndexIT.java
@@ -0,0 +1,300 @@
+/*
+ * 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.phoenix.end2end;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.phoenix.end2end.index.BaseLocalIndexIT;
+import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.util.QueryUtil;
+import org.apache.phoenix.util.SchemaUtil;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.Test;
+
+public class FlappingLocalIndexIT extends BaseLocalIndexIT {
+
+    public FlappingLocalIndexIT(boolean isNamespaceMapped) {
+        super(isNamespaceMapped);
+    }
+
+    @Test
+    public void testScanWhenATableHasMultipleLocalIndexes() throws Exception {
+        String tableName = schemaName + "." + generateUniqueName();
+        String indexName = "IDX_" + generateUniqueName();
+
+        createBaseTable(tableName, null, "('e','i','o')");
+        Connection conn1 = DriverManager.getConnection(getUrl());
+        try {
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('b',1,2,4,'z')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('f',1,2,3,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('j',2,4,2,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('q',3,1,1,'c')");
+            conn1.commit();
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + "2 ON " + tableName + "(k3)");
+            conn1.commit();
+            conn1 = DriverManager.getConnection(getUrl());
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + tableName);
+            assertTrue(rs.next());
+            assertEquals(4, rs.getInt(1));
+        } finally {
+            conn1.close();
+        }
+    }
+
+    @Test
+    public void testLocalIndexScanWithSmallChunks() throws Exception {
+        String tableName = schemaName + "." + generateUniqueName();
+        String indexName = "IDX_" + generateUniqueName();
+
+        createBaseTable(tableName, 3, null);
+        Properties props = new Properties();
+        props.setProperty(QueryServices.SCAN_RESULT_CHUNK_SIZE, "2");
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(isNamespaceMapped));
+        Connection conn1 = DriverManager.getConnection(getUrl(), props);
+        try{
+            String[] strings = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
+            for (int i = 0; i < 26; i++) {
+               conn1.createStatement().execute(
+                    "UPSERT INTO " + tableName + " values('"+strings[i]+"'," + i + ","
+                            + (i + 1) + "," + (i + 2) + ",'" + strings[25 - i] + "')");
+            }
+            conn1.commit();
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + "_2 ON " + tableName + "(k3)");
+
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT * FROM " + tableName);
+            assertTrue(rs.next());
+
+            String query = "SELECT t_id,k1,v1 FROM " + tableName;
+            rs = conn1.createStatement().executeQuery(query);
+            for (int j = 0; j < 26; j++) {
+                assertTrue(rs.next());
+                assertEquals(strings[25 - j], rs.getString("t_id"));
+                assertEquals(25 - j, rs.getInt("k1"));
+                assertEquals(strings[j], rs.getString("V1"));
+            }
+            query = "SELECT t_id,k1,k3 FROM " + tableName;
+            rs = conn1.createStatement().executeQuery(query);
+            Thread.sleep(1000);
+            for (int j = 0; j < 26; j++) {
+                assertTrue(rs.next());
+                assertEquals(strings[j], rs.getString("t_id"));
+                assertEquals(j, rs.getInt("k1"));
+                assertEquals(j + 2, rs.getInt("k3"));
+            }
+       } finally {
+            conn1.close();
+        }
+    }
+    
+    @Test
+    public void testLocalIndexScan() throws Exception {
+        String tableName = schemaName + "." + generateUniqueName();
+        String indexName = "IDX_" + generateUniqueName();
+        String indexTableName = schemaName + "." + indexName;
+        TableName physicalTableName = SchemaUtil.getPhysicalTableName(tableName.getBytes(), isNamespaceMapped);
+        String indexPhysicalTableName = physicalTableName.getNameAsString();
+
+        createBaseTable(tableName, null, "('e','i','o')");
+        Connection conn1 = DriverManager.getConnection(getUrl());
+        try{
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('a',1,2,5,'y')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('b',1,2,4,'z')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('f',1,2,3,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('e',1,2,3,'b')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('j',2,4,2,'a')");
+            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('q',3,1,1,'c')");
+            conn1.commit();
+            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+            
+            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + indexTableName);
+            assertTrue(rs.next());
+            
+            HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+            int numRegions = admin.getTableRegions(physicalTableName).size();
+            
+            String query = "SELECT * FROM " + tableName +" where v1 like 'a%'";
+            rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
+            
+            assertEquals(
+                "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
+                        + indexPhysicalTableName + " [1,'a'] - [1,'b']\n"
+                                + "    SERVER FILTER BY FIRST KEY ONLY\n"
+                                + "CLIENT MERGE SORT",
+                        QueryUtil.getExplainPlan(rs));
+            
+            rs = conn1.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("f", rs.getString("t_id"));
+            assertEquals(1, rs.getInt("k1"));
+            assertEquals(2, rs.getInt("k2"));
+            assertEquals("a", rs.getString("v1"));
+            assertEquals(3, rs.getInt("k3"));
+            assertTrue(rs.next());
+            assertEquals("j", rs.getString("t_id"));
+            assertEquals(2, rs.getInt("k1"));
+            assertEquals(4, rs.getInt("k2"));
+            assertEquals("a", rs.getString("v1"));
+            assertEquals(2, rs.getInt("k3"));
+            assertFalse(rs.next());
+            query = "SELECT t_id, k1, k2,V1 FROM " + tableName +" where v1='a'";
+            rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
+            
+            assertEquals(
+                "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
+                        + indexPhysicalTableName + " [1,'a']\n"
+                        + "    SERVER FILTER BY FIRST KEY ONLY\n"
+                        + "CLIENT MERGE SORT",
+                        QueryUtil.getExplainPlan(rs));
+            
+            rs = conn1.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("f", rs.getString("t_id"));
+            assertEquals(1, rs.getInt("k1"));
+            assertEquals(2, rs.getInt("k2"));
+            assertTrue(rs.next());
+            assertEquals("j", rs.getString("t_id"));
+            assertEquals(2, rs.getInt("k1"));
+            assertEquals(4, rs.getInt("k2"));
+            assertFalse(rs.next());
+            query = "SELECT t_id, k1, k2,V1, k3 FROM " + tableName +" where v1<='z' order by k3";
+            rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
+            
+            assertEquals("CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER " + indexPhysicalTableName
+                    + " [1,*] - [1,'z']\n" + "    SERVER FILTER BY FIRST KEY ONLY\n"
+                    + "    SERVER SORTED BY [\"K3\"]\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
+ 
+            rs = conn1.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals(1, rs.getInt("k3"));
+            assertTrue(rs.next());
+            assertEquals(2, rs.getInt("k3"));
+            assertTrue(rs.next());
+            assertEquals(3, rs.getInt("k3"));
+            assertTrue(rs.next());
+            assertEquals(3, rs.getInt("k3"));
+            assertTrue(rs.next());
+            assertEquals(4, rs.getInt("k3"));
+            assertTrue(rs.next());
+            assertEquals(5, rs.getInt("k3"));
+            assertFalse(rs.next());
+            
+            query = "SELECT t_id, k1, k2,v1 from " + tableName + " order by V1,t_id";
+            rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
+            
+            assertEquals(
+                "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
+                        + indexPhysicalTableName +" [1]\n"
+                        + "    SERVER FILTER BY FIRST KEY ONLY\n"
+                        + "CLIENT MERGE SORT",
+                QueryUtil.getExplainPlan(rs));
+            
+            rs = conn1.createStatement().executeQuery(query);
+            assertTrue(rs.next());
+            assertEquals("f", rs.getString("t_id"));
+            assertEquals(1, rs.getInt("k1"));
+            assertEquals(2, rs.getInt("k2"));
+            assertEquals("a", rs.getString("V1"));
+            assertTrue(rs.next());
+            assertEquals("j", rs.getString("t_id"));
+            assertEquals(2, rs.getInt("k1"));
+            assertEquals(4, rs.getInt("k2"));
+            assertEquals("a", rs.getString("V1"));
+            assertTrue(rs.next());
+            assertEquals("e", rs.getString("t_id"));
+            assertEquals(1, rs.getInt("k1"));
+            assertEquals(2, rs.getInt("k2"));
+            assertEquals("b", rs.getString("V1"));
+            assertTrue(rs.next());
+            assertEquals("q", rs.getString("t_id"));
+            assertEquals(3, rs.getInt("k1"));
+            assertEquals(1, rs.getInt("k2"));
+            assertEquals("c", rs.getString("V1"));
+            assertTrue(rs.next());
+            assertEquals("a", rs.getString("t_id"));
+            assertEquals(1, rs.getInt("k1"));
+            assertEquals(2, rs.getInt("k2"));
+            assertEquals("y", rs.getString("V1"));
+            assertTrue(rs.next());
+            assertEquals("b", rs.getString("t_id"));
+            assertEquals(1, rs.getInt("k1"));
+            assertEquals(2, rs.getInt("k2"));
+            assertEquals("z", rs.getString("V1"));
+        } finally {
+            conn1.close();
+        }
+    }
+
+    @Test
+    public void testBuildIndexWhenUserTableAlreadyHasData() throws Exception {
+        String tableName = schemaName + "." + generateUniqueName();
+        String indexName = "IDX_" + generateUniqueName();
+        String indexTableName = schemaName + "." + indexName;
+        TableName physicalTableName = SchemaUtil.getPhysicalTableName(tableName.getBytes(), isNamespaceMapped);
+        String indexPhysicalTableName = physicalTableName.getNameAsString();
+
+        createBaseTable(tableName, null, "('e','i','o')");
+        Connection conn1 = DriverManager.getConnection(getUrl());
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('b',1,2,4,'z')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('f',1,2,3,'z')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('j',2,4,2,'a')");
+        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('q',3,1,1,'c')");
+        conn1.commit();
+        conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
+        ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + indexTableName);
+        assertTrue(rs.next());
+        assertEquals(4, rs.getInt(1));
+        HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
+        HTable indexTable = new HTable(admin.getConfiguration(),Bytes.toBytes(indexPhysicalTableName));
+        Pair<byte[][], byte[][]> startEndKeys = indexTable.getStartEndKeys();
+        byte[][] startKeys = startEndKeys.getFirst();
+        byte[][] endKeys = startEndKeys.getSecond();
+        for (int i = 0; i < startKeys.length; i++) {
+            Scan s = new Scan();
+            s.addFamily(QueryConstants.DEFAULT_LOCAL_INDEX_COLUMN_FAMILY_BYTES);
+            s.setStartRow(startKeys[i]);
+            s.setStopRow(endKeys[i]);
+            ResultScanner scanner = indexTable.getScanner(s);
+            int count = 0;
+            for(Result r:scanner){
+                count++;
+            }
+            scanner.close();
+            assertEquals(1, count);
+        }
+        indexTable.close();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d5b3bced/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseLocalIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseLocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseLocalIndexIT.java
new file mode 100644
index 0000000..5c8670d
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/BaseLocalIndexIT.java
@@ -0,0 +1,80 @@
+/*
+ * 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.phoenix.end2end.index;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Properties;
+
+import org.apache.phoenix.end2end.ParallelStatsDisabledIT;
+import org.apache.phoenix.query.BaseTest;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.TestUtil;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public abstract class BaseLocalIndexIT extends ParallelStatsDisabledIT {
+    protected boolean isNamespaceMapped;
+    protected String schemaName;
+
+    public BaseLocalIndexIT(boolean isNamespaceMapped) {
+        this.isNamespaceMapped = isNamespaceMapped;
+    }
+    
+    @Before
+    public void setup() {
+        schemaName = BaseTest.generateUniqueName();
+    }
+    
+    protected Connection getConnection() throws SQLException{
+        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
+        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(isNamespaceMapped));
+        return DriverManager.getConnection(getUrl(),props);
+    }
+
+    protected void createBaseTable(String tableName, Integer saltBuckets, String splits) throws SQLException {
+        Connection conn = getConnection();
+        if (isNamespaceMapped) {
+            conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schemaName);
+        }
+        String ddl = "CREATE TABLE " + tableName + " (t_id VARCHAR NOT NULL,\n" +
+                "k1 INTEGER NOT NULL,\n" +
+                "k2 INTEGER NOT NULL,\n" +
+                "k3 INTEGER,\n" +
+                "v1 VARCHAR,\n" +
+                "CONSTRAINT pk PRIMARY KEY (t_id, k1, k2))\n"
+                        + (saltBuckets != null && splits == null ? (" salt_buckets=" + saltBuckets) : ""
+                        + (saltBuckets == null && splits != null ? (" split on " + splits) : ""));
+        conn.createStatement().execute(ddl);
+        conn.close();
+    }
+
+    @Parameters(name = "LocalIndexIT_isNamespaceMapped={0}") // name is used by failsafe as file name in reports
+    public static Collection<Boolean> data() {
+        return Arrays.asList(true, false);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d5b3bced/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
index 234a466..bf99db0 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
@@ -31,9 +31,7 @@ import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
-import java.util.Arrays;
 import java.util.Collection;
-import java.util.Properties;
 
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HTableDescriptor;
@@ -47,64 +45,25 @@ import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.coprocessor.BaseScannerRegionObserver;
-import org.apache.phoenix.end2end.ParallelStatsDisabledIT;
 import org.apache.phoenix.hbase.index.IndexRegionSplitPolicy;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixStatement;
-import org.apache.phoenix.query.BaseTest;
 import org.apache.phoenix.query.QueryConstants;
-import org.apache.phoenix.query.QueryServices;
 import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.PTable;
 import org.apache.phoenix.schema.PTable.IndexType;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.TableNotFoundException;
-import org.apache.phoenix.util.PropertiesUtil;
 import org.apache.phoenix.util.QueryUtil;
 import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.util.TestUtil;
-import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class LocalIndexIT extends ParallelStatsDisabledIT {
-    private boolean isNamespaceMapped;
-    private String schemaName;
 
+public class LocalIndexIT extends BaseLocalIndexIT {
     public LocalIndexIT(boolean isNamespaceMapped) {
-        this.isNamespaceMapped = isNamespaceMapped;
-    }
-    
-    @Before
-    public void setup() {
-        schemaName = BaseTest.generateUniqueName();
+        super(isNamespaceMapped);
     }
     
-    private void createBaseTable(String tableName, Integer saltBuckets, String splits) throws SQLException {
-        Connection conn = getConnection();
-        if (isNamespaceMapped) {
-            conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS " + schemaName);
-        }
-        String ddl = "CREATE TABLE " + tableName + " (t_id VARCHAR NOT NULL,\n" +
-                "k1 INTEGER NOT NULL,\n" +
-                "k2 INTEGER NOT NULL,\n" +
-                "k3 INTEGER,\n" +
-                "v1 VARCHAR,\n" +
-                "CONSTRAINT pk PRIMARY KEY (t_id, k1, k2))\n"
-                        + (saltBuckets != null && splits == null ? (" salt_buckets=" + saltBuckets) : ""
-                        + (saltBuckets == null && splits != null ? (" split on " + splits) : ""));
-        conn.createStatement().execute(ddl);
-        conn.close();
-    }
-
-    @Parameters(name = "LocalIndexIT_isNamespaceMapped={0}") // name is used by failsafe as file name in reports
-    public static Collection<Boolean> data() {
-        return Arrays.asList(true, false);
-    }
-
     @Test
     public void testLocalIndexRoundTrip() throws Exception {
         String tableName = schemaName + "." + generateUniqueName();
@@ -192,12 +151,6 @@ public class LocalIndexIT extends ParallelStatsDisabledIT {
         }
     }
     
-    private Connection getConnection() throws SQLException{
-        Properties props = PropertiesUtil.deepCopy(TestUtil.TEST_PROPERTIES);
-        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(isNamespaceMapped));
-        return DriverManager.getConnection(getUrl(),props);
-    }
-
     @Test
     public void testDropLocalIndexTable() throws Exception {
         String tableName = schemaName + "." + generateUniqueName();
@@ -257,184 +210,6 @@ public class LocalIndexIT extends ParallelStatsDisabledIT {
     }
     
     @Test
-    public void testBuildIndexWhenUserTableAlreadyHasData() throws Exception {
-        String tableName = schemaName + "." + generateUniqueName();
-        String indexName = "IDX_" + generateUniqueName();
-        String indexTableName = schemaName + "." + indexName;
-        TableName physicalTableName = SchemaUtil.getPhysicalTableName(tableName.getBytes(), isNamespaceMapped);
-        String indexPhysicalTableName = physicalTableName.getNameAsString();
-
-        createBaseTable(tableName, null, "('e','i','o')");
-        Connection conn1 = DriverManager.getConnection(getUrl());
-        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('b',1,2,4,'z')");
-        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('f',1,2,3,'z')");
-        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('j',2,4,2,'a')");
-        conn1.createStatement().execute("UPSERT INTO "+tableName+" values('q',3,1,1,'c')");
-        conn1.commit();
-        conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
-        ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + indexTableName);
-        assertTrue(rs.next());
-        assertEquals(4, rs.getInt(1));
-        HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
-        HTable indexTable = new HTable(admin.getConfiguration(),Bytes.toBytes(indexPhysicalTableName));
-        Pair<byte[][], byte[][]> startEndKeys = indexTable.getStartEndKeys();
-        byte[][] startKeys = startEndKeys.getFirst();
-        byte[][] endKeys = startEndKeys.getSecond();
-        for (int i = 0; i < startKeys.length; i++) {
-            Scan s = new Scan();
-            s.addFamily(QueryConstants.DEFAULT_LOCAL_INDEX_COLUMN_FAMILY_BYTES);
-            s.setStartRow(startKeys[i]);
-            s.setStopRow(endKeys[i]);
-            ResultScanner scanner = indexTable.getScanner(s);
-            int count = 0;
-            for(Result r:scanner){
-                count++;
-            }
-            scanner.close();
-            assertEquals(1, count);
-        }
-        indexTable.close();
-    }
-
-    @Test
-    public void testLocalIndexScan() throws Exception {
-        String tableName = schemaName + "." + generateUniqueName();
-        String indexName = "IDX_" + generateUniqueName();
-        String indexTableName = schemaName + "." + indexName;
-        TableName physicalTableName = SchemaUtil.getPhysicalTableName(tableName.getBytes(), isNamespaceMapped);
-        String indexPhysicalTableName = physicalTableName.getNameAsString();
-
-        createBaseTable(tableName, null, "('e','i','o')");
-        Connection conn1 = DriverManager.getConnection(getUrl());
-        try{
-            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('a',1,2,5,'y')");
-            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('b',1,2,4,'z')");
-            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('f',1,2,3,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('e',1,2,3,'b')");
-            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('j',2,4,2,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('q',3,1,1,'c')");
-            conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
-            
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + indexTableName);
-            assertTrue(rs.next());
-            
-            HBaseAdmin admin = driver.getConnectionQueryServices(getUrl(), TestUtil.TEST_PROPERTIES).getAdmin();
-            int numRegions = admin.getTableRegions(physicalTableName).size();
-            
-            String query = "SELECT * FROM " + tableName +" where v1 like 'a%'";
-            rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
-            
-            assertEquals(
-                "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
-                        + indexPhysicalTableName + " [1,'a'] - [1,'b']\n"
-                                + "    SERVER FILTER BY FIRST KEY ONLY\n"
-                                + "CLIENT MERGE SORT",
-                        QueryUtil.getExplainPlan(rs));
-            
-            rs = conn1.createStatement().executeQuery(query);
-            assertTrue(rs.next());
-            assertEquals("f", rs.getString("t_id"));
-            assertEquals(1, rs.getInt("k1"));
-            assertEquals(2, rs.getInt("k2"));
-            assertEquals("a", rs.getString("v1"));
-            assertEquals(3, rs.getInt("k3"));
-            assertTrue(rs.next());
-            assertEquals("j", rs.getString("t_id"));
-            assertEquals(2, rs.getInt("k1"));
-            assertEquals(4, rs.getInt("k2"));
-            assertEquals("a", rs.getString("v1"));
-            assertEquals(2, rs.getInt("k3"));
-            assertFalse(rs.next());
-            query = "SELECT t_id, k1, k2,V1 FROM " + tableName +" where v1='a'";
-            rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
-            
-            assertEquals(
-                "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
-                        + indexPhysicalTableName + " [1,'a']\n"
-                        + "    SERVER FILTER BY FIRST KEY ONLY\n"
-                        + "CLIENT MERGE SORT",
-                        QueryUtil.getExplainPlan(rs));
-            
-            rs = conn1.createStatement().executeQuery(query);
-            assertTrue(rs.next());
-            assertEquals("f", rs.getString("t_id"));
-            assertEquals(1, rs.getInt("k1"));
-            assertEquals(2, rs.getInt("k2"));
-            assertTrue(rs.next());
-            assertEquals("j", rs.getString("t_id"));
-            assertEquals(2, rs.getInt("k1"));
-            assertEquals(4, rs.getInt("k2"));
-            assertFalse(rs.next());
-            query = "SELECT t_id, k1, k2,V1, k3 FROM " + tableName +" where v1<='z' order by k3";
-            rs = conn1.createStatement().executeQuery("EXPLAIN "+ query);
-            
-            assertEquals("CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER " + indexPhysicalTableName
-                    + " [1,*] - [1,'z']\n" + "    SERVER FILTER BY FIRST KEY ONLY\n"
-                    + "    SERVER SORTED BY [\"K3\"]\n" + "CLIENT MERGE SORT", QueryUtil.getExplainPlan(rs));
- 
-            rs = conn1.createStatement().executeQuery(query);
-            assertTrue(rs.next());
-            assertEquals(1, rs.getInt("k3"));
-            assertTrue(rs.next());
-            assertEquals(2, rs.getInt("k3"));
-            assertTrue(rs.next());
-            assertEquals(3, rs.getInt("k3"));
-            assertTrue(rs.next());
-            assertEquals(3, rs.getInt("k3"));
-            assertTrue(rs.next());
-            assertEquals(4, rs.getInt("k3"));
-            assertTrue(rs.next());
-            assertEquals(5, rs.getInt("k3"));
-            assertFalse(rs.next());
-            
-            query = "SELECT t_id, k1, k2,v1 from " + tableName + " order by V1,t_id";
-            rs = conn1.createStatement().executeQuery("EXPLAIN " + query);
-            
-            assertEquals(
-                "CLIENT PARALLEL " + numRegions + "-WAY RANGE SCAN OVER "
-                        + indexPhysicalTableName +" [1]\n"
-                        + "    SERVER FILTER BY FIRST KEY ONLY\n"
-                        + "CLIENT MERGE SORT",
-                QueryUtil.getExplainPlan(rs));
-            
-            rs = conn1.createStatement().executeQuery(query);
-            assertTrue(rs.next());
-            assertEquals("f", rs.getString("t_id"));
-            assertEquals(1, rs.getInt("k1"));
-            assertEquals(2, rs.getInt("k2"));
-            assertEquals("a", rs.getString("V1"));
-            assertTrue(rs.next());
-            assertEquals("j", rs.getString("t_id"));
-            assertEquals(2, rs.getInt("k1"));
-            assertEquals(4, rs.getInt("k2"));
-            assertEquals("a", rs.getString("V1"));
-            assertTrue(rs.next());
-            assertEquals("e", rs.getString("t_id"));
-            assertEquals(1, rs.getInt("k1"));
-            assertEquals(2, rs.getInt("k2"));
-            assertEquals("b", rs.getString("V1"));
-            assertTrue(rs.next());
-            assertEquals("q", rs.getString("t_id"));
-            assertEquals(3, rs.getInt("k1"));
-            assertEquals(1, rs.getInt("k2"));
-            assertEquals("c", rs.getString("V1"));
-            assertTrue(rs.next());
-            assertEquals("a", rs.getString("t_id"));
-            assertEquals(1, rs.getInt("k1"));
-            assertEquals(2, rs.getInt("k2"));
-            assertEquals("y", rs.getString("V1"));
-            assertTrue(rs.next());
-            assertEquals("b", rs.getString("t_id"));
-            assertEquals(1, rs.getInt("k1"));
-            assertEquals(2, rs.getInt("k2"));
-            assertEquals("z", rs.getString("V1"));
-        } finally {
-            conn1.close();
-        }
-    }
-
-    @Test
     public void testLocalIndexScanJoinColumnsFromDataTable() throws Exception {
         String tableName = schemaName + "." + generateUniqueName();
         String indexName = "IDX_" + generateUniqueName();
@@ -670,31 +445,6 @@ public class LocalIndexIT extends ParallelStatsDisabledIT {
     }
     
     @Test
-    public void testScanWhenATableHasMultipleLocalIndexes() throws Exception {
-        String tableName = schemaName + "." + generateUniqueName();
-        String indexName = "IDX_" + generateUniqueName();
-
-        createBaseTable(tableName, null, "('e','i','o')");
-        Connection conn1 = DriverManager.getConnection(getUrl());
-        try {
-            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('b',1,2,4,'z')");
-            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('f',1,2,3,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('j',2,4,2,'a')");
-            conn1.createStatement().execute("UPSERT INTO " + tableName + " values('q',3,1,1,'c')");
-            conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + "2 ON " + tableName + "(k3)");
-            conn1.commit();
-            conn1 = DriverManager.getConnection(getUrl());
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT COUNT(*) FROM " + tableName);
-            assertTrue(rs.next());
-            assertEquals(4, rs.getInt(1));
-        } finally {
-            conn1.close();
-        }
-    }
-
-    @Test
     public void testLocalIndexesOnTableWithImmutableRows() throws Exception {
         String tableName = schemaName + "." + generateUniqueName();
         String indexName = "IDX_" + generateUniqueName();
@@ -791,49 +541,4 @@ public class LocalIndexIT extends ParallelStatsDisabledIT {
         }
     }
 
-    @Test
-    public void testLocalIndexScanWithSmallChunks() throws Exception {
-        String tableName = schemaName + "." + generateUniqueName();
-        String indexName = "IDX_" + generateUniqueName();
-
-        createBaseTable(tableName, 3, null);
-        Properties props = new Properties();
-        props.setProperty(QueryServices.SCAN_RESULT_CHUNK_SIZE, "2");
-        props.setProperty(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, Boolean.toString(isNamespaceMapped));
-        Connection conn1 = DriverManager.getConnection(getUrl(), props);
-        try{
-            String[] strings = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
-            for (int i = 0; i < 26; i++) {
-               conn1.createStatement().execute(
-                    "UPSERT INTO " + tableName + " values('"+strings[i]+"'," + i + ","
-                            + (i + 1) + "," + (i + 2) + ",'" + strings[25 - i] + "')");
-            }
-            conn1.commit();
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + " ON " + tableName + "(v1)");
-            conn1.createStatement().execute("CREATE LOCAL INDEX " + indexName + "_2 ON " + tableName + "(k3)");
-
-            ResultSet rs = conn1.createStatement().executeQuery("SELECT * FROM " + tableName);
-            assertTrue(rs.next());
-
-            String query = "SELECT t_id,k1,v1 FROM " + tableName;
-            rs = conn1.createStatement().executeQuery(query);
-            for (int j = 0; j < 26; j++) {
-                assertTrue(rs.next());
-                assertEquals(strings[25 - j], rs.getString("t_id"));
-                assertEquals(25 - j, rs.getInt("k1"));
-                assertEquals(strings[j], rs.getString("V1"));
-            }
-            query = "SELECT t_id,k1,k3 FROM " + tableName;
-            rs = conn1.createStatement().executeQuery(query);
-            Thread.sleep(1000);
-            for (int j = 0; j < 26; j++) {
-                assertTrue(rs.next());
-                assertEquals(strings[j], rs.getString("t_id"));
-                assertEquals(j, rs.getInt("k1"));
-                assertEquals(j + 2, rs.getInt("k3"));
-            }
-       } finally {
-            conn1.close();
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d5b3bced/phoenix-core/src/it/java/org/apache/phoenix/tx/FlappingTransactionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/tx/FlappingTransactionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/tx/FlappingTransactionIT.java
new file mode 100644
index 0000000..fd198f4
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/tx/FlappingTransactionIT.java
@@ -0,0 +1,328 @@
+/*
+ * 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.phoenix.tx;
+
+import static org.apache.phoenix.util.TestUtil.INDEX_DATA_SCHEMA;
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+import static org.apache.phoenix.util.TestUtil.createTransactionalTable;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.HTableInterface;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.end2end.ParallelStatsDisabledIT;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.TestUtil;
+import org.apache.tephra.TransactionContext;
+import org.apache.tephra.TransactionSystemClient;
+import org.apache.tephra.TxConstants;
+import org.apache.tephra.hbase.TransactionAwareHTable;
+import org.junit.Test;
+
+/**
+ * 
+ * Transaction related tests that flap when run in parallel.
+ * TODO: review with Tephra community
+ *
+ */
+public class FlappingTransactionIT extends ParallelStatsDisabledIT {
+    @Test
+    public void testDelete() throws Exception {
+        String transTableName = generateUniqueName();
+        String fullTableName = INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + transTableName;
+        String selectSQL = "SELECT * FROM " + fullTableName;
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection conn1 = DriverManager.getConnection(getUrl()); 
+                Connection conn2 = DriverManager.getConnection(getUrl())) {
+            TestUtil.createTransactionalTable(conn, fullTableName);
+            conn1.setAutoCommit(false);
+            ResultSet rs = conn1.createStatement().executeQuery(selectSQL);
+            assertFalse(rs.next());
+            
+            String upsert = "UPSERT INTO " + fullTableName + "(varchar_pk, char_pk, int_pk, long_pk, decimal_pk, date_pk) VALUES(?, ?, ?, ?, ?, ?)";
+            PreparedStatement stmt = conn1.prepareStatement(upsert);
+            // upsert two rows
+            TestUtil.setRowKeyColumns(stmt, 1);
+            stmt.execute();
+            conn1.commit();
+            
+            TestUtil.setRowKeyColumns(stmt, 2);
+            stmt.execute();
+            
+            // verify rows can be read even though commit has not been called
+            int rowsDeleted = conn1.createStatement().executeUpdate("DELETE FROM " + fullTableName);
+            assertEquals(2, rowsDeleted);
+            
+            // Delete and second upsert not committed yet, so there should be one row.
+            rs = conn2.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(1, rs.getInt(1));
+            
+            conn1.commit();
+            
+            // verify rows are deleted after commit
+            rs = conn1.createStatement().executeQuery(selectSQL);
+            assertFalse(rs.next());
+        }
+    }
+        
+    @Test
+    public void testInflightUpdateNotSeen() throws Exception {
+        String transTableName = generateUniqueName();
+        String fullTableName = INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + transTableName;
+        String selectSQL = "SELECT * FROM " + fullTableName;
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection conn1 = DriverManager.getConnection(getUrl()); 
+                Connection conn2 = DriverManager.getConnection(getUrl())) {
+            createTransactionalTable(conn, fullTableName);
+            conn1.setAutoCommit(false);
+            conn2.setAutoCommit(true);
+            ResultSet rs = conn1.createStatement().executeQuery(selectSQL);
+            assertFalse(rs.next());
+            
+            String upsert = "UPSERT INTO " + fullTableName + "(varchar_pk, char_pk, int_pk, long_pk, decimal_pk, date_pk) VALUES(?, ?, ?, ?, ?, ?)";
+            PreparedStatement stmt = conn1.prepareStatement(upsert);
+            // upsert two rows
+            TestUtil.setRowKeyColumns(stmt, 1);
+            stmt.execute();
+            conn1.commit();
+            
+            TestUtil.setRowKeyColumns(stmt, 2);
+            stmt.execute();
+            
+            rs = conn1.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName + " WHERE int_col1 IS NULL");
+            assertTrue(rs.next());
+            assertEquals(2, rs.getInt(1));
+            
+            upsert = "UPSERT INTO " + fullTableName + "(varchar_pk, char_pk, int_pk, long_pk, decimal_pk, date_pk, int_col1) VALUES(?, ?, ?, ?, ?, ?, 1)";
+            stmt = conn1.prepareStatement(upsert);
+            TestUtil.setRowKeyColumns(stmt, 1);
+            stmt.execute();
+            
+            rs = conn1.createStatement().executeQuery("SELECT int_col1 FROM " + fullTableName + " WHERE int_col1 = 1");
+            assertTrue(rs.next());
+            assertEquals(1, rs.getInt(1));
+            assertFalse(rs.next());
+            
+            rs = conn2.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName + " WHERE int_col1 = 1");
+            assertTrue(rs.next());
+            assertEquals(0, rs.getInt(1));
+            rs = conn2.createStatement().executeQuery("SELECT * FROM " + fullTableName + " WHERE int_col1 = 1");
+            assertFalse(rs.next());
+            
+            conn1.commit();
+            
+            rs = conn2.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName + " WHERE int_col1 = 1");
+            assertTrue(rs.next());
+            assertEquals(1, rs.getInt(1));
+            rs = conn2.createStatement().executeQuery("SELECT * FROM " + fullTableName + " WHERE int_col1 = 1");
+            assertTrue(rs.next());
+            assertFalse(rs.next());
+        }
+    }
+    
+    @Test
+    public void testInflightDeleteNotSeen() throws Exception {
+        String transTableName = generateUniqueName();
+        String fullTableName = INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + transTableName;
+        String selectSQL = "SELECT * FROM " + fullTableName;
+        try (Connection conn = DriverManager.getConnection(getUrl());
+                Connection conn1 = DriverManager.getConnection(getUrl()); 
+                Connection conn2 = DriverManager.getConnection(getUrl())) {
+            createTransactionalTable(conn, fullTableName);
+            conn1.setAutoCommit(false);
+            conn2.setAutoCommit(true);
+            ResultSet rs = conn1.createStatement().executeQuery(selectSQL);
+            assertFalse(rs.next());
+            
+            String upsert = "UPSERT INTO " + fullTableName + "(varchar_pk, char_pk, int_pk, long_pk, decimal_pk, date_pk) VALUES(?, ?, ?, ?, ?, ?)";
+            PreparedStatement stmt = conn1.prepareStatement(upsert);
+            // upsert two rows
+            TestUtil.setRowKeyColumns(stmt, 1);
+            stmt.execute();
+            TestUtil.setRowKeyColumns(stmt, 2);
+            stmt.execute();
+            
+            conn1.commit();
+            
+            rs = conn1.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(2, rs.getInt(1));
+            
+            String delete = "DELETE FROM " + fullTableName + " WHERE varchar_pk = 'varchar1'";
+            stmt = conn1.prepareStatement(delete);
+            int count = stmt.executeUpdate();
+            assertEquals(1,count);
+            
+            rs = conn1.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(1, rs.getInt(1));
+            assertFalse(rs.next());
+            
+            rs = conn2.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(2, rs.getInt(1));
+            assertFalse(rs.next());
+            
+            conn1.commit();
+            
+            rs = conn2.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(1, rs.getInt(1));
+            assertFalse(rs.next());
+        }
+    }
+
+    @Test
+    public void testExternalTxContext() throws Exception {
+        ResultSet rs;
+        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.setAutoCommit(false);
+        String fullTableName = generateUniqueName();
+        PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
+        
+        TransactionSystemClient txServiceClient = pconn.getQueryServices().getTransactionSystemClient();
+
+        Statement stmt = conn.createStatement();
+        stmt.execute("CREATE TABLE " + fullTableName + "(K VARCHAR PRIMARY KEY, V1 VARCHAR, V2 VARCHAR) TRANSACTIONAL=true");
+        HTableInterface htable = pconn.getQueryServices().getTable(Bytes.toBytes(fullTableName));
+        stmt.executeUpdate("upsert into " + fullTableName + " values('x', 'a', 'a')");
+        conn.commit();
+
+        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
+            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(1,rs.getInt(1));
+        }
+
+        // Use HBase level Tephra APIs to start a new transaction
+        TransactionAwareHTable txAware = new TransactionAwareHTable(htable, TxConstants.ConflictDetection.ROW);
+        TransactionContext txContext = new TransactionContext(txServiceClient, txAware);
+        txContext.start();
+        
+        // Use HBase APIs to add a new row
+        Put put = new Put(Bytes.toBytes("z"));
+        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
+        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, Bytes.toBytes("V1"), Bytes.toBytes("b"));
+        txAware.put(put);
+        
+        // Use Phoenix APIs to add new row (sharing the transaction context)
+        pconn.setTransactionContext(txContext);
+        conn.createStatement().executeUpdate("upsert into " + fullTableName + " values('y', 'c', 'c')");
+
+        // New connection should not see data as it hasn't been committed yet
+        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
+            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(1,rs.getInt(1));
+        }
+        
+        // Use new connection to create a row with a conflict
+        Connection connWithConflict = DriverManager.getConnection(getUrl(), props);
+        connWithConflict.createStatement().execute("upsert into " + fullTableName + " values('z', 'd', 'd')");
+        
+        // Existing connection should see data even though it hasn't been committed yet
+        rs = conn.createStatement().executeQuery("select count(*) from " + fullTableName);
+        assertTrue(rs.next());
+        assertEquals(3,rs.getInt(1));
+        
+        // Use Tephra APIs directly to finish (i.e. commit) the transaction
+        txContext.finish();
+        
+        // Confirm that attempt to commit row with conflict fails
+        try {
+            connWithConflict.commit();
+            fail();
+        } catch (SQLException e) {
+            assertEquals(SQLExceptionCode.TRANSACTION_CONFLICT_EXCEPTION.getErrorCode(), e.getErrorCode());
+        } finally {
+            connWithConflict.close();
+        }
+        
+        // New connection should now see data as it has been committed
+        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
+            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(3,rs.getInt(1));
+        }
+        
+        // Repeat the same as above, but this time abort the transaction
+        txContext = new TransactionContext(txServiceClient, txAware);
+        txContext.start();
+        
+        // Use HBase APIs to add a new row
+        put = new Put(Bytes.toBytes("j"));
+        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
+        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, Bytes.toBytes("V1"), Bytes.toBytes("e"));
+        txAware.put(put);
+        
+        // Use Phoenix APIs to add new row (sharing the transaction context)
+        pconn.setTransactionContext(txContext);
+        conn.createStatement().executeUpdate("upsert into " + fullTableName + " values('k', 'f', 'f')");
+        
+        // Existing connection should see data even though it hasn't been committed yet
+        rs = conn.createStatement().executeQuery("select count(*) from " + fullTableName);
+        assertTrue(rs.next());
+        assertEquals(5,rs.getInt(1));
+
+        connWithConflict.createStatement().execute("upsert into " + fullTableName + " values('k', 'g', 'g')");
+        rs = connWithConflict.createStatement().executeQuery("select count(*) from " + fullTableName);
+        assertTrue(rs.next());
+        assertEquals(4,rs.getInt(1));
+
+        // Use Tephra APIs directly to abort (i.e. rollback) the transaction
+        txContext.abort();
+        
+        rs = conn.createStatement().executeQuery("select count(*) from " + fullTableName);
+        assertTrue(rs.next());
+        assertEquals(3,rs.getInt(1));
+
+        // Should succeed since conflicting row was aborted
+        connWithConflict.commit();
+
+        // New connection should now see data as it has been committed
+        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
+            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
+            assertTrue(rs.next());
+            assertEquals(4,rs.getInt(1));
+        }
+        
+        // Even using HBase APIs directly, we shouldn't find 'j' since a delete marker would have been
+        // written to hide it.
+        Result result = htable.get(new Get(Bytes.toBytes("j")));
+        assertTrue(result.isEmpty());
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d5b3bced/phoenix-core/src/it/java/org/apache/phoenix/tx/NotThreadSafeTransactionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/tx/NotThreadSafeTransactionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/tx/NotThreadSafeTransactionIT.java
deleted file mode 100644
index 404bb9e..0000000
--- a/phoenix-core/src/it/java/org/apache/phoenix/tx/NotThreadSafeTransactionIT.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * 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.phoenix.tx;
-
-import static org.apache.phoenix.util.TestUtil.INDEX_DATA_SCHEMA;
-import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
-import static org.apache.phoenix.util.TestUtil.createTransactionalTable;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Properties;
-
-import javax.annotation.concurrent.NotThreadSafe;
-
-import org.apache.hadoop.hbase.client.Get;
-import org.apache.hadoop.hbase.client.HTableInterface;
-import org.apache.hadoop.hbase.client.Put;
-import org.apache.hadoop.hbase.client.Result;
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.phoenix.end2end.ParallelStatsDisabledIT;
-import org.apache.phoenix.exception.SQLExceptionCode;
-import org.apache.phoenix.jdbc.PhoenixConnection;
-import org.apache.phoenix.query.QueryConstants;
-import org.apache.phoenix.util.PropertiesUtil;
-import org.apache.phoenix.util.TestUtil;
-import org.apache.tephra.TransactionContext;
-import org.apache.tephra.TransactionSystemClient;
-import org.apache.tephra.TxConstants;
-import org.apache.tephra.hbase.TransactionAwareHTable;
-import org.junit.Test;
-
-/**
- * 
- * Transaction related tests that flap when run in parallel.
- * TODO: review with Tephra community
- *
- */
-@NotThreadSafe // Prevents test methods from running in parallel
-public class NotThreadSafeTransactionIT extends ParallelStatsDisabledIT {
-    @Test
-    public void testDelete() throws Exception {
-        String transTableName = generateUniqueName();
-        String fullTableName = INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + transTableName;
-        String selectSQL = "SELECT * FROM " + fullTableName;
-        try (Connection conn = DriverManager.getConnection(getUrl());
-                Connection conn1 = DriverManager.getConnection(getUrl()); 
-                Connection conn2 = DriverManager.getConnection(getUrl())) {
-            TestUtil.createTransactionalTable(conn, fullTableName);
-            conn1.setAutoCommit(false);
-            ResultSet rs = conn1.createStatement().executeQuery(selectSQL);
-            assertFalse(rs.next());
-            
-            String upsert = "UPSERT INTO " + fullTableName + "(varchar_pk, char_pk, int_pk, long_pk, decimal_pk, date_pk) VALUES(?, ?, ?, ?, ?, ?)";
-            PreparedStatement stmt = conn1.prepareStatement(upsert);
-            // upsert two rows
-            TestUtil.setRowKeyColumns(stmt, 1);
-            stmt.execute();
-            conn1.commit();
-            
-            TestUtil.setRowKeyColumns(stmt, 2);
-            stmt.execute();
-            
-            // verify rows can be read even though commit has not been called
-            int rowsDeleted = conn1.createStatement().executeUpdate("DELETE FROM " + fullTableName);
-            assertEquals(2, rowsDeleted);
-            
-            // Delete and second upsert not committed yet, so there should be one row.
-            rs = conn2.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(1, rs.getInt(1));
-            
-            conn1.commit();
-            
-            // verify rows are deleted after commit
-            rs = conn1.createStatement().executeQuery(selectSQL);
-            assertFalse(rs.next());
-        }
-    }
-        
-    @Test
-    public void testInflightUpdateNotSeen() throws Exception {
-        String transTableName = generateUniqueName();
-        String fullTableName = INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + transTableName;
-        String selectSQL = "SELECT * FROM " + fullTableName;
-        try (Connection conn = DriverManager.getConnection(getUrl());
-                Connection conn1 = DriverManager.getConnection(getUrl()); 
-                Connection conn2 = DriverManager.getConnection(getUrl())) {
-            createTransactionalTable(conn, fullTableName);
-            conn1.setAutoCommit(false);
-            conn2.setAutoCommit(true);
-            ResultSet rs = conn1.createStatement().executeQuery(selectSQL);
-            assertFalse(rs.next());
-            
-            String upsert = "UPSERT INTO " + fullTableName + "(varchar_pk, char_pk, int_pk, long_pk, decimal_pk, date_pk) VALUES(?, ?, ?, ?, ?, ?)";
-            PreparedStatement stmt = conn1.prepareStatement(upsert);
-            // upsert two rows
-            TestUtil.setRowKeyColumns(stmt, 1);
-            stmt.execute();
-            conn1.commit();
-            
-            TestUtil.setRowKeyColumns(stmt, 2);
-            stmt.execute();
-            
-            rs = conn1.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName + " WHERE int_col1 IS NULL");
-            assertTrue(rs.next());
-            assertEquals(2, rs.getInt(1));
-            
-            upsert = "UPSERT INTO " + fullTableName + "(varchar_pk, char_pk, int_pk, long_pk, decimal_pk, date_pk, int_col1) VALUES(?, ?, ?, ?, ?, ?, 1)";
-            stmt = conn1.prepareStatement(upsert);
-            TestUtil.setRowKeyColumns(stmt, 1);
-            stmt.execute();
-            
-            rs = conn1.createStatement().executeQuery("SELECT int_col1 FROM " + fullTableName + " WHERE int_col1 = 1");
-            assertTrue(rs.next());
-            assertEquals(1, rs.getInt(1));
-            assertFalse(rs.next());
-            
-            rs = conn2.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName + " WHERE int_col1 = 1");
-            assertTrue(rs.next());
-            assertEquals(0, rs.getInt(1));
-            rs = conn2.createStatement().executeQuery("SELECT * FROM " + fullTableName + " WHERE int_col1 = 1");
-            assertFalse(rs.next());
-            
-            conn1.commit();
-            
-            rs = conn2.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName + " WHERE int_col1 = 1");
-            assertTrue(rs.next());
-            assertEquals(1, rs.getInt(1));
-            rs = conn2.createStatement().executeQuery("SELECT * FROM " + fullTableName + " WHERE int_col1 = 1");
-            assertTrue(rs.next());
-            assertFalse(rs.next());
-        }
-    }
-    
-    @Test
-    public void testInflightDeleteNotSeen() throws Exception {
-        String transTableName = generateUniqueName();
-        String fullTableName = INDEX_DATA_SCHEMA + QueryConstants.NAME_SEPARATOR + transTableName;
-        String selectSQL = "SELECT * FROM " + fullTableName;
-        try (Connection conn = DriverManager.getConnection(getUrl());
-                Connection conn1 = DriverManager.getConnection(getUrl()); 
-                Connection conn2 = DriverManager.getConnection(getUrl())) {
-            createTransactionalTable(conn, fullTableName);
-            conn1.setAutoCommit(false);
-            conn2.setAutoCommit(true);
-            ResultSet rs = conn1.createStatement().executeQuery(selectSQL);
-            assertFalse(rs.next());
-            
-            String upsert = "UPSERT INTO " + fullTableName + "(varchar_pk, char_pk, int_pk, long_pk, decimal_pk, date_pk) VALUES(?, ?, ?, ?, ?, ?)";
-            PreparedStatement stmt = conn1.prepareStatement(upsert);
-            // upsert two rows
-            TestUtil.setRowKeyColumns(stmt, 1);
-            stmt.execute();
-            TestUtil.setRowKeyColumns(stmt, 2);
-            stmt.execute();
-            
-            conn1.commit();
-            
-            rs = conn1.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(2, rs.getInt(1));
-            
-            String delete = "DELETE FROM " + fullTableName + " WHERE varchar_pk = 'varchar1'";
-            stmt = conn1.prepareStatement(delete);
-            int count = stmt.executeUpdate();
-            assertEquals(1,count);
-            
-            rs = conn1.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(1, rs.getInt(1));
-            assertFalse(rs.next());
-            
-            rs = conn2.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(2, rs.getInt(1));
-            assertFalse(rs.next());
-            
-            conn1.commit();
-            
-            rs = conn2.createStatement().executeQuery("SELECT count(*) FROM " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(1, rs.getInt(1));
-            assertFalse(rs.next());
-        }
-    }
-
-    @Test
-    public void testExternalTxContext() throws Exception {
-        ResultSet rs;
-        Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
-        Connection conn = DriverManager.getConnection(getUrl(), props);
-        conn.setAutoCommit(false);
-        String fullTableName = generateUniqueName();
-        PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class);
-        
-        TransactionSystemClient txServiceClient = pconn.getQueryServices().getTransactionSystemClient();
-
-        Statement stmt = conn.createStatement();
-        stmt.execute("CREATE TABLE " + fullTableName + "(K VARCHAR PRIMARY KEY, V1 VARCHAR, V2 VARCHAR) TRANSACTIONAL=true");
-        HTableInterface htable = pconn.getQueryServices().getTable(Bytes.toBytes(fullTableName));
-        stmt.executeUpdate("upsert into " + fullTableName + " values('x', 'a', 'a')");
-        conn.commit();
-
-        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
-            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(1,rs.getInt(1));
-        }
-
-        // Use HBase level Tephra APIs to start a new transaction
-        TransactionAwareHTable txAware = new TransactionAwareHTable(htable, TxConstants.ConflictDetection.ROW);
-        TransactionContext txContext = new TransactionContext(txServiceClient, txAware);
-        txContext.start();
-        
-        // Use HBase APIs to add a new row
-        Put put = new Put(Bytes.toBytes("z"));
-        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
-        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, Bytes.toBytes("V1"), Bytes.toBytes("b"));
-        txAware.put(put);
-        
-        // Use Phoenix APIs to add new row (sharing the transaction context)
-        pconn.setTransactionContext(txContext);
-        conn.createStatement().executeUpdate("upsert into " + fullTableName + " values('y', 'c', 'c')");
-
-        // New connection should not see data as it hasn't been committed yet
-        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
-            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(1,rs.getInt(1));
-        }
-        
-        // Use new connection to create a row with a conflict
-        Connection connWithConflict = DriverManager.getConnection(getUrl(), props);
-        connWithConflict.createStatement().execute("upsert into " + fullTableName + " values('z', 'd', 'd')");
-        
-        // Existing connection should see data even though it hasn't been committed yet
-        rs = conn.createStatement().executeQuery("select count(*) from " + fullTableName);
-        assertTrue(rs.next());
-        assertEquals(3,rs.getInt(1));
-        
-        // Use Tephra APIs directly to finish (i.e. commit) the transaction
-        txContext.finish();
-        
-        // Confirm that attempt to commit row with conflict fails
-        try {
-            connWithConflict.commit();
-            fail();
-        } catch (SQLException e) {
-            assertEquals(SQLExceptionCode.TRANSACTION_CONFLICT_EXCEPTION.getErrorCode(), e.getErrorCode());
-        } finally {
-            connWithConflict.close();
-        }
-        
-        // New connection should now see data as it has been committed
-        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
-            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(3,rs.getInt(1));
-        }
-        
-        // Repeat the same as above, but this time abort the transaction
-        txContext = new TransactionContext(txServiceClient, txAware);
-        txContext.start();
-        
-        // Use HBase APIs to add a new row
-        put = new Put(Bytes.toBytes("j"));
-        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, QueryConstants.EMPTY_COLUMN_BYTES, QueryConstants.EMPTY_COLUMN_VALUE_BYTES);
-        put.add(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, Bytes.toBytes("V1"), Bytes.toBytes("e"));
-        txAware.put(put);
-        
-        // Use Phoenix APIs to add new row (sharing the transaction context)
-        pconn.setTransactionContext(txContext);
-        conn.createStatement().executeUpdate("upsert into " + fullTableName + " values('k', 'f', 'f')");
-        
-        // Existing connection should see data even though it hasn't been committed yet
-        rs = conn.createStatement().executeQuery("select count(*) from " + fullTableName);
-        assertTrue(rs.next());
-        assertEquals(5,rs.getInt(1));
-
-        connWithConflict.createStatement().execute("upsert into " + fullTableName + " values('k', 'g', 'g')");
-        rs = connWithConflict.createStatement().executeQuery("select count(*) from " + fullTableName);
-        assertTrue(rs.next());
-        assertEquals(4,rs.getInt(1));
-
-        // Use Tephra APIs directly to abort (i.e. rollback) the transaction
-        txContext.abort();
-        
-        rs = conn.createStatement().executeQuery("select count(*) from " + fullTableName);
-        assertTrue(rs.next());
-        assertEquals(3,rs.getInt(1));
-
-        // Should succeed since conflicting row was aborted
-        connWithConflict.commit();
-
-        // New connection should now see data as it has been committed
-        try (Connection newConn = DriverManager.getConnection(getUrl(), props)) {
-            rs = newConn.createStatement().executeQuery("select count(*) from " + fullTableName);
-            assertTrue(rs.next());
-            assertEquals(4,rs.getInt(1));
-        }
-        
-        // Even using HBase APIs directly, we shouldn't find 'j' since a delete marker would have been
-        // written to hide it.
-        Result result = htable.get(new Get(Bytes.toBytes("j")));
-        assertTrue(result.isEmpty());
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/d5b3bced/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 2fe55ec..bc6159f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -234,7 +234,7 @@
                 <runOrder>alphabetical</runOrder>
                 <reuseForks>true</reuseForks>
                 <runOrder>alphabetical</runOrder>
-                <!--parallel>classesAndMethods</parallel>
+                <!--parallel>methods</parallel>
                 <threadCount>20</threadCount>
 		<enableAssertions>false</enableAssertions-->
                 <argLine>-Xmx2000m -XX:MaxPermSize=256m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}" -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled -XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68</argLine>
@@ -262,7 +262,7 @@
                 <runOrder>alphabetical</runOrder>
                 <reuseForks>true</reuseForks>
                 <runOrder>alphabetical</runOrder>
-                <!--parallel>classesAndMethods</parallel>
+                <!--parallel>methods</parallel>
                 <threadCount>20</threadCount>
 		<enableAssertions>false</enableAssertions-->
                 <argLine>-Xmx2000m -XX:MaxPermSize=256m -Djava.security.egd=file:/dev/./urandom "-Djava.library.path=${hadoop.library.path}${path.separator}${java.library.path}" -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled -XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68</argLine>