You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by gr...@apache.org on 2018/10/02 19:01:54 UTC

[3/6] kudu git commit: [test] Move BaseKuduTest to a Junit Rule

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestAuthnTokenReacquireOpen.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestAuthnTokenReacquireOpen.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestAuthnTokenReacquireOpen.java
index 16dc1aa..f019e43 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestAuthnTokenReacquireOpen.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestAuthnTokenReacquireOpen.java
@@ -24,6 +24,12 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import org.apache.kudu.Schema;
+import org.apache.kudu.client.MiniKuduCluster.MiniKuduClusterBuilder;
+import org.apache.kudu.test.KuduTestHarness;
+import org.apache.kudu.util.ClientTestUtil;
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 
 /**
@@ -33,31 +39,42 @@ import org.junit.Test;
  * so this test verifies that the client opens a new connection using its primary credentials to
  * acquire a new authentication token and automatically retries its RPCs with the new authn token.
  */
-public class TestAuthnTokenReacquireOpen extends BaseKuduTest {
+public class TestAuthnTokenReacquireOpen {
 
   private static final String TABLE_NAME = "TestAuthnTokenReacquireOpen-table";
   private static final int TOKEN_TTL_SEC = 1;
   private static final int OP_TIMEOUT_MS = 60 * TOKEN_TTL_SEC * 1000;
   private static final int KEEPALIVE_TIME_MS = 2 * OP_TIMEOUT_MS;
 
-  @Override
-  protected MiniKuduCluster.MiniKuduClusterBuilder getMiniClusterBuilder() {
-    return super.getMiniClusterBuilder()
-        // We want to have a cluster with a single master.
-        .numMasters(1)
-        // Set appropriate TTL for authn token and connection keep-alive property, so the client could
-        // keep an open connection to the master when its authn token is already expired. Inject
-        // additional INVALID_AUTHENTICATION_TOKEN responses from the tablet server even for
-        // not-yet-expired tokens for an extra stress on the client.
-        .enableKerberos()
-        .addMasterFlag(String.format("--authn_token_validity_seconds=%d", TOKEN_TTL_SEC))
-        .addMasterFlag(String.format("--rpc_default_keepalive_time_ms=%d", KEEPALIVE_TIME_MS))
-        .addTserverFlag(String.format("--rpc_default_keepalive_time_ms=%d", KEEPALIVE_TIME_MS))
-        .addTserverFlag("--rpc_inject_invalid_authn_token_ratio=0.5");
+  private static final Schema basicSchema = ClientTestUtil.getBasicSchema();
+
+  private static final MiniKuduClusterBuilder clusterBuilder = KuduTestHarness.getBaseClusterBuilder()
+      // We want to have a cluster with a single master.
+      .numMasterServers(1)
+      // Set appropriate TTL for authn token and connection keep-alive property, so the client could
+      // keep an open connection to the master when its authn token is already expired. Inject
+      // additional INVALID_AUTHENTICATION_TOKEN responses from the tablet server even for
+      // not-yet-expired tokens for an extra stress on the client.
+      .enableKerberos()
+      .addMasterServerFlag(String.format("--authn_token_validity_seconds=%d", TOKEN_TTL_SEC))
+      .addMasterServerFlag(String.format("--rpc_default_keepalive_time_ms=%d", KEEPALIVE_TIME_MS))
+      .addTabletServerFlag(String.format("--rpc_default_keepalive_time_ms=%d", KEEPALIVE_TIME_MS))
+      .addTabletServerFlag("--rpc_inject_invalid_authn_token_ratio=0.5");
+
+  private KuduClient client;
+  private AsyncKuduClient asyncClient;
+
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness(clusterBuilder);
+
+  @Before
+  public void setUp() {
+    client = harness.getClient();
+    asyncClient = harness.getAsyncClient();
   }
 
   private void dropConnections() {
-    for (Connection c : client.getConnectionListCopy()) {
+    for (Connection c : asyncClient.getConnectionListCopy()) {
       c.disconnect();
     }
   }
@@ -71,31 +88,31 @@ public class TestAuthnTokenReacquireOpen extends BaseKuduTest {
   public void test() throws Exception {
     // Establish a connection to the cluster, get the list of tablet servers. That would fetch
     // an authn token.
-    ListTabletServersResponse response = syncClient.listTabletServers();
+    ListTabletServersResponse response = client.listTabletServers();
     assertNotNull(response);
     dropConnections();
 
     // The connection to the master has been dropped. Make a call to the master again so the client
     // would create a new connection using authn token.
-    ListTablesResponse tableList = syncClient.getTablesList(null);
+    ListTablesResponse tableList = client.getTablesList(null);
     assertNotNull(tableList);
     assertTrue(tableList.getTablesList().isEmpty());
 
-    syncClient.createTable(TABLE_NAME, basicSchema, getBasicCreateTableOptions());
-    assertTrue(syncClient.tableExists(TABLE_NAME));
+    client.createTable(TABLE_NAME, basicSchema, getBasicCreateTableOptions());
+    assertTrue(client.tableExists(TABLE_NAME));
 
     expireToken();
 
     // Try scan table rows once the authn token has expired. This request goes to corresponding
     // tablet server, and a new connection should be negotiated. During connection negotiation,
     // the server authenticates the client using authn token, which is expired.
-    KuduTable scanTable = syncClient.openTable(TABLE_NAME);
-    AsyncKuduScanner scanner = new AsyncKuduScanner.AsyncKuduScannerBuilder(client, scanTable)
+    KuduTable scanTable = client.openTable(TABLE_NAME);
+    AsyncKuduScanner scanner = new AsyncKuduScanner.AsyncKuduScannerBuilder(asyncClient, scanTable)
         .scanRequestTimeout(OP_TIMEOUT_MS)
         .build();
     assertEquals(0, countRowsInScan(scanner));
 
-    syncClient.deleteTable(TABLE_NAME);
-    assertFalse(syncClient.tableExists(TABLE_NAME));
+    client.deleteTable(TABLE_NAME);
+    assertFalse(client.tableExists(TABLE_NAME));
   }
 }

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestClientFailoverSupport.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestClientFailoverSupport.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestClientFailoverSupport.java
index 1da9fc3..c30ef72 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestClientFailoverSupport.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestClientFailoverSupport.java
@@ -16,6 +16,7 @@
 // under the License.
 package org.apache.kudu.client;
 
+import static org.apache.kudu.test.KuduTestHarness.DEFAULT_SLEEP;
 import static org.apache.kudu.util.AssertHelpers.assertEventuallyTrue;
 import static org.apache.kudu.util.ClientTestUtil.countRowsInScan;
 import static org.apache.kudu.util.ClientTestUtil.createBasicSchemaInsert;
@@ -26,13 +27,21 @@ import static org.junit.Assert.assertFalse;
 import java.io.Closeable;
 import java.io.IOException;
 import java.util.List;
+
+import org.apache.kudu.Schema;
+import org.apache.kudu.test.KuduTestHarness;
 import org.apache.kudu.util.AssertHelpers.BooleanExpression;
 import org.apache.kudu.util.CapturingLogAppender;
+import org.apache.kudu.util.ClientTestUtil;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 
-public class TestClientFailoverSupport extends BaseKuduTest {
+public class TestClientFailoverSupport {
+
+  private static final Schema basicSchema = ClientTestUtil.getBasicSchema();
+
   private CapturingLogAppender cla = new CapturingLogAppender();
   private Closeable claAttach;
 
@@ -41,8 +50,16 @@ public class TestClientFailoverSupport extends BaseKuduTest {
     KILL
   }
 
+  private KuduClient client;
+  private AsyncKuduClient asyncClient;
+
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
   @Before
-  public void attachToLog() {
+  public void setUp() {
+    client = harness.getClient();
+    asyncClient = harness.getAsyncClient();
     claAttach = cla.attach();
   }
 
@@ -60,7 +77,7 @@ public class TestClientFailoverSupport extends BaseKuduTest {
         new BooleanExpression() {
           @Override
           public boolean get() throws Exception {
-            AsyncKuduScanner scanner = client.newScannerBuilder(table).build();
+            AsyncKuduScanner scanner = asyncClient.newScannerBuilder(table).build();
             int read_count = countRowsInScan(scanner);
             return read_count == rowCount;
           }
@@ -90,10 +107,10 @@ public class TestClientFailoverSupport extends BaseKuduTest {
   private void doTestMasterFailover(MasterFailureType failureType) throws Exception {
     final String TABLE_NAME = TestClientFailoverSupport.class.getName()
         + "-" + failureType;
-    createTable(TABLE_NAME, basicSchema, getBasicCreateTableOptions());
+    client.createTable(TABLE_NAME, basicSchema, getBasicCreateTableOptions());
 
-    KuduTable table = openTable(TABLE_NAME);
-    KuduSession session = syncClient.newSession();
+    KuduTable table = client.openTable(TABLE_NAME);
+    KuduSession session = client.newSession();
 
     final int TOTAL_ROWS_TO_INSERT = 10;
 
@@ -106,10 +123,10 @@ public class TestClientFailoverSupport extends BaseKuduTest {
     // Kill or restart the leader master.
     switch (failureType) {
     case KILL:
-      killLeaderMasterServer();
+      harness.killLeaderMasterServer();
       break;
     case RESTART:
-      restartLeaderMaster();
+      harness.restartLeaderMaster();
       break;
     }
 
@@ -119,14 +136,14 @@ public class TestClientFailoverSupport extends BaseKuduTest {
     // to the new one.
     List<LocatedTablet> tablets = table.getTabletsLocations(DEFAULT_SLEEP);
     assertEquals(1, tablets.size());
-    killTabletLeader(tablets.get(0));
+    harness.killTabletLeader(tablets.get(0));
 
     // Insert some more rows.
     for (int i = TOTAL_ROWS_TO_INSERT; i < 2*TOTAL_ROWS_TO_INSERT; i++) {
       session.apply(createBasicSchemaInsert(table, i));
     }
     waitUntilRowCount(table, 2*TOTAL_ROWS_TO_INSERT, DEFAULT_SLEEP);
-    syncClient.deleteTable(TABLE_NAME);
-    assertFalse(syncClient.tableExists(TABLE_NAME));
+    client.deleteTable(TABLE_NAME);
+    assertFalse(client.tableExists(TABLE_NAME));
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestConnectToCluster.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestConnectToCluster.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestConnectToCluster.java
index a3379e5..57ac3cd 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestConnectToCluster.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestConnectToCluster.java
@@ -47,9 +47,9 @@ public class TestConnectToCluster {
   @Test(timeout=60000)
   public void testFallbackConnectRpc() throws Exception {
     MiniKuduCluster cluster = new MiniKuduCluster.MiniKuduClusterBuilder()
-        .addMasterFlag("--master_support_connect_to_master_rpc=0")
-        .numMasters(1)
-        .numTservers(0)
+        .addMasterServerFlag("--master_support_connect_to_master_rpc=0")
+        .numMasterServers(1)
+        .numTabletServers(0)
         .build();
     KuduClient c = null;
     try {
@@ -75,8 +75,8 @@ public class TestConnectToCluster {
   @Test(timeout=60000)
   public void testConnectToOneOfManyMasters() throws Exception {
     MiniKuduCluster cluster = new MiniKuduCluster.MiniKuduClusterBuilder()
-        .numMasters(3)
-        .numTservers(0)
+        .numMasterServers(3)
+        .numTabletServers(0)
         .build();
     int successes = 0;
     try {

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestConnectionCache.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestConnectionCache.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestConnectionCache.java
index 11eb4bc..72ff6a3 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestConnectionCache.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestConnectionCache.java
@@ -23,17 +23,22 @@ import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertTrue;
 
 import com.stumbleupon.async.Deferred;
+import org.apache.kudu.junit.RetryRule;
+import org.junit.Rule;
 import org.junit.Test;
 
 import org.apache.kudu.util.NetUtil;
 
 public class TestConnectionCache {
 
+  @Rule
+  public RetryRule retryRule = new RetryRule();
+
   @Test(timeout = 50000)
   public void test() throws Exception {
     MiniKuduCluster cluster = null;
     try {
-      cluster = new MiniKuduCluster.MiniKuduClusterBuilder().numMasters(3).build();
+      cluster = new MiniKuduCluster.MiniKuduClusterBuilder().numMasterServers(3).build();
 
       final AsyncKuduClient client =
           new AsyncKuduClient.AsyncKuduClientBuilder(cluster.getMasterAddressesAsString()).build();

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestFlexiblePartitioning.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestFlexiblePartitioning.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestFlexiblePartitioning.java
index b3ab7ff..5931d01 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestFlexiblePartitioning.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestFlexiblePartitioning.java
@@ -16,6 +16,7 @@
 // under the License.
 package org.apache.kudu.client;
 
+import static org.apache.kudu.test.KuduTestHarness.DEFAULT_SLEEP;
 import static org.junit.Assert.assertEquals;
 
 import java.util.ArrayList;
@@ -30,7 +31,9 @@ import com.google.common.base.Predicates;
 import com.google.common.collect.ComparisonChain;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Sets;
+import org.apache.kudu.test.KuduTestHarness;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -39,12 +42,18 @@ import org.apache.kudu.ColumnSchema;
 import org.apache.kudu.Schema;
 import org.apache.kudu.Type;
 
-public class TestFlexiblePartitioning extends BaseKuduTest {
+public class TestFlexiblePartitioning {
   private static final Logger LOG = LoggerFactory.getLogger(TestKuduClient.class);
   private String tableName;
 
+  private KuduClient client;
+
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
   @Before
-  public void setTableName() {
+  public void setUp() {
+    client = harness.getClient();
     tableName = TestFlexiblePartitioning.class.getName() + "-" + System.currentTimeMillis();
   }
 
@@ -71,7 +80,7 @@ public class TestFlexiblePartitioning extends BaseKuduTest {
   }
 
   private void insertRows(KuduTable table, Set<Row> rows) throws KuduException {
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     try {
       for (Row row : rows) {
         Insert insert = table.newInsert();
@@ -104,10 +113,10 @@ public class TestFlexiblePartitioning extends BaseKuduTest {
     Set<Row> rows = new HashSet<>();
     for (KuduScanToken token : scanTokens.build()) {
       LOG.debug("Scanning token: {}", KuduScanToken.stringifySerializedToken(token.serialize(),
-                                                                             syncClient));
+          client));
 
       int existingCount = rows.size();
-      Set<Row> newRows = collectRows(token.intoScanner(syncClient));
+      Set<Row> newRows = collectRows(token.intoScanner(client));
       rows.addAll(newRows);
       assertEquals(existingCount + newRows.size(), rows.size());
     }
@@ -117,15 +126,15 @@ public class TestFlexiblePartitioning extends BaseKuduTest {
   private void testPartitionSchema(CreateTableOptions tableBuilder) throws Exception {
     Schema schema = createSchema();
 
-    syncClient.createTable(tableName, schema, tableBuilder);
+    client.createTable(tableName, schema, tableBuilder);
 
-    KuduTable table = syncClient.openTable(tableName);
+    KuduTable table = client.openTable(tableName);
 
     Set<Row> rows = rows();
     insertRows(table, rows);
 
     // Full table scan
-    assertEquals(rows, collectRows(syncClient.newScannerBuilder(table).build()));
+    assertEquals(rows, collectRows(client.newScannerBuilder(table).build()));
 
     { // Lower bound
       Row minRow = new Row("1", "3", "5");
@@ -134,12 +143,12 @@ public class TestFlexiblePartitioning extends BaseKuduTest {
 
       Set<Row> expected = Sets.filter(rows, minRow.gtePred());
 
-      KuduScanner scanner = syncClient.newScannerBuilder(table).lowerBound(lowerBound).build();
+      KuduScanner scanner = client.newScannerBuilder(table).lowerBound(lowerBound).build();
       Set<Row> results = collectRows(scanner);
       assertEquals(expected, results);
 
       KuduScanToken.KuduScanTokenBuilder scanTokens =
-          syncClient.newScanTokenBuilder(table).lowerBound(lowerBound);
+          client.newScanTokenBuilder(table).lowerBound(lowerBound);
       Set<Row> tokenResults = collectRows(scanTokens);
       assertEquals(expected, tokenResults);
     }
@@ -151,14 +160,14 @@ public class TestFlexiblePartitioning extends BaseKuduTest {
 
       Set<Row> expected = Sets.filter(rows, maxRow.ltPred());
 
-      KuduScanner scanner = syncClient.newScannerBuilder(table)
+      KuduScanner scanner = client.newScannerBuilder(table)
                                       .exclusiveUpperBound(upperBound)
                                       .build();
       Set<Row> results = collectRows(scanner);
       assertEquals(expected, results);
 
       KuduScanToken.KuduScanTokenBuilder scanTokens =
-          syncClient.newScanTokenBuilder(table).exclusiveUpperBound(upperBound);
+          client.newScanTokenBuilder(table).exclusiveUpperBound(upperBound);
       Set<Row> tokenResults = collectRows(scanTokens);
       assertEquals(expected, tokenResults);
     }
@@ -173,7 +182,7 @@ public class TestFlexiblePartitioning extends BaseKuduTest {
 
       Set<Row> expected = Sets.filter(rows, Predicates.and(minRow.gtePred(), maxRow.ltPred()));
 
-      KuduScanner scanner = syncClient.newScannerBuilder(table)
+      KuduScanner scanner = client.newScannerBuilder(table)
                                       .lowerBound(lowerBound)
                                       .exclusiveUpperBound(upperBound)
                                       .build();
@@ -181,20 +190,20 @@ public class TestFlexiblePartitioning extends BaseKuduTest {
       assertEquals(expected, results);
 
       KuduScanToken.KuduScanTokenBuilder scanTokens =
-          syncClient.newScanTokenBuilder(table)
+          client.newScanTokenBuilder(table)
                     .lowerBound(lowerBound)
                     .exclusiveUpperBound(upperBound);
       Set<Row> tokenResults = collectRows(scanTokens);
       assertEquals(expected, tokenResults);
     }
 
-    List<LocatedTablet> tablets = table.getTabletsLocations(TestTimeouts.DEFAULT_SLEEP);
+    List<LocatedTablet> tablets = table.getTabletsLocations(DEFAULT_SLEEP);
 
     { // Per-tablet scan
       Set<Row> results = new HashSet<>();
 
       for (LocatedTablet tablet : tablets) {
-        KuduScanner scanner = syncClient.newScannerBuilder(table)
+        KuduScanner scanner = client.newScannerBuilder(table)
                                         .lowerBoundPartitionKeyRaw(tablet.getPartition().getPartitionKeyStart())
                                         .exclusiveUpperBoundPartitionKeyRaw(tablet.getPartition().getPartitionKeyEnd())
                                         .build();
@@ -219,7 +228,7 @@ public class TestFlexiblePartitioning extends BaseKuduTest {
       Set<Row> results = new HashSet<>();
 
       for (LocatedTablet tablet : tablets) {
-        KuduScanner scanner = syncClient.newScannerBuilder(table)
+        KuduScanner scanner = client.newScannerBuilder(table)
                                         .lowerBound(lowerBound)
                                         .exclusiveUpperBound(upperBound)
                                         .lowerBoundPartitionKeyRaw(tablet.getPartition().getPartitionKeyStart())

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestHandleTooBusy.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestHandleTooBusy.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestHandleTooBusy.java
index 7b1b3a9..e506809 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestHandleTooBusy.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestHandleTooBusy.java
@@ -23,6 +23,11 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 
 import com.google.common.collect.Lists;
+import org.apache.kudu.Schema;
+import org.apache.kudu.client.MiniKuduCluster.MiniKuduClusterBuilder;
+import org.apache.kudu.test.KuduTestHarness;
+import org.apache.kudu.util.ClientTestUtil;
+import org.junit.Rule;
 import org.junit.Test;
 
 import static org.apache.kudu.util.ClientTestUtil.getBasicCreateTableOptions;
@@ -31,19 +36,21 @@ import static org.apache.kudu.util.ClientTestUtil.getBasicCreateTableOptions;
  * Tests which provoke RPC queue overflow errors on the server side
  * to ensure that we properly handle them in the client.
  */
-public class TestHandleTooBusy extends BaseKuduTest {
+public class TestHandleTooBusy {
   private static final String TABLE_NAME = "TestHandleTooBusy";
 
-  @Override
-  protected MiniKuduCluster.MiniKuduClusterBuilder getMiniClusterBuilder() {
-    return super.getMiniClusterBuilder()
-        // Short queue to provoke overflow.
-        .addMasterFlag("--rpc_service_queue_length=1")
-        // Low number of service threads, so things stay in the queue.
-        .addMasterFlag("--rpc_num_service_threads=3")
-        // inject latency so lookups process slowly.
-        .addMasterFlag("--master_inject_latency_on_tablet_lookups_ms=100");
-  }
+  private static final Schema basicSchema = ClientTestUtil.getBasicSchema();
+
+  private static final MiniKuduClusterBuilder clusterBuilder = KuduTestHarness.getBaseClusterBuilder()
+      // Short queue to provoke overflow.
+      .addMasterServerFlag("--rpc_service_queue_length=1")
+      // Low number of service threads, so things stay in the queue.
+      .addMasterServerFlag("--rpc_num_service_threads=3")
+      // inject latency so lookups process slowly.
+      .addMasterServerFlag("--master_inject_latency_on_tablet_lookups_ms=100");
+
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness(clusterBuilder);
 
   /**
    * Provoke overflows in the master RPC queue while connecting to the master
@@ -51,7 +58,7 @@ public class TestHandleTooBusy extends BaseKuduTest {
    */
   @Test(timeout=60000)
   public void testMasterLookupOverflow() throws Exception {
-    createTable(TABLE_NAME, basicSchema, getBasicCreateTableOptions());
+    harness.getClient().createTable(TABLE_NAME, basicSchema, getBasicCreateTableOptions());
     ExecutorService exec = Executors.newCachedThreadPool();
     List<Future<Void>> futures = Lists.newArrayList();
     for (int thr = 0; thr < 10; thr++) {
@@ -59,7 +66,7 @@ public class TestHandleTooBusy extends BaseKuduTest {
         @Override
         public Void call() throws Exception {
           for (int i = 0; i < 5; i++) {
-            try (KuduClient c = new KuduClient.KuduClientBuilder(getMasterAddressesAsString())
+            try (KuduClient c = new KuduClient.KuduClientBuilder(harness.getMasterAddressesAsString())
                 .build()) {
               KuduTable table = c.openTable(TABLE_NAME);
               for (int j = 0; j < 5; j++) {

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestHybridTime.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestHybridTime.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestHybridTime.java
index 8662c55..14fb1c4 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestHybridTime.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestHybridTime.java
@@ -31,7 +31,10 @@ import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 import com.google.common.collect.ImmutableList;
+import org.apache.kudu.client.MiniKuduCluster.MiniKuduClusterBuilder;
+import org.apache.kudu.test.KuduTestHarness;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -43,33 +46,35 @@ import org.apache.kudu.Schema;
  * This only tests client propagation since it's the only thing that is client-specific.
  * All the work for commit wait is done and tested on the server-side.
  */
-public class TestHybridTime extends BaseKuduTest {
+public class TestHybridTime {
   private static final Logger LOG = LoggerFactory.getLogger(TestHybridTime.class);
 
   // Generate a unique table name
-  protected static final String TABLE_NAME =
+  private static final String TABLE_NAME =
     TestHybridTime.class.getName() + "-" + System.currentTimeMillis();
 
-  protected static final Schema schema = getSchema();
-  protected static KuduTable table;
-
-  @Override
-  protected MiniKuduCluster.MiniKuduClusterBuilder getMiniClusterBuilder() {
-    return super.getMiniClusterBuilder()
-        // Before starting the cluster, disable automatic safe time advancement in the
-        // absence of writes. This test does snapshot reads in the present and expects
-        // certain timestamps to be assigned to the scans. If safe time was allowed
-        // to move automatically the scans might not be assigned the expected timestamps.
-        .addTserverFlag("--safe_time_advancement_without_writes=false");
-  }
+  private static final Schema schema = getSchema();
+  private static KuduTable table;
+  private KuduClient client;
+
+  private static final MiniKuduClusterBuilder clusterBuilder = KuduTestHarness.getBaseClusterBuilder()
+      // Before starting the cluster, disable automatic safe time advancement in the
+      // absence of writes. This test does snapshot reads in the present and expects
+      // certain timestamps to be assigned to the scans. If safe time was allowed
+      // to move automatically the scans might not be assigned the expected timestamps.
+      .addTabletServerFlag("--safe_time_advancement_without_writes=false");
+
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness(clusterBuilder);
 
   @Before
   public void setUp() throws Exception {
+    client = harness.getClient();
     // Using multiple tablets doesn't work with the current way this test works since we could
     // jump from one TS to another which changes the logical clock.
     CreateTableOptions builder =
         new CreateTableOptions().setRangePartitionColumns(ImmutableList.of("key"));
-    table = createTable(TABLE_NAME, schema, builder);
+    table = client.createTable(TABLE_NAME, schema, builder);
   }
 
   private static Schema getSchema() {
@@ -89,7 +94,7 @@ public class TestHybridTime extends BaseKuduTest {
    */
   @Test(timeout = 100000)
   public void test() throws Exception {
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
 
     // Test timestamp propagation with AUTO_FLUSH_SYNC flush mode.
     session.setFlushMode(KuduSession.FlushMode.AUTO_FLUSH_SYNC);
@@ -169,7 +174,7 @@ public class TestHybridTime extends BaseKuduTest {
   }
 
   private int scanAtSnapshot(long time) throws Exception {
-    AsyncKuduScanner.AsyncKuduScannerBuilder builder = client.newScannerBuilder(table)
+    AsyncKuduScanner.AsyncKuduScannerBuilder builder = harness.getAsyncClient().newScannerBuilder(table)
         .snapshotTimestampRaw(time)
         .readMode(AsyncKuduScanner.ReadMode.READ_AT_SNAPSHOT);
     return countRowsInScan(builder.build());

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestKeyEncoding.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKeyEncoding.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKeyEncoding.java
index f169f48..10215d2 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKeyEncoding.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKeyEncoding.java
@@ -25,6 +25,9 @@ import java.util.ArrayList;
 import java.util.List;
 
 import com.google.common.collect.ImmutableList;
+import org.apache.kudu.test.KuduTestHarness;
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 
 import org.apache.kudu.ColumnSchema;
@@ -36,7 +39,17 @@ import org.apache.kudu.client.PartitionSchema.HashBucketSchema;
 import org.apache.kudu.client.PartitionSchema.RangeSchema;
 import org.apache.kudu.util.DecimalUtil;
 
-public class TestKeyEncoding extends BaseKuduTest {
+public class TestKeyEncoding {
+
+  private KuduClient client;
+
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
+  @Before
+  public void setUp() {
+    client = harness.getClient();
+  }
 
   private static Schema buildSchema(ColumnSchemaBuilder... columns) {
     int i = 0;
@@ -372,9 +385,9 @@ public class TestKeyEncoding extends BaseKuduTest {
         new ColumnSchemaBuilder("float", Type.FLOAT),     // not primary key type
         new ColumnSchemaBuilder("double", Type.DOUBLE));  // not primary key type
 
-    KuduTable table = createTable("testAllPrimaryKeyTypes-" + System.currentTimeMillis(),
+    KuduTable table = client.createTable("testAllPrimaryKeyTypes-" + System.currentTimeMillis(),
         schema, defaultCreateTableOptions(schema));
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
 
     Insert insert = table.newInsert();
     PartialRow row = insert.getRow();
@@ -394,7 +407,7 @@ public class TestKeyEncoding extends BaseKuduTest {
     session.apply(insert);
     session.close();
 
-    KuduScanner scanner = syncClient.newScannerBuilder(table).build();
+    KuduScanner scanner = client.newScannerBuilder(table).build();
     while (scanner.hasMoreRows()) {
       RowResultIterator it = scanner.nextRows();
       assertTrue(it.hasNext());

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduClient.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduClient.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduClient.java
index 6e6b831..49357f6 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduClient.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduClient.java
@@ -53,11 +53,13 @@ import java.util.concurrent.Future;
 import com.google.common.collect.ImmutableList;
 import com.stumbleupon.async.Deferred;
 
-import org.apache.kudu.client.MiniKuduCluster.MiniKuduClusterBuilder;
+import org.apache.kudu.test.KuduTestHarness;
+import org.apache.kudu.test.KuduTestHarness.TabletServerConfig;
+import org.apache.kudu.util.ClientTestUtil;
 import org.apache.kudu.util.TimestampUtil;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.TestName;
 
 import org.apache.kudu.ColumnSchema;
 import org.apache.kudu.Schema;
@@ -67,7 +69,7 @@ import org.apache.kudu.util.DecimalUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class TestKuduClient extends BaseKuduTest {
+public class TestKuduClient {
   private static final Logger LOG = LoggerFactory.getLogger(TestKuduClient.class);
 
   private static final String TABLE_NAME = "TestKuduClient";
@@ -75,21 +77,18 @@ public class TestKuduClient extends BaseKuduTest {
   private static final int SHORT_SCANNER_TTL_MS = 5000;
   private static final int SHORT_SCANNER_GC_US = SHORT_SCANNER_TTL_MS * 100; // 10% of the TTL.
 
+  private static final Schema basicSchema = ClientTestUtil.getBasicSchema();
+
+  private KuduClient client;
+  private AsyncKuduClient asyncClient;
+
   @Rule
-  public TestName testName = new TestName();
-
-  @Override
-  protected MiniKuduClusterBuilder getMiniClusterBuilder() {
-    MiniKuduClusterBuilder builder = super.getMiniClusterBuilder();
-    // Set a short scanner ttl for some tests.
-    if ("testKeepAlive".equals(testName.getMethodName()) ||
-        "testScannerExpiration".equals(testName.getMethodName())
-    ) {
-      LOG.info("Overriding scanner TTL and GC for testKeepAlive");
-      builder.addTserverFlag(String.format("--scanner_ttl_ms=%d", SHORT_SCANNER_TTL_MS));
-      builder.addTserverFlag(String.format("--scanner_gc_check_interval_us=%d", SHORT_SCANNER_GC_US));
-    }
-    return builder;
+  public KuduTestHarness harness = new KuduTestHarness();
+
+  @Before
+  public void setUp() {
+    client = harness.getClient();
+    asyncClient = harness.getAsyncClient();
   }
 
   /**
@@ -98,28 +97,29 @@ public class TestKuduClient extends BaseKuduTest {
   @Test(timeout = 100000)
   public void testLastPropagatedTimestamps() throws Exception {
     // Scan a table to ensure a timestamp is propagated.
-    KuduTable table = syncClient.createTable(TABLE_NAME, basicSchema, getBasicCreateTableOptions());
-    syncClient.newScannerBuilder(table).build().nextRows().getNumRows();
-    assertTrue(syncClient.hasLastPropagatedTimestamp());
+    KuduTable table = client.createTable(TABLE_NAME, basicSchema, getBasicCreateTableOptions());
+    client.newScannerBuilder(table).build().nextRows().getNumRows();
     assertTrue(client.hasLastPropagatedTimestamp());
+    assertTrue(client.hasLastPropagatedTimestamp());
+    assertTrue(asyncClient.hasLastPropagatedTimestamp());
 
-    long initial_ts = syncClient.getLastPropagatedTimestamp();
+    long initial_ts = client.getLastPropagatedTimestamp();
 
     // Check that the initial timestamp is consistent with the asynchronous client.
     assertEquals(initial_ts, client.getLastPropagatedTimestamp());
-    assertEquals(initial_ts, syncClient.getLastPropagatedTimestamp());
+    assertEquals(initial_ts, asyncClient.getLastPropagatedTimestamp());
 
     // Attempt to change the timestamp to a lower value. This should not change
     // the internal timestamp, as it must be monotonically increasing.
-    syncClient.updateLastPropagatedTimestamp(initial_ts - 1);
+    client.updateLastPropagatedTimestamp(initial_ts - 1);
     assertEquals(initial_ts, client.getLastPropagatedTimestamp());
-    assertEquals(initial_ts, syncClient.getLastPropagatedTimestamp());
+    assertEquals(initial_ts, asyncClient.getLastPropagatedTimestamp());
 
     // Use the synchronous client to update the last propagated timestamp and
     // check with both clients that the timestamp was updated.
-    syncClient.updateLastPropagatedTimestamp(initial_ts + 1);
+    client.updateLastPropagatedTimestamp(initial_ts + 1);
     assertEquals(initial_ts + 1, client.getLastPropagatedTimestamp());
-    assertEquals(initial_ts + 1, syncClient.getLastPropagatedTimestamp());
+    assertEquals(initial_ts + 1, asyncClient.getLastPropagatedTimestamp());
   }
 
   /**
@@ -128,22 +128,22 @@ public class TestKuduClient extends BaseKuduTest {
   @Test(timeout = 100000)
   public void testCreateDeleteTable() throws Exception {
     // Check that we can create a table.
-    syncClient.createTable(TABLE_NAME, basicSchema, getBasicCreateTableOptions());
-    assertFalse(syncClient.getTablesList().getTablesList().isEmpty());
-    assertTrue(syncClient.getTablesList().getTablesList().contains(TABLE_NAME));
+    client.createTable(TABLE_NAME, basicSchema, getBasicCreateTableOptions());
+    assertFalse(client.getTablesList().getTablesList().isEmpty());
+    assertTrue(client.getTablesList().getTablesList().contains(TABLE_NAME));
 
     // Check that we can delete it.
-    syncClient.deleteTable(TABLE_NAME);
-    assertFalse(syncClient.getTablesList().getTablesList().contains(TABLE_NAME));
+    client.deleteTable(TABLE_NAME);
+    assertFalse(client.getTablesList().getTablesList().contains(TABLE_NAME));
 
     // Check that we can re-recreate it, with a different schema.
     List<ColumnSchema> columns = new ArrayList<>(basicSchema.getColumns());
     columns.add(new ColumnSchema.ColumnSchemaBuilder("one more", Type.STRING).build());
     Schema newSchema = new Schema(columns);
-    syncClient.createTable(TABLE_NAME, newSchema, getBasicCreateTableOptions());
+    client.createTable(TABLE_NAME, newSchema, getBasicCreateTableOptions());
 
     // Check that we can open a table and see that it has the new schema.
-    KuduTable table = syncClient.openTable(TABLE_NAME);
+    KuduTable table = client.openTable(TABLE_NAME);
     assertEquals(newSchema.getColumnCount(), table.getSchema().getColumnCount());
     assertTrue(table.getPartitionSchema().isSimpleRangePartitioning());
 
@@ -171,7 +171,7 @@ public class TestKuduClient extends BaseKuduTest {
     }
     Schema schema = new Schema(cols);
     try {
-      syncClient.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
+      client.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
       fail();
     } catch (NonRecoverableException nre) {
       assertThat(nre.toString(), containsString(
@@ -182,25 +182,28 @@ public class TestKuduClient extends BaseKuduTest {
   /*
    * Test the scanner behavior when a scanner is used beyond
    * the scanner ttl without calling keepAlive.
-   * Note: The getMiniClusterBuilder override above depends on this method name.
    */
   @Test(timeout = 100000)
+  @TabletServerConfig(flags = {
+      "--scanner_ttl_ms=" + SHORT_SCANNER_TTL_MS,
+      "--scanner_gc_check_interval_us=" + SHORT_SCANNER_GC_US,
+  })
   public void testScannerExpiration() throws Exception {
     // Create a basic table and load it with data.
     int numRows = 1000;
-    syncClient.createTable(
+    client.createTable(
         TABLE_NAME,
         basicSchema,
         new CreateTableOptions().addHashPartitions(ImmutableList.of("key"), 2));
-    KuduSession session = syncClient.newSession();
-    KuduTable table = syncClient.openTable(TABLE_NAME);
+    KuduSession session = client.newSession();
+    KuduTable table = client.openTable(TABLE_NAME);
 
     for (int i = 0; i < numRows; i++) {
       Insert insert = createBasicSchemaInsert(table, i);
       session.apply(insert);
     }
 
-    KuduScanner scanner = new KuduScanner.KuduScannerBuilder(client, table)
+    KuduScanner scanner = new KuduScanner.KuduScannerBuilder(asyncClient, table)
         .replicaSelection(ReplicaSelection.CLOSEST_REPLICA)
         .batchSizeBytes(100) // Use a small batch size so we can call nextRows many times.
         .build();
@@ -226,25 +229,28 @@ public class TestKuduClient extends BaseKuduTest {
 
   /*
    * Test keeping a scanner alive beyond scanner ttl.
-   * Note: The getMiniClusterBuilder override above depends on this method name.
    */
   @Test(timeout = 100000)
+  @TabletServerConfig(flags = {
+      "--scanner_ttl_ms=" + SHORT_SCANNER_TTL_MS,
+      "--scanner_gc_check_interval_us=" + SHORT_SCANNER_GC_US,
+  })
   public void testKeepAlive() throws Exception {
     // Create a basic table and load it with data.
     int numRows = 1000;
-    syncClient.createTable(
+    client.createTable(
         TABLE_NAME,
-            basicSchema,
-            new CreateTableOptions().addHashPartitions(ImmutableList.of("key"), 2));
-    KuduSession session = syncClient.newSession();
-    KuduTable table = syncClient.openTable(TABLE_NAME);
+        basicSchema,
+        new CreateTableOptions().addHashPartitions(ImmutableList.of("key"), 2));
+    KuduSession session = client.newSession();
+    KuduTable table = client.openTable(TABLE_NAME);
 
     for (int i = 0; i < numRows; i++) {
       Insert insert = createBasicSchemaInsert(table, i);
       session.apply(insert);
     }
 
-    KuduScanner scanner = new KuduScanner.KuduScannerBuilder(client, table)
+    KuduScanner scanner = new KuduScanner.KuduScannerBuilder(asyncClient, table)
         .replicaSelection(ReplicaSelection.CLOSEST_REPLICA)
         .batchSizeBytes(100) // Use a small batch size so we can call nextRows many times.
         .build();
@@ -327,9 +333,9 @@ public class TestKuduClient extends BaseKuduTest {
              .defaultValue("def")
              .build());
     Schema schema = new Schema(cols);
-    syncClient.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
-    KuduSession session = syncClient.newSession();
-    KuduTable table = syncClient.openTable(TABLE_NAME);
+    client.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
+    KuduSession session = client.newSession();
+    KuduTable table = client.openTable(TABLE_NAME);
 
     // Insert various rows. '-' indicates leaving the row unset in the insert.
     List<String> rows = ImmutableList.of(
@@ -384,10 +390,10 @@ public class TestKuduClient extends BaseKuduTest {
   @Test(timeout = 100000)
   public void testStrings() throws Exception {
     Schema schema = createManyStringsSchema();
-    syncClient.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
+    client.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
 
-    KuduSession session = syncClient.newSession();
-    KuduTable table = syncClient.openTable(TABLE_NAME);
+    KuduSession session = client.newSession();
+    KuduTable table = client.openTable(TABLE_NAME);
     for (int i = 0; i < 100; i++) {
       Insert insert = table.newInsert();
       PartialRow row = insert.getRow();
@@ -417,7 +423,7 @@ public class TestKuduClient extends BaseKuduTest {
         "STRING key=key_04, STRING c1=c1_4, STRING c2=c2_4, STRING c3=NULL, STRING c4=c4_4",
         rowStrings.get(4));
 
-    KuduScanner scanner = syncClient.newScannerBuilder(table).build();
+    KuduScanner scanner = client.newScannerBuilder(table).build();
 
     assertTrue("Scanner should have returned row", scanner.hasMoreRows());
 
@@ -438,10 +444,10 @@ public class TestKuduClient extends BaseKuduTest {
   @Test(timeout = 100000)
   public void testUTF8() throws Exception {
     Schema schema = createManyStringsSchema();
-    syncClient.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
+    client.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
 
-    KuduSession session = syncClient.newSession();
-    KuduTable table = syncClient.openTable(TABLE_NAME);
+    KuduSession session = client.newSession();
+    KuduTable table = client.openTable(TABLE_NAME);
     Insert insert = table.newInsert();
     PartialRow row = insert.getRow();
     row.addString("key", "กขฃคฅฆง"); // some thai
@@ -465,12 +471,12 @@ public class TestKuduClient extends BaseKuduTest {
   @Test(timeout = 100000)
   public void testBinaryColumns() throws Exception {
     Schema schema = createSchemaWithBinaryColumns();
-    syncClient.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
+    client.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
 
     byte[] testArray = new byte[] {1, 2, 3, 4, 5, 6 ,7, 8, 9};
 
-    KuduSession session = syncClient.newSession();
-    KuduTable table = syncClient.openTable(TABLE_NAME);
+    KuduSession session = client.newSession();
+    KuduTable table = client.openTable(TABLE_NAME);
     for (int i = 0; i < 100; i++) {
       Insert insert = table.newInsert();
       PartialRow row = insert.getRow();
@@ -508,12 +514,12 @@ public class TestKuduClient extends BaseKuduTest {
   @Test(timeout = 100000)
   public void testTimestampColumns() throws Exception {
     Schema schema = createSchemaWithTimestampColumns();
-    syncClient.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
+    client.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
 
     List<Long> timestamps = new ArrayList<>();
 
-    KuduSession session = syncClient.newSession();
-    KuduTable table = syncClient.openTable(TABLE_NAME);
+    KuduSession session = client.newSession();
+    KuduTable table = client.openTable(TABLE_NAME);
     long lastTimestamp = 0;
     for (int i = 0; i < 100; i++) {
       Insert insert = table.newInsert();
@@ -556,10 +562,10 @@ public class TestKuduClient extends BaseKuduTest {
   @Test(timeout = 100000)
   public void testDecimalColumns() throws Exception {
     Schema schema = createSchemaWithDecimalColumns();
-    syncClient.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
+    client.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
 
-    KuduSession session = syncClient.newSession();
-    KuduTable table = syncClient.openTable(TABLE_NAME);
+    KuduSession session = client.newSession();
+    KuduTable table = client.openTable(TABLE_NAME);
 
     // Verify ColumnTypeAttributes
     assertEquals(DecimalUtil.MAX_DECIMAL128_PRECISION,
@@ -595,9 +601,10 @@ public class TestKuduClient extends BaseKuduTest {
   */
   @Test
   public void testScanWithLimit() throws Exception {
-    syncClient.createTable(TABLE_NAME, basicSchema, getBasicTableOptionsWithNonCoveredRange());
-    KuduTable table = syncClient.openTable(TABLE_NAME);
-    KuduSession session = syncClient.newSession();
+    AsyncKuduClient asyncClient = harness.getAsyncClient();
+    client.createTable(TABLE_NAME, basicSchema, getBasicTableOptionsWithNonCoveredRange());
+    KuduTable table = client.openTable(TABLE_NAME);
+    KuduSession session = client.newSession();
     int num_rows = 100;
     for (int key = 0; key < num_rows; key++) {
       session.apply(createBasicSchemaInsert(table, key));
@@ -607,7 +614,7 @@ public class TestKuduClient extends BaseKuduTest {
     int non_positives[] = { -1, 0 };
     for (int limit : non_positives) {
       try {
-        KuduScanner scanner = syncClient.newScannerBuilder(table)
+        KuduScanner scanner = client.newScannerBuilder(table)
                                         .limit(limit)
                                         .build();
         fail();
@@ -619,7 +626,7 @@ public class TestKuduClient extends BaseKuduTest {
     // Test with a limit and ensure we get the expected number of rows.
     int limits[] = { num_rows - 1, num_rows, num_rows + 1 };
     for (int limit : limits) {
-      KuduScanner scanner = syncClient.newScannerBuilder(table)
+      KuduScanner scanner = client.newScannerBuilder(table)
                                       .limit(limit)
                                       .build();
       int count = 0;
@@ -632,7 +639,7 @@ public class TestKuduClient extends BaseKuduTest {
 
     // Now test with limits for async scanners.
     for (int limit : limits) {
-      AsyncKuduScanner scanner = new AsyncKuduScanner.AsyncKuduScannerBuilder(client, table)
+      AsyncKuduScanner scanner = new AsyncKuduScanner.AsyncKuduScannerBuilder(asyncClient, table)
                                                      .limit(limit)
                                                      .build();
       assertEquals(Math.min(limit, num_rows), countRowsInScan(scanner));
@@ -645,11 +652,11 @@ public class TestKuduClient extends BaseKuduTest {
   @Test
   public void testScanWithPredicates() throws Exception {
     Schema schema = createManyStringsSchema();
-    syncClient.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
+    client.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
 
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_BACKGROUND);
-    KuduTable table = syncClient.openTable(TABLE_NAME);
+    KuduTable table = client.openTable(TABLE_NAME);
     for (int i = 0; i < 100; i++) {
       Insert insert = table.newInsert();
       PartialRow row = insert.getRow();
@@ -726,7 +733,7 @@ public class TestKuduClient extends BaseKuduTest {
 
   @Test
   public void testGetAuthnToken() throws Exception {
-    byte[] token = client.exportAuthenticationCredentials().join();
+    byte[] token = asyncClient.exportAuthenticationCredentials().join();
     assertNotNull(token);
   }
 
@@ -743,7 +750,7 @@ public class TestKuduClient extends BaseKuduTest {
                                                   Integer lowerBound,
                                                   Integer upperBound) throws Exception {
 
-    KuduScanner.KuduScannerBuilder scanBuilder = syncClient.newScannerBuilder(table);
+    KuduScanner.KuduScannerBuilder scanBuilder = client.newScannerBuilder(table);
     if (lowerBound != null) {
       PartialRow bound = basicSchema.newPartialRow();
       bound.addInt(0, lowerBound);
@@ -768,11 +775,11 @@ public class TestKuduClient extends BaseKuduTest {
    */
   @Test(timeout = 100000)
   public void testScanNonCoveredTable() throws Exception {
-    syncClient.createTable(TABLE_NAME, basicSchema, getBasicTableOptionsWithNonCoveredRange());
+    client.createTable(TABLE_NAME, basicSchema, getBasicTableOptionsWithNonCoveredRange());
 
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_BACKGROUND);
-    KuduTable table = syncClient.openTable(TABLE_NAME);
+    KuduTable table = client.openTable(TABLE_NAME);
 
     for (int key = 0; key < 100; key++) {
       session.apply(createBasicSchemaInsert(table, key));
@@ -791,12 +798,13 @@ public class TestKuduClient extends BaseKuduTest {
   }
 
   /**
-   * Creates a local client that we auto-close while buffering one row, then makes sure that after
+   * Creates a local aclient that we auto-close while buffering one row, then makes sure that after
    * closing that we can read the row.
    */
   @Test(timeout = 100000)
   public void testAutoClose() throws Exception {
-    try (KuduClient localClient = new KuduClient.KuduClientBuilder(getMasterAddressesAsString()).build()) {
+    try (KuduClient localClient =
+             new KuduClient.KuduClientBuilder(harness.getMasterAddressesAsString()).build()) {
       localClient.createTable(TABLE_NAME, basicSchema, getBasicCreateTableOptions());
       KuduTable table = localClient.openTable(TABLE_NAME);
       KuduSession session = localClient.newSession();
@@ -806,8 +814,8 @@ public class TestKuduClient extends BaseKuduTest {
       session.apply(insert);
     }
 
-    KuduTable table = syncClient.openTable(TABLE_NAME);
-    AsyncKuduScanner scanner = new AsyncKuduScanner.AsyncKuduScannerBuilder(client, table).build();
+    KuduTable table = client.openTable(TABLE_NAME);
+    AsyncKuduScanner scanner = new AsyncKuduScanner.AsyncKuduScannerBuilder(asyncClient, table).build();
     assertEquals(1, countRowsInScan(scanner));
   }
 
@@ -819,7 +827,8 @@ public class TestKuduClient extends BaseKuduTest {
   public void testCloseShortlyAfterOpen() throws Exception {
     CapturingLogAppender cla = new CapturingLogAppender();
     try (Closeable c = cla.attach()) {
-      try (KuduClient localClient = new KuduClient.KuduClientBuilder(getMasterAddressesAsString()).build()) {
+      try (KuduClient localClient =
+               new KuduClient.KuduClientBuilder(harness.getMasterAddressesAsString()).build()) {
         // Force the client to connect to the masters.
         localClient.exportAuthenticationCredentials();
       }
@@ -838,8 +847,9 @@ public class TestKuduClient extends BaseKuduTest {
   public void testNoLogSpewOnConnectionRefused() throws Exception {
     CapturingLogAppender cla = new CapturingLogAppender();
     try (Closeable c = cla.attach()) {
-      killAllMasterServers();
-      try (KuduClient localClient = new KuduClient.KuduClientBuilder(getMasterAddressesAsString()).build()) {
+      harness.killAllMasterServers();
+      try (KuduClient localClient =
+               new KuduClient.KuduClientBuilder(harness.getMasterAddressesAsString()).build()) {
         // Force the client to connect to the masters.
         localClient.exportAuthenticationCredentials();
         fail("Should have failed to connect.");
@@ -850,7 +860,7 @@ public class TestKuduClient extends BaseKuduTest {
                 ".*Connection refused.*"));
       }
     } finally {
-      startAllMasterServers();
+      harness.startAllMasterServers();
     }
     // Ensure there is no log spew due to an unexpected lost connection.
     String logText = cla.getAppendedText();
@@ -863,7 +873,7 @@ public class TestKuduClient extends BaseKuduTest {
   @Test(timeout = 100000)
   public void testCustomNioExecutor() throws Exception {
     long startTime = System.nanoTime();
-    final KuduClient localClient = new KuduClient.KuduClientBuilder(getMasterAddressesAsString())
+    final KuduClient localClient = new KuduClient.KuduClientBuilder(harness.getMasterAddressesAsString())
         .nioExecutors(Executors.newFixedThreadPool(1), Executors.newFixedThreadPool(2))
         .bossCount(1)
         .workerCount(2)
@@ -901,7 +911,7 @@ public class TestKuduClient extends BaseKuduTest {
 
   @Test(expected=IllegalArgumentException.class)
   public void testNoDefaultPartitioning() throws Exception {
-    syncClient.createTable(TABLE_NAME, basicSchema, new CreateTableOptions());
+    client.createTable(TABLE_NAME, basicSchema, new CreateTableOptions());
   }
 
   @Test(timeout = 100000)
@@ -913,18 +923,18 @@ public class TestKuduClient extends BaseKuduTest {
     upper.addInt("key", 1);
     options.addRangePartition(lower, upper);
 
-    syncClient.createTable(TABLE_NAME, basicSchema, options);
-    KuduTable table = syncClient.openTable(TABLE_NAME);
+    client.createTable(TABLE_NAME, basicSchema, options);
+    KuduTable table = client.openTable(TABLE_NAME);
 
     // Count the number of tablets.
-    KuduScanToken.KuduScanTokenBuilder tokenBuilder = syncClient.newScanTokenBuilder(table);
+    KuduScanToken.KuduScanTokenBuilder tokenBuilder = client.newScanTokenBuilder(table);
     List<KuduScanToken> tokens = tokenBuilder.build();
     assertEquals(1, tokens.size());
 
     // Add a range partition with a separate client. The new client is necessary
     // in order to avoid clearing the meta cache as part of the alter operation.
-    try (KuduClient alterClient = new KuduClient.KuduClientBuilder(getMasterAddressesAsString())
-                                                .defaultAdminOperationTimeoutMs(DEFAULT_SLEEP)
+    try (KuduClient alterClient = new KuduClient.KuduClientBuilder(harness.getMasterAddressesAsString())
+                                                .defaultAdminOperationTimeoutMs(harness.DEFAULT_SLEEP)
                                                 .build()) {
       AlterTableOptions alter = new AlterTableOptions();
       lower = basicSchema.newPartialRow();
@@ -936,20 +946,20 @@ public class TestKuduClient extends BaseKuduTest {
 
     // Count the number of tablets.  The result should still be the same, since
     // the new tablet is still cached as a non-covered range.
-    tokenBuilder = syncClient.newScanTokenBuilder(table);
+    tokenBuilder = client.newScanTokenBuilder(table);
     tokens = tokenBuilder.build();
     assertEquals(1, tokens.size());
 
     // Reopen the table and count the tablets again. The new tablet should now show up.
-    table = syncClient.openTable(TABLE_NAME);
-    tokenBuilder = syncClient.newScanTokenBuilder(table);
+    table = client.openTable(TABLE_NAME);
+    tokenBuilder = client.newScanTokenBuilder(table);
     tokens = tokenBuilder.build();
     assertEquals(2, tokens.size());
   }
 
   @Test(timeout = 100000)
   public void testCreateTableWithConcurrentInsert() throws Exception {
-    KuduTable table = syncClient.createTable(
+    KuduTable table = client.createTable(
         TABLE_NAME, createManyStringsSchema(), getBasicCreateTableOptions().setWait(false));
 
     // Insert a row.
@@ -961,19 +971,19 @@ public class TestKuduClient extends BaseKuduTest {
     insert.getRow().addString("key", "key_0");
     insert.getRow().addString("c1", "c1_0");
     insert.getRow().addString("c2", "c2_0");
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     OperationResponse resp = session.apply(insert);
     assertFalse(resp.hasRowError());
 
     // This won't do anything useful (i.e. if the insert succeeds, we know the
     // table has been created), but it's here for additional code coverage.
-    assertTrue(syncClient.isCreateTableDone(TABLE_NAME));
+    assertTrue(client.isCreateTableDone(TABLE_NAME));
   }
 
   @Test(timeout = 100000)
   public void testCreateTableWithConcurrentAlter() throws Exception {
     // Kick off an asynchronous table creation.
-    Deferred<KuduTable> d = client.createTable(TABLE_NAME,
+    Deferred<KuduTable> d = asyncClient.createTable(TABLE_NAME,
         createManyStringsSchema(), getBasicCreateTableOptions());
 
     // Rename the table that's being created to make sure it doesn't interfere
@@ -983,7 +993,7 @@ public class TestKuduClient extends BaseKuduTest {
     // actually exists.
     while (true) {
       try {
-        syncClient.alterTable(TABLE_NAME,
+        client.alterTable(TABLE_NAME,
             new AlterTableOptions().renameTable("foo"));
         break;
       } catch (KuduException e) {
@@ -1034,7 +1044,7 @@ public class TestKuduClient extends BaseKuduTest {
                               final ReplicaSelection replicaSelection)
           throws Exception {
     Schema schema = createManyStringsSchema();
-    syncClient.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
+    client.createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
 
     final int tasksNum = 4;
     List<Callable<Void>> callables = new ArrayList<>();
@@ -1044,9 +1054,9 @@ public class TestKuduClient extends BaseKuduTest {
         public Void call() throws Exception {
           // From the same client continuously performs inserts to a tablet
           // in the given flush mode.
-          KuduSession session = syncClient.newSession();
+          KuduSession session = client.newSession();
           session.setFlushMode(flushMode);
-          KuduTable table = syncClient.openTable(TABLE_NAME);
+          KuduTable table = client.openTable(TABLE_NAME);
           for (int i = 0; i < 3; i++) {
             for (int j = 100 * i; j < 100 * (i + 1); j++) {
               Insert insert = table.newInsert();
@@ -1066,14 +1076,14 @@ public class TestKuduClient extends BaseKuduTest {
             // reads will not "go back in time" regarding writes that other
             // clients have done.
             for (int k = 0; k < 3; k++) {
-              AsyncKuduScanner scanner = client.newScannerBuilder(table)
+              AsyncKuduScanner scanner = asyncClient.newScannerBuilder(table)
                       .readMode(AsyncKuduScanner.ReadMode.READ_YOUR_WRITES)
                       .replicaSelection(replicaSelection)
                       .build();
               KuduScanner syncScanner = new KuduScanner(scanner);
-              long preTs = client.getLastPropagatedTimestamp();
+              long preTs = asyncClient.getLastPropagatedTimestamp();
               assertNotEquals(AsyncKuduClient.NO_TIMESTAMP,
-                              client.getLastPropagatedTimestamp());
+                  asyncClient.getLastPropagatedTimestamp());
 
               long row_count = countRowsInScan(syncScanner);
               long expected_count = 100L * (i + 1);

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduSession.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduSession.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduSession.java
index 5f9d942..46624c0 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduSession.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduSession.java
@@ -31,17 +31,35 @@ import static org.junit.Assert.fail;
 import java.util.List;
 
 import com.google.common.collect.ImmutableList;
+import org.apache.kudu.Schema;
+import org.apache.kudu.test.KuduTestHarness;
+import org.apache.kudu.util.ClientTestUtil;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 
-public class TestKuduSession extends BaseKuduTest {
+public class TestKuduSession {
   private static final String tableName = "TestKuduSession";
 
+  private static final Schema basicSchema = ClientTestUtil.getBasicSchema();
+
+  private KuduClient client;
+  private AsyncKuduClient asyncClient;
+
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
+  @Before
+  public void setUp() {
+    client = harness.getClient();
+    asyncClient = harness.getAsyncClient();
+  }
+
   @Test(timeout = 100000)
   public void testBasicOps() throws Exception {
-    KuduTable table = createTable(tableName, basicSchema, getBasicCreateTableOptions());
+    KuduTable table = client.createTable(tableName, basicSchema, getBasicCreateTableOptions());
 
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     for (int i = 0; i < 10; i++) {
       session.apply(createInsert(table, i));
     }
@@ -61,9 +79,9 @@ public class TestKuduSession extends BaseKuduTest {
 
   @Test(timeout = 100000)
   public void testIgnoreAllDuplicateRows() throws Exception {
-    KuduTable table = createTable(tableName, basicSchema, getBasicCreateTableOptions());
+    KuduTable table = client.createTable(tableName, basicSchema, getBasicCreateTableOptions());
 
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setIgnoreAllDuplicateRows(true);
     for (int i = 0; i < 10; i++) {
       session.apply(createInsert(table, i));
@@ -92,9 +110,9 @@ public class TestKuduSession extends BaseKuduTest {
 
   @Test(timeout = 100000)
   public void testBatchWithSameRow() throws Exception {
-    KuduTable table = createTable(tableName, basicSchema, getBasicCreateTableOptions());
+    KuduTable table = client.createTable(tableName, basicSchema, getBasicCreateTableOptions());
 
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setFlushMode(SessionConfiguration.FlushMode.MANUAL_FLUSH);
 
     // Insert 25 rows, one per batch, along with 50 updates for each, and a delete at the end,
@@ -115,7 +133,7 @@ public class TestKuduSession extends BaseKuduTest {
       session.apply(del);
       session.flush();
       if (i % 2 == 0) {
-        client.emptyTabletsCacheForTable(table.getTableId());
+        asyncClient.emptyTabletsCacheForTable(table.getTableId());
       }
     }
     assertEquals(0, countRowsInScan(client.newScannerBuilder(table).build()));
@@ -128,7 +146,7 @@ public class TestKuduSession extends BaseKuduTest {
    */
   @Test(timeout = 100000)
   public void testEmptyFlush() throws Exception {
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setFlushMode(SessionConfiguration.FlushMode.MANUAL_FLUSH);
     List<OperationResponse> result = session.flush();
     assertNotNull(result);
@@ -152,10 +170,10 @@ public class TestKuduSession extends BaseKuduTest {
       split.addInt(0, i * numRowsPerTablet);
       builder.addSplitRow(split);
     }
-    KuduTable table = createTable(tableName, basicSchema, builder);
+    KuduTable table = client.createTable(tableName, basicSchema, builder);
 
     // Configure the session to background flush as often as it can (every 1ms).
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_BACKGROUND);
     session.setFlushInterval(1);
 
@@ -171,8 +189,8 @@ public class TestKuduSession extends BaseKuduTest {
 
   @Test(timeout = 10000)
   public void testOverWritingValues() throws Exception {
-    KuduTable table = createTable(tableName, basicSchema, getBasicCreateTableOptions());
-    KuduSession session = syncClient.newSession();
+    KuduTable table = client.createTable(tableName, basicSchema, getBasicCreateTableOptions());
+    KuduSession session = client.newSession();
     Insert insert = createInsert(table, 0);
     PartialRow row = insert.getRow();
 
@@ -189,7 +207,7 @@ public class TestKuduSession extends BaseKuduTest {
     assertEquals(5, row.getVarLengthData().size());
     session.apply(insert);
 
-    KuduScanner scanner = syncClient.newScannerBuilder(table).build();
+    KuduScanner scanner = client.newScannerBuilder(table).build();
     RowResult rr = scanner.nextRows().next();
     assertEquals(magicNumber, rr.getInt(1));
     assertEquals(magicNumber, rr.getInt(2));
@@ -207,8 +225,8 @@ public class TestKuduSession extends BaseKuduTest {
 
   @Test(timeout = 10000)
   public void testUpsert() throws Exception {
-    KuduTable table = createTable(tableName, basicSchema, getBasicCreateTableOptions());
-    KuduSession session = syncClient.newSession();
+    KuduTable table = client.createTable(tableName, basicSchema, getBasicCreateTableOptions());
+    KuduSession session = client.newSession();
 
     // Test an Upsert that acts as an Insert.
     assertFalse(session.apply(createUpsert(table, 1, 1, false)).hasRowError());
@@ -233,10 +251,10 @@ public class TestKuduSession extends BaseKuduTest {
   public void testInsertManualFlushNonCoveredRange() throws Exception {
     CreateTableOptions createOptions = getBasicTableOptionsWithNonCoveredRange();
     createOptions.setNumReplicas(1);
-    syncClient.createTable(tableName, basicSchema, createOptions);
-    KuduTable table = syncClient.openTable(tableName);
+    client.createTable(tableName, basicSchema, createOptions);
+    KuduTable table = client.openTable(tableName);
 
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setFlushMode(SessionConfiguration.FlushMode.MANUAL_FLUSH);
 
     // Insert in reverse sorted order so that more table location lookups occur
@@ -272,10 +290,10 @@ public class TestKuduSession extends BaseKuduTest {
   public void testInsertManualFlushResponseOrder() throws Exception {
     CreateTableOptions createOptions = getBasicTableOptionsWithNonCoveredRange();
     createOptions.setNumReplicas(1);
-    syncClient.createTable(tableName, basicSchema, createOptions);
-    KuduTable table = syncClient.openTable(tableName);
+    client.createTable(tableName, basicSchema, createOptions);
+    KuduTable table = client.openTable(tableName);
 
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setFlushMode(SessionConfiguration.FlushMode.MANUAL_FLUSH);
 
     // Insert a batch of some valid and some invalid.
@@ -302,10 +320,10 @@ public class TestKuduSession extends BaseKuduTest {
   public void testInsertAutoFlushSyncNonCoveredRange() throws Exception {
     CreateTableOptions createOptions = getBasicTableOptionsWithNonCoveredRange();
     createOptions.setNumReplicas(1);
-    syncClient.createTable(tableName, basicSchema, createOptions);
-    KuduTable table = syncClient.openTable(tableName);
+    client.createTable(tableName, basicSchema, createOptions);
+    KuduTable table = client.openTable(tableName);
 
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_SYNC);
 
     List<Integer> nonCoveredKeys = ImmutableList.of(350, 300, 199, 150, 100, -1, -50);
@@ -320,10 +338,10 @@ public class TestKuduSession extends BaseKuduTest {
   public void testInsertAutoFlushBackgrounNonCoveredRange() throws Exception {
     CreateTableOptions createOptions = getBasicTableOptionsWithNonCoveredRange();
     createOptions.setNumReplicas(1);
-    syncClient.createTable(tableName, basicSchema, createOptions);
-    KuduTable table = syncClient.openTable(tableName);
+    client.createTable(tableName, basicSchema, createOptions);
+    KuduTable table = client.openTable(tableName);
 
-    AsyncKuduSession session = client.newSession();
+    AsyncKuduSession session = asyncClient.newSession();
     session.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_BACKGROUND);
 
     List<Integer> nonCoveredKeys = ImmutableList.of(350, 300, 199, 150, 100, -1, -50);

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduTable.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduTable.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduTable.java
index aa7adf7..4d95f9a 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduTable.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduTable.java
@@ -16,6 +16,7 @@
 // under the License.
 package org.apache.kudu.client;
 
+import static org.apache.kudu.test.KuduTestHarness.DEFAULT_SLEEP;
 import static org.apache.kudu.util.ClientTestUtil.createBasicSchemaInsert;
 import static org.apache.kudu.util.ClientTestUtil.getBasicCreateTableOptions;
 import static org.apache.kudu.util.ClientTestUtil.getBasicSchema;
@@ -33,18 +34,38 @@ import java.util.List;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
+import org.apache.kudu.test.KuduTestHarness;
+import org.apache.kudu.util.ClientTestUtil;
 import org.junit.Before;
-import org.junit.BeforeClass;
+import org.junit.Rule;
 import org.junit.Test;
 
 import org.apache.kudu.ColumnSchema;
 import org.apache.kudu.Schema;
 import org.apache.kudu.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestKuduTable {
+  private static final Logger LOG = LoggerFactory.getLogger(TestKuduTable.class);
 
-public class TestKuduTable extends BaseKuduTest {
   private static final Schema BASIC_SCHEMA = getBasicSchema();
   private static final String tableName = "TestKuduTable";
 
+  private static final Schema basicSchema = ClientTestUtil.getBasicSchema();
+
+  private KuduClient client;
+  private AsyncKuduClient asyncClient;
+
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
+  @Before
+  public void setUp() {
+    client = harness.getClient();
+    asyncClient = harness.getAsyncClient();
+  }
+
   @Test(timeout = 100000)
   public void testAlterColumn() throws Exception {
     // Used a simplified schema because BASIC_SCHEMA has extra columns that make the asserts
@@ -57,8 +78,8 @@ public class TestKuduTable extends BaseKuduTest {
             .encoding(ColumnSchema.Encoding.PLAIN_ENCODING)
             .compressionAlgorithm(ColumnSchema.CompressionAlgorithm.NO_COMPRESSION)
             .build());
-    KuduTable table = createTable(tableName, new Schema(columns), getBasicCreateTableOptions());
-    KuduSession session = syncClient.newSession();
+    KuduTable table = client.createTable(tableName, new Schema(columns), getBasicCreateTableOptions());
+    KuduSession session = client.newSession();
     // Insert a row before a default is defined and check the value is NULL.
     insertDefaultRow(table, session, 0);
     //ClientTestUtil.scanTa
@@ -67,7 +88,7 @@ public class TestKuduTable extends BaseKuduTest {
     assertEquals("wrong row", "INT32 key=0, STRING value=NULL", rows.get(0));
 
     // Add a default, checking new rows see the new default and old rows remain the same.
-    syncClient.alterTable(tableName, new AlterTableOptions().changeDefault("value", "pizza"));
+    client.alterTable(tableName, new AlterTableOptions().changeDefault("value", "pizza"));
 
     insertDefaultRow(table, session, 1);
     rows = scanTableToStrings(table);
@@ -76,7 +97,7 @@ public class TestKuduTable extends BaseKuduTest {
     assertEquals("wrong row", "INT32 key=1, STRING value=pizza", rows.get(1));
 
     // Change the default, checking new rows see the new default and old rows remain the same.
-    syncClient.alterTable(tableName, new AlterTableOptions().changeDefault("value", "taco"));
+    client.alterTable(tableName, new AlterTableOptions().changeDefault("value", "taco"));
 
     insertDefaultRow(table, session, 2);
 
@@ -87,7 +108,7 @@ public class TestKuduTable extends BaseKuduTest {
     assertEquals("wrong row", "INT32 key=2, STRING value=taco", rows.get(2));
 
     // Remove the default, checking that new rows default to NULL and old rows remain the same.
-    syncClient.alterTable(tableName, new AlterTableOptions().removeDefault("value"));
+    client.alterTable(tableName, new AlterTableOptions().removeDefault("value"));
 
     insertDefaultRow(table, session, 3);
 
@@ -109,12 +130,12 @@ public class TestKuduTable extends BaseKuduTest {
         ColumnSchema.CompressionAlgorithm.NO_COMPRESSION,
         table.getSchema().getColumn("value").getCompressionAlgorithm());
 
-    syncClient.alterTable(tableName, new AlterTableOptions()
+    client.alterTable(tableName, new AlterTableOptions()
         .changeDesiredBlockSize("value", 8192)
         .changeEncoding("value", ColumnSchema.Encoding.DICT_ENCODING)
         .changeCompressionAlgorithm("value", ColumnSchema.CompressionAlgorithm.SNAPPY));
 
-    KuduTable reopenedTable = syncClient.openTable(tableName);
+    KuduTable reopenedTable = client.openTable(tableName);
     assertEquals("wrong block size post alter",
         8192,
         reopenedTable.getSchema().getColumn("value").getDesiredBlockSize());
@@ -137,30 +158,30 @@ public class TestKuduTable extends BaseKuduTest {
 
   @Test(timeout = 100000)
   public void testAlterTable() throws Exception {
-    createTable(tableName, basicSchema, getBasicCreateTableOptions());
+    client.createTable(tableName, basicSchema, getBasicCreateTableOptions());
     try {
 
       // Add a col.
-      syncClient.alterTable(tableName,
+      client.alterTable(tableName,
           new AlterTableOptions().addColumn("testaddint", Type.INT32, 4));
 
       // Rename that col.
-      syncClient.alterTable(tableName,
+      client.alterTable(tableName,
           new AlterTableOptions().renameColumn("testaddint", "newtestaddint"));
 
       // Delete it.
-      syncClient.alterTable(tableName, new AlterTableOptions().dropColumn("newtestaddint"));
+      client.alterTable(tableName, new AlterTableOptions().dropColumn("newtestaddint"));
 
       String newTableName = tableName +"new";
 
       // Rename our table.
-      syncClient.alterTable(tableName, new AlterTableOptions().renameTable(newTableName));
+      client.alterTable(tableName, new AlterTableOptions().renameTable(newTableName));
 
       // Rename it back.
-      syncClient.alterTable(newTableName, new AlterTableOptions().renameTable(tableName));
+      client.alterTable(newTableName, new AlterTableOptions().renameTable(tableName));
 
       // Add 3 columns, where one has default value, nullable and Timestamp with default value
-      syncClient.alterTable(tableName, new AlterTableOptions()
+      client.alterTable(tableName, new AlterTableOptions()
           .addColumn("testaddmulticolnotnull", Type.INT32, 4)
           .addNullableColumn("testaddmulticolnull", Type.STRING)
           .addColumn("testaddmulticolTimestampcol", Type.UNIXTIME_MICROS,
@@ -169,14 +190,14 @@ public class TestKuduTable extends BaseKuduTest {
       // Try altering a table that doesn't exist.
       String nonExistingTableName = "table_does_not_exist";
       try {
-        syncClient.alterTable(nonExistingTableName, new AlterTableOptions());
+        client.alterTable(nonExistingTableName, new AlterTableOptions());
         fail("Shouldn't be able to alter a table that doesn't exist");
       } catch (KuduException ex) {
         assertTrue(ex.getStatus().isNotFound());
       }
 
       try {
-        syncClient.isAlterTableDone(nonExistingTableName);
+        client.isAlterTableDone(nonExistingTableName);
         fail("Shouldn't be able to query if an alter table is done here");
       } catch (KuduException ex) {
         assertTrue(ex.getStatus().isNotFound());
@@ -186,7 +207,7 @@ public class TestKuduTable extends BaseKuduTest {
       // when shutting down the mini cluster at the end of every test class.
       // However, testGetLocations below expects a certain table count, so
       // we'll delete our table to ensure there's no interaction between them.
-      syncClient.deleteTable(tableName);
+      client.deleteTable(tableName);
     }
   }
 
@@ -196,13 +217,13 @@ public class TestKuduTable extends BaseKuduTest {
    */
   @Test
   public void testGetLocations() throws Exception {
-    int initialTableCount = client.getTablesList().join(DEFAULT_SLEEP).getTablesList().size();
+    int initialTableCount = asyncClient.getTablesList().join(DEFAULT_SLEEP).getTablesList().size();
 
     final String NON_EXISTENT_TABLE = "NON_EXISTENT_TABLE";
 
     // Test a non-existing table
     try {
-      openTable(NON_EXISTENT_TABLE);
+      client.openTable(NON_EXISTENT_TABLE);
       fail("Should receive an exception since the table doesn't exist");
     } catch (Exception ex) {
       // expected
@@ -231,7 +252,7 @@ public class TestKuduTable extends BaseKuduTest {
               .defaultValue(defaultValue).build());
     }
     Schema schemaWithDefault = new Schema(columns);
-    KuduTable kuduTable = createTable(tableWithDefault, schemaWithDefault, builder);
+    KuduTable kuduTable = client.createTable(tableWithDefault, schemaWithDefault, builder);
     assertEquals(defaultInt, kuduTable.getSchema().getColumnByIndex(0).getDefaultValue());
     assertEquals(defaultString,
         kuduTable.getSchema().getColumnByIndex(columns.size() - 2).getDefaultValue());
@@ -242,7 +263,7 @@ public class TestKuduTable extends BaseKuduTest {
     assertTrue(kuduTable.getSchema().hasColumnIds());
 
     // Test we can open a table that was already created.
-    openTable(tableWithDefault);
+    client.openTable(tableWithDefault);
 
     String splitTablePrefix = tableName + "-Splits";
     // Test splitting and reading those splits
@@ -287,22 +308,23 @@ public class TestKuduTable extends BaseKuduTest {
     assertEquals(11, table.asyncGetTabletsLocations(getKeyInBytes(20), getKeyInBytes(10000), DEFAULT_SLEEP).join().size());
 
     // Test listing tables.
-    assertEquals(0, client.getTablesList(NON_EXISTENT_TABLE).join(DEFAULT_SLEEP).getTablesList().size());
-    assertEquals(1, client.getTablesList(tableWithDefault)
-                          .join(DEFAULT_SLEEP).getTablesList().size());
+    assertEquals(0, asyncClient.getTablesList(NON_EXISTENT_TABLE)
+        .join(DEFAULT_SLEEP).getTablesList().size());
+    assertEquals(1, asyncClient.getTablesList(tableWithDefault)
+        .join(DEFAULT_SLEEP).getTablesList().size());
     assertEquals(initialTableCount + 5,
-                 client.getTablesList().join(DEFAULT_SLEEP).getTablesList().size());
-    assertFalse(client.getTablesList(tableWithDefault).
+        asyncClient.getTablesList().join(DEFAULT_SLEEP).getTablesList().size());
+    assertFalse(asyncClient.getTablesList(tableWithDefault).
         join(DEFAULT_SLEEP).getTablesList().isEmpty());
 
-    assertFalse(client.tableExists(NON_EXISTENT_TABLE).join(DEFAULT_SLEEP));
-    assertTrue(client.tableExists(tableWithDefault).join(DEFAULT_SLEEP));
+    assertFalse(asyncClient.tableExists(NON_EXISTENT_TABLE).join(DEFAULT_SLEEP));
+    assertTrue(asyncClient.tableExists(tableWithDefault).join(DEFAULT_SLEEP));
   }
 
   @Test(timeout = 100000)
   public void testLocateTableNonCoveringRange() throws Exception {
-    syncClient.createTable(tableName, basicSchema, getBasicTableOptionsWithNonCoveredRange());
-    KuduTable table = syncClient.openTable(tableName);
+    client.createTable(tableName, basicSchema, getBasicTableOptionsWithNonCoveredRange());
+    KuduTable table = client.openTable(tableName);
 
     List<LocatedTablet> tablets;
 
@@ -347,9 +369,9 @@ public class TestKuduTable extends BaseKuduTest {
 
   @Test(timeout = 100000)
   public void testAlterTableNonCoveringRange() throws Exception {
-    syncClient.createTable(tableName, basicSchema, getBasicTableOptionsWithNonCoveredRange());
-    KuduTable table = syncClient.openTable(tableName);
-    KuduSession session = syncClient.newSession();
+    client.createTable(tableName, basicSchema, getBasicTableOptionsWithNonCoveredRange());
+    KuduTable table = client.openTable(tableName);
+    KuduSession session = client.newSession();
 
     AlterTableOptions ato = new AlterTableOptions();
     PartialRow bLowerBound = BASIC_SCHEMA.newPartialRow();
@@ -357,7 +379,7 @@ public class TestKuduTable extends BaseKuduTest {
     PartialRow bUpperBound = BASIC_SCHEMA.newPartialRow();
     bUpperBound.addInt("key", 400);
     ato.addRangePartition(bLowerBound, bUpperBound);
-    syncClient.alterTable(tableName, ato);
+    client.alterTable(tableName, ato);
 
     Insert insert = createBasicSchemaInsert(table, 301);
     session.apply(insert);
@@ -379,7 +401,7 @@ public class TestKuduTable extends BaseKuduTest {
     bUpperBound = BASIC_SCHEMA.newPartialRow();
     bUpperBound.addInt("key", 300);
     ato.dropRangePartition(bLowerBound, bUpperBound);
-    syncClient.alterTable(tableName, ato);
+    client.alterTable(tableName, ato);
 
     insert = createBasicSchemaInsert(table, 202);
     OperationResponse response = session.apply(insert);
@@ -433,10 +455,10 @@ public class TestKuduTable extends BaseKuduTest {
       builder.addRangePartition(lower, basicSchema.newPartialRow());
     }
 
-    syncClient.createTable(tableName, basicSchema, builder);
+    client.createTable(tableName, basicSchema, builder);
     assertEquals(
         expected,
-        syncClient.openTable(tableName).getFormattedRangePartitions(10000));
+        client.openTable(tableName).getFormattedRangePartitions(10000));
   }
 
   @Test(timeout = 100000)
@@ -482,10 +504,10 @@ public class TestKuduTable extends BaseKuduTest {
                                 RangePartitionBound.INCLUSIVE_BOUND);
     }
 
-    syncClient.createTable(tableName, schema, builder);
+    client.createTable(tableName, schema, builder);
     assertEquals(
         expected,
-        syncClient.openTable(tableName).getFormattedRangePartitions(10000));
+        client.openTable(tableName).getFormattedRangePartitions(10000));
   }
 
   @Test(timeout = 100000)
@@ -527,20 +549,20 @@ public class TestKuduTable extends BaseKuduTest {
       builder.addRangePartition(lower, schema.newPartialRow());
     }
 
-    syncClient.createTable(tableName, schema, builder);
+    client.createTable(tableName, schema, builder);
     assertEquals(
         expected,
-        syncClient.openTable(tableName).getFormattedRangePartitions(10000));
+        client.openTable(tableName).getFormattedRangePartitions(10000));
   }
 
   @Test(timeout = 100000)
   public void testFormatRangePartitionsUnbounded() throws Exception {
     CreateTableOptions builder = getBasicCreateTableOptions();
-    syncClient.createTable(tableName, basicSchema, builder);
+    client.createTable(tableName, basicSchema, builder);
 
     assertEquals(
         ImmutableList.of("UNBOUNDED"),
-        syncClient.openTable(tableName).getFormattedRangePartitions(10000));
+        client.openTable(tableName).getFormattedRangePartitions(10000));
   }
 
   private KuduTable createTableWithSplitsAndTest(String tableNamePrefix, int splitsCount)
@@ -555,7 +577,7 @@ public class TestKuduTable extends BaseKuduTest {
         builder.addSplitRow(row);
       }
     }
-    KuduTable table = createTable(newTableName, BASIC_SCHEMA, builder);
+    KuduTable table = client.createTable(newTableName, BASIC_SCHEMA, builder);
 
     List<LocatedTablet> tablets = table.getTabletsLocations(DEFAULT_SLEEP);
     assertEquals(splitsCount + 1, tablets.size());
@@ -587,7 +609,7 @@ public class TestKuduTable extends BaseKuduTest {
     builder.addRangePartition(bottom, middle);
     builder.addRangePartition(middle, upper);
 
-    KuduTable table = createTable(tableName, schema, builder);
+    KuduTable table = client.createTable(tableName, schema, builder);
 
     List<Partition> rangePartitions =
         table.getRangePartitions(client.getDefaultOperationTimeoutMs());
@@ -611,7 +633,7 @@ public class TestKuduTable extends BaseKuduTest {
   @Test(timeout = 100000)
   public void testGetRangePartitionsUnbounded() throws Exception {
     CreateTableOptions builder = getBasicCreateTableOptions();
-    KuduTable table = createTable(tableName, BASIC_SCHEMA, builder);
+    KuduTable table = client.createTable(tableName, BASIC_SCHEMA, builder);
 
     List<Partition> rangePartitions =
         table.getRangePartitions(client.getDefaultOperationTimeoutMs());
@@ -623,12 +645,12 @@ public class TestKuduTable extends BaseKuduTest {
 
   @Test(timeout = 100000)
   public void testAlterNoWait() throws Exception {
-    createTable(tableName, basicSchema, getBasicCreateTableOptions());
+    client.createTable(tableName, basicSchema, getBasicCreateTableOptions());
 
     String oldName = "column2_i";
     for (int i = 0; i < 10; i++) {
       String newName = String.format("foo%d", i);
-      syncClient.alterTable(tableName, new AlterTableOptions()
+      client.alterTable(tableName, new AlterTableOptions()
           .renameColumn(oldName, newName)
           .setWait(false));
 
@@ -636,7 +658,7 @@ public class TestKuduTable extends BaseKuduTest {
       // to still see 'oldName' and not yet see 'newName'. However, this is
       // timing dependent: if the alter finishes before we reload the schema,
       // loop and try again.
-      KuduTable table = syncClient.openTable(tableName);
+      KuduTable table = client.openTable(tableName);
       try {
         table.getSchema().getColumn(oldName);
       } catch (IllegalArgumentException e) {
@@ -652,8 +674,8 @@ public class TestKuduTable extends BaseKuduTest {
 
       // After waiting for the alter to finish and reloading the schema,
       // 'newName' should be visible and 'oldName' should be gone.
-      assertTrue(syncClient.isAlterTableDone(tableName));
-      table = syncClient.openTable(tableName);
+      assertTrue(client.isAlterTableDone(tableName));
+      table = client.openTable(tableName);
       try {
         table.getSchema().getColumn(oldName);
         fail(String.format("Old column name %s should not be visible", oldName));
@@ -673,8 +695,8 @@ public class TestKuduTable extends BaseKuduTest {
         String tableName = "testNumReplicas" + "-" + i;
         CreateTableOptions options = getBasicCreateTableOptions();
         options.setNumReplicas(i);
-        createTable(tableName, basicSchema, options);
-        KuduTable table = syncClient.openTable(tableName);
+        client.createTable(tableName, basicSchema, options);
+        KuduTable table = client.openTable(tableName);
         assertEquals(i, table.getNumReplicas());
       }
     }