kudu-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From granthe...@apache.org
Subject [4/6] kudu git commit: [test] Move BaseKuduTest to a Junit Rule
Date Tue, 02 Oct 2018 19:01:55 GMT
[test] Move BaseKuduTest to a Junit Rule

This patch moves all of BaseKuduTest to a Junit Rule.
This avoids inheritance for tests and allows more
interesting test composition.

Additionally I added method level annotations
that can be used to modify the Kudu mini cluster
configs on a per test method basis. I changed
the tests in TestKuduClient to use the annotations,
and will migrate other tests in follow on patches.

Change-Id: I32c83b47a576377b924ea41dbeaf78ce2b75e4c4
Reviewed-on: http://gerrit.cloudera.org:8080/11547
Tested-by: Kudu Jenkins
Reviewed-by: Adar Dembo <adar@cloudera.com>


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

Branch: refs/heads/master
Commit: dc8ae79961f71b8bdc344781fc89d38d94152fc4
Parents: 6466c0d
Author: Grant Henke <granthenke@apache.org>
Authored: Sun Sep 30 20:00:40 2018 -0500
Committer: Grant Henke <granthenke@apache.org>
Committed: Tue Oct 2 19:00:56 2018 +0000

----------------------------------------------------------------------
 .../kudu/mapreduce/tools/ITExportCsv.java       |  13 +-
 .../kudu/mapreduce/tools/ITImportCsv.java       |  18 +-
 .../kudu/mapreduce/tools/ITImportParquet.java   |  18 +-
 .../tools/ITImportParquetPreCheck.java          |  15 +-
 .../tools/ITIntegrationTestBigLinkedList.java   |  10 +-
 .../kudu/mapreduce/tools/ITRowCounter.java      |  13 +-
 .../org/apache/kudu/client/AsyncKuduClient.java |   3 +-
 .../org/apache/kudu/client/LocatedTablet.java   |   3 +-
 .../org/apache/kudu/client/RemoteTablet.java    |   2 +-
 .../org/apache/kudu/client/BaseKuduTest.java    | 376 ----------------
 .../java/org/apache/kudu/client/ITClient.java   |  19 +-
 .../org/apache/kudu/client/ITClientStress.java  |  23 +-
 .../kudu/client/ITNonFaultTolerantScanner.java  |   2 +-
 .../kudu/client/ITScannerMultiTablet.java       |  25 +-
 .../org/apache/kudu/client/MiniKuduCluster.java |  33 +-
 .../org/apache/kudu/client/TestAlterTable.java  |  73 +--
 .../apache/kudu/client/TestAsyncKuduClient.java |  55 ++-
 .../kudu/client/TestAsyncKuduSession.java       |  31 +-
 .../kudu/client/TestAuthnTokenReacquire.java    |  66 ++-
 .../client/TestAuthnTokenReacquireOpen.java     |  65 ++-
 .../kudu/client/TestClientFailoverSupport.java  |  39 +-
 .../kudu/client/TestConnectToCluster.java       |  10 +-
 .../apache/kudu/client/TestConnectionCache.java |   7 +-
 .../kudu/client/TestFlexiblePartitioning.java   |  43 +-
 .../apache/kudu/client/TestHandleTooBusy.java   |  33 +-
 .../org/apache/kudu/client/TestHybridTime.java  |  39 +-
 .../org/apache/kudu/client/TestKeyEncoding.java |  21 +-
 .../org/apache/kudu/client/TestKuduClient.java  | 226 +++++-----
 .../org/apache/kudu/client/TestKuduSession.java |  74 +--
 .../org/apache/kudu/client/TestKuduTable.java   | 132 +++---
 .../apache/kudu/client/TestLeaderFailover.java  |  21 +-
 .../apache/kudu/client/TestMasterFailover.java  |  28 +-
 .../apache/kudu/client/TestMiniKuduCluster.java |  17 +-
 .../kudu/client/TestMultipleLeaderFailover.java |  22 +-
 .../org/apache/kudu/client/TestNegotiation.java |  15 +-
 .../apache/kudu/client/TestPartitionPruner.java |  51 ++-
 .../org/apache/kudu/client/TestRowErrors.java   |  24 +-
 .../org/apache/kudu/client/TestRowResult.java   |  20 +-
 .../apache/kudu/client/TestScanPredicate.java   |  85 ++--
 .../org/apache/kudu/client/TestScanToken.java   |  75 ++--
 .../kudu/client/TestScannerMultiTablet.java     |  94 ++--
 .../org/apache/kudu/client/TestSecurity.java    |  11 +-
 .../client/TestSecurityContextRealUser.java     |  47 +-
 .../org/apache/kudu/client/TestStatistics.java  |  15 +-
 .../org/apache/kudu/client/TestTimeouts.java    |  13 +-
 .../org/apache/kudu/test/KuduTestHarness.java   | 445 +++++++++++++++++++
 .../sink/AvroKuduOperationsProducerTest.java    |  13 +-
 .../sink/KeyedKuduOperationsProducerTest.java   |  16 +-
 .../apache/kudu/flume/sink/KuduSinkTest.java    |  19 +-
 ...expKuduOperationsProducerParseErrorTest.java |   9 +-
 .../sink/RegexpKuduOperationsProducerTest.java  |  13 +-
 .../kudu/flume/sink/SecureKuduSinkTest.java     |  25 +-
 .../apache/kudu/mapreduce/ITInputFormatJob.java |  17 +-
 .../kudu/mapreduce/ITKuduTableInputFormat.java  |  17 +-
 .../kudu/mapreduce/ITKuduTableOutputFormat.java |  14 +-
 .../kudu/mapreduce/ITOutputFormatJob.java       |  18 +-
 .../apache/kudu/spark/kudu/KuduTestSuite.scala  |   4 +-
 57 files changed, 1549 insertions(+), 1086 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITExportCsv.java
----------------------------------------------------------------------
diff --git a/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITExportCsv.java b/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITExportCsv.java
index 16e548e..e44876d 100644
--- a/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITExportCsv.java
+++ b/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITExportCsv.java
@@ -17,6 +17,7 @@
 
 package org.apache.kudu.mapreduce.tools;
 
+import static org.apache.kudu.test.KuduTestHarness.DEFAULT_SLEEP;
 import static org.apache.kudu.util.ClientTestUtil.createFourTabletsTableWithNineRows;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -29,20 +30,24 @@ import org.apache.commons.io.IOUtils;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.mapreduce.Job;
 import org.apache.hadoop.util.GenericOptionsParser;
+import org.apache.kudu.test.KuduTestHarness;
 import org.junit.After;
+import org.junit.Rule;
 import org.junit.Test;
 
-import org.apache.kudu.client.BaseKuduTest;
 import org.apache.kudu.mapreduce.CommandLineParser;
 import org.apache.kudu.mapreduce.HadoopTestingUtility;
 
-public class ITExportCsv extends BaseKuduTest {
+public class ITExportCsv {
 
   private static final String TABLE_NAME =
     ITExportCsv.class.getName() + "-" + System.currentTimeMillis();
 
   private static final HadoopTestingUtility HADOOP_UTIL = new HadoopTestingUtility();
 
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
   @After
   public void tearDown() throws Exception {
     HADOOP_UTIL.cleanup();
@@ -55,9 +60,9 @@ public class ITExportCsv extends BaseKuduTest {
       HADOOP_UTIL.setupAndGetTestDir(ITExportCsv.class.getName(), conf).getAbsolutePath();
 
     // create a table with on empty tablet and 3 tablets of 3 rows each.
-    createFourTabletsTableWithNineRows(client, TABLE_NAME, DEFAULT_SLEEP);
+    createFourTabletsTableWithNineRows(harness.getAsyncClient(), TABLE_NAME, DEFAULT_SLEEP);
     String[] args = new String[] {
-      "-D" + CommandLineParser.MASTER_ADDRESSES_KEY + "=" + getMasterAddressesAsString(),
+      "-D" + CommandLineParser.MASTER_ADDRESSES_KEY + "=" + harness.getMasterAddressesAsString(),
       "*", TABLE_NAME, testHome + "/exportdata"};
 
     GenericOptionsParser parser = new GenericOptionsParser(conf, args);

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportCsv.java
----------------------------------------------------------------------
diff --git a/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportCsv.java b/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportCsv.java
index 670880e..969f521 100644
--- a/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportCsv.java
+++ b/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportCsv.java
@@ -32,20 +32,21 @@ import com.google.common.collect.ImmutableList;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.mapreduce.Job;
 import org.apache.hadoop.util.GenericOptionsParser;
+import org.apache.kudu.test.KuduTestHarness;
 import org.junit.After;
 import org.junit.Before;
+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.apache.kudu.client.BaseKuduTest;
 import org.apache.kudu.client.KuduTable;
 import org.apache.kudu.client.CreateTableOptions;
 import org.apache.kudu.mapreduce.CommandLineParser;
 import org.apache.kudu.mapreduce.HadoopTestingUtility;
 
-public class ITImportCsv extends BaseKuduTest {
+public class ITImportCsv {
 
   private static final String TABLE_NAME =
       ITImportCsv.class.getName() + "-" + System.currentTimeMillis();
@@ -71,10 +72,13 @@ public class ITImportCsv extends BaseKuduTest {
     schema = new Schema(columns);
   }
 
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
   @Before
   public void setUp() throws Exception {
-    createTable(TABLE_NAME, schema,
-                new CreateTableOptions().setRangePartitionColumns(ImmutableList.of("key")));
+    harness.getClient().createTable(TABLE_NAME, schema,
+        new CreateTableOptions().setRangePartitionColumns(ImmutableList.of("key")));
   }
 
   @After
@@ -99,16 +103,16 @@ public class ITImportCsv extends BaseKuduTest {
     }
     sb.deleteCharAt(sb.length() - 1);
     String[] args = new String[] {
-        "-D" + CommandLineParser.MASTER_ADDRESSES_KEY + "=" + getMasterAddressesAsString(),
+        "-D" + CommandLineParser.MASTER_ADDRESSES_KEY + "=" + harness.getMasterAddressesAsString(),
         sb.toString(), TABLE_NAME, data.toString()};
 
     GenericOptionsParser parser = new GenericOptionsParser(conf, args);
     Job job = ImportCsv.createSubmittableJob(parser.getConfiguration(), parser.getRemainingArgs());
     assertTrue("Test job did not end properly", job.waitForCompletion(true));
 
-    KuduTable openTable = openTable(TABLE_NAME);
+    KuduTable openTable = harness.getClient().openTable(TABLE_NAME);
     assertEquals(1, job.getCounters().findCounter(ImportCsv.Counters.BAD_LINES).getValue());
-    assertEquals(3, countRowsInScan(client.newScannerBuilder(openTable).build()));
+    assertEquals(3, countRowsInScan(harness.getAsyncClient().newScannerBuilder(openTable).build()));
     assertEquals("INT32 key=1, INT32 column1_i=3, DOUBLE column2_d=2.3, STRING column3_s=some " +
       "string, BOOL column4_b=true", scanTableToStrings(openTable).get(0));
   }

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportParquet.java
----------------------------------------------------------------------
diff --git a/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportParquet.java b/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportParquet.java
index 7156d3b..2599426 100644
--- a/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportParquet.java
+++ b/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportParquet.java
@@ -33,6 +33,7 @@ import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.mapreduce.Job;
 import org.apache.hadoop.util.GenericOptionsParser;
 import org.apache.kudu.client.KuduTable;
+import org.apache.kudu.test.KuduTestHarness;
 import org.apache.parquet.column.ParquetProperties;
 import org.apache.parquet.example.data.Group;
 import org.apache.parquet.example.data.simple.SimpleGroupFactory;
@@ -41,17 +42,17 @@ import org.apache.parquet.hadoop.example.GroupWriteSupport;
 import org.apache.parquet.schema.MessageType;
 import org.junit.After;
 import org.junit.Before;
+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.apache.kudu.client.BaseKuduTest;
 import org.apache.kudu.client.CreateTableOptions;
 import org.apache.kudu.mapreduce.CommandLineParser;
 import org.apache.kudu.mapreduce.HadoopTestingUtility;
 
-public class ITImportParquet extends BaseKuduTest {
+public class ITImportParquet {
 
   private static final String TABLE_NAME =
     ITImportParquet.class.getName() + "-" + System.currentTimeMillis();
@@ -77,9 +78,12 @@ public class ITImportParquet extends BaseKuduTest {
     schema = new Schema(columns);
   }
 
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
   @Before
   public void setUp() throws Exception {
-    createTable(TABLE_NAME, schema,
+    harness.getClient().createTable(TABLE_NAME, schema,
       new CreateTableOptions().setRangePartitionColumns(ImmutableList.of("key")));
   }
 
@@ -104,16 +108,16 @@ public class ITImportParquet extends BaseKuduTest {
       sb.append(",");
     }
     sb.deleteCharAt(sb.length() - 1);
-    String[] args = new String[] { "-D" + CommandLineParser.MASTER_ADDRESSES_KEY + "=" + getMasterAddressesAsString(),
-      TABLE_NAME, data.toString()};
+    String[] args = new String[] { "-D" + CommandLineParser.MASTER_ADDRESSES_KEY + "="
+        + harness.getMasterAddressesAsString(), TABLE_NAME, data.toString()};
 
     GenericOptionsParser parser = new GenericOptionsParser(conf, args);
     Job job = ImportParquet.createSubmittableJob(parser.getConfiguration(), parser.getRemainingArgs());
     assertTrue("Test job did not end properly", job.waitForCompletion(true));
 
-    KuduTable openTable = openTable(TABLE_NAME);
+    KuduTable openTable = harness.getClient().openTable(TABLE_NAME);
     assertEquals(4, countRowsInScan(
-      client.newScannerBuilder(openTable).build()));
+      harness.getAsyncClient().newScannerBuilder(openTable).build()));
     assertEquals("INT32 key=1, INT32 column1_i=3, DOUBLE column2_d=2.3, STRING column3_s=some string, " +
       "BOOL column4_b=true",scanTableToStrings(openTable).get(0));
   }

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportParquetPreCheck.java
----------------------------------------------------------------------
diff --git a/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportParquetPreCheck.java b/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportParquetPreCheck.java
index c286edb..34625e0 100644
--- a/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportParquetPreCheck.java
+++ b/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITImportParquetPreCheck.java
@@ -31,6 +31,7 @@ import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.mapreduce.Job;
 import org.apache.hadoop.util.GenericOptionsParser;
 import org.apache.kudu.client.KuduTable;
+import org.apache.kudu.test.KuduTestHarness;
 import org.apache.parquet.column.ParquetProperties;
 import org.apache.parquet.example.data.Group;
 import org.apache.parquet.example.data.simple.SimpleGroupFactory;
@@ -46,12 +47,11 @@ import org.junit.rules.ExpectedException;
 import org.apache.kudu.ColumnSchema;
 import org.apache.kudu.Schema;
 import org.apache.kudu.Type;
-import org.apache.kudu.client.BaseKuduTest;
 import org.apache.kudu.client.CreateTableOptions;
 import org.apache.kudu.mapreduce.CommandLineParser;
 import org.apache.kudu.mapreduce.HadoopTestingUtility;
 
-public class ITImportParquetPreCheck extends BaseKuduTest {
+public class ITImportParquetPreCheck {
 
   private static final String TABLE_NAME =
     ITImportParquet.class.getName() + "-" + System.currentTimeMillis();
@@ -78,11 +78,14 @@ public class ITImportParquetPreCheck extends BaseKuduTest {
   }
 
   @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
+  @Rule
   public ExpectedException thrown = ExpectedException.none();
 
   @Before
   public void setUp() throws Exception {
-    createTable(TABLE_NAME, schema,
+    harness.getClient().createTable(TABLE_NAME, schema,
       new CreateTableOptions().setRangePartitionColumns(ImmutableList.of("key")));
   }
 
@@ -108,7 +111,7 @@ public class ITImportParquetPreCheck extends BaseKuduTest {
     }
     sb.deleteCharAt(sb.length() - 1);
     String[] args = new String[] { "-D" + CommandLineParser.MASTER_ADDRESSES_KEY + "=" +
-      getMasterAddressesAsString(), TABLE_NAME, data.toString()};
+      harness.getMasterAddressesAsString(), TABLE_NAME, data.toString()};
 
     thrown.expect(IllegalArgumentException.class);
     thrown.expectMessage("The column column1_i does not exist in Parquet schema");
@@ -117,8 +120,8 @@ public class ITImportParquetPreCheck extends BaseKuduTest {
     Job job = ImportParquet.createSubmittableJob(parser.getConfiguration(), parser.getRemainingArgs());
     job.waitForCompletion(true);
 
-    KuduTable openTable = openTable(TABLE_NAME);
-    assertEquals(0, countRowsInScan(client.newScannerBuilder(openTable).build()));
+    KuduTable openTable = harness.getClient().openTable(TABLE_NAME);
+    assertEquals(0, countRowsInScan(harness.getAsyncClient().newScannerBuilder(openTable).build()));
   }
 
   private void writeParquetFile(Path data,Configuration conf) throws IOException {

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITIntegrationTestBigLinkedList.java
----------------------------------------------------------------------
diff --git a/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITIntegrationTestBigLinkedList.java b/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITIntegrationTestBigLinkedList.java
index a7d1973..1e72403 100644
--- a/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITIntegrationTestBigLinkedList.java
+++ b/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITIntegrationTestBigLinkedList.java
@@ -19,18 +19,22 @@ package org.apache.kudu.mapreduce.tools;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.util.ToolRunner;
+import org.apache.kudu.test.KuduTestHarness;
 import org.junit.After;
 import org.junit.Assert;
+import org.junit.Rule;
 import org.junit.Test;
 
-import org.apache.kudu.client.BaseKuduTest;
 import org.apache.kudu.mapreduce.CommandLineParser;
 import org.apache.kudu.mapreduce.HadoopTestingUtility;
 
-public class ITIntegrationTestBigLinkedList extends BaseKuduTest {
+public class ITIntegrationTestBigLinkedList {
 
   private static final HadoopTestingUtility HADOOP_UTIL = new HadoopTestingUtility();
 
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
   @After
   public void tearDown() throws Exception {
     HADOOP_UTIL.cleanup();
@@ -43,7 +47,7 @@ public class ITIntegrationTestBigLinkedList extends BaseKuduTest {
         ITIntegrationTestBigLinkedList.class.getName(),conf).getAbsolutePath();
 
     String[] args = new String[] {
-        "-D" + CommandLineParser.MASTER_ADDRESSES_KEY + "=" + getMasterAddressesAsString(),
+        "-D" + CommandLineParser.MASTER_ADDRESSES_KEY + "=" + harness.getMasterAddressesAsString(),
         "Loop",
         "2", // Two iterations
         "1", // 1 mapper

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITRowCounter.java
----------------------------------------------------------------------
diff --git a/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITRowCounter.java b/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITRowCounter.java
index 011921b..3b5f01b 100644
--- a/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITRowCounter.java
+++ b/java/kudu-client-tools/src/test/java/org/apache/kudu/mapreduce/tools/ITRowCounter.java
@@ -17,6 +17,7 @@
 
 package org.apache.kudu.mapreduce.tools;
 
+import static org.apache.kudu.test.KuduTestHarness.DEFAULT_SLEEP;
 import static org.apache.kudu.util.ClientTestUtil.createFourTabletsTableWithNineRows;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -24,20 +25,24 @@ import static org.junit.Assert.assertTrue;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.mapreduce.Job;
 import org.apache.hadoop.util.GenericOptionsParser;
+import org.apache.kudu.test.KuduTestHarness;
 import org.junit.After;
+import org.junit.Rule;
 import org.junit.Test;
 
-import org.apache.kudu.client.BaseKuduTest;
 import org.apache.kudu.mapreduce.CommandLineParser;
 import org.apache.kudu.mapreduce.HadoopTestingUtility;
 
-public class ITRowCounter extends BaseKuduTest {
+public class ITRowCounter {
 
   private static final String TABLE_NAME =
       ITRowCounter.class.getName() + "-" + System.currentTimeMillis();
 
   private static final HadoopTestingUtility HADOOP_UTIL = new HadoopTestingUtility();
 
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
   @After
   public void tearDown() throws Exception {
     HADOOP_UTIL.cleanup();
@@ -48,10 +53,10 @@ public class ITRowCounter extends BaseKuduTest {
     Configuration conf = new Configuration();
     HADOOP_UTIL.setupAndGetTestDir(ITRowCounter.class.getName(), conf).getAbsolutePath();
 
-    createFourTabletsTableWithNineRows(client, TABLE_NAME, DEFAULT_SLEEP);
+    createFourTabletsTableWithNineRows(harness.getAsyncClient(), TABLE_NAME, DEFAULT_SLEEP);
 
     String[] args = new String[] {
-        "-D" + CommandLineParser.MASTER_ADDRESSES_KEY + "=" + getMasterAddressesAsString(), TABLE_NAME};
+        "-D" + CommandLineParser.MASTER_ADDRESSES_KEY + "=" + harness.getMasterAddressesAsString(), TABLE_NAME};
     GenericOptionsParser parser = new GenericOptionsParser(conf, args);
     Job job = RowCounter.createSubmittableJob(parser.getConfiguration(), parser.getRemainingArgs());
     assertTrue("Job did not end properly", job.waitForCompletion(true));

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduClient.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduClient.java b/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduClient.java
index 3407ad9..b0ed000 100644
--- a/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduClient.java
+++ b/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduClient.java
@@ -1584,7 +1584,8 @@ public class AsyncKuduClient implements AutoCloseable {
    * fill a {@link Master.GetTabletLocationsResponsePB} object.
    * @return An initialized Deferred object to hold the response.
    */
-  Deferred<Master.GetTableLocationsResponsePB> getMasterTableLocationsPB(KuduRpc<?> parentRpc) {
+  @InterfaceAudience.LimitedPrivate("Test")
+  public Deferred<Master.GetTableLocationsResponsePB> getMasterTableLocationsPB(KuduRpc<?> parentRpc) {
     // TODO(todd): stop using this 'masterTable' hack.
     return ConnectToCluster.run(masterTable, masterAddresses, parentRpc,
         defaultAdminOperationTimeoutMs, Connection.CredentialsPolicy.ANY_CREDENTIALS).addCallback(

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/main/java/org/apache/kudu/client/LocatedTablet.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/main/java/org/apache/kudu/client/LocatedTablet.java b/java/kudu-client/src/main/java/org/apache/kudu/client/LocatedTablet.java
index 7539d8a..655f800 100644
--- a/java/kudu-client/src/main/java/org/apache/kudu/client/LocatedTablet.java
+++ b/java/kudu-client/src/main/java/org/apache/kudu/client/LocatedTablet.java
@@ -41,7 +41,8 @@ public class LocatedTablet {
 
   private final List<Replica> replicas;
 
-  LocatedTablet(RemoteTablet tablet) {
+  @InterfaceAudience.LimitedPrivate("Tests")
+  public LocatedTablet(RemoteTablet tablet) {
     partition = tablet.getPartition();
     tabletId = tablet.getTabletIdAsBytes();
     replicas = tablet.getReplicas();

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/main/java/org/apache/kudu/client/RemoteTablet.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/main/java/org/apache/kudu/client/RemoteTablet.java b/java/kudu-client/src/main/java/org/apache/kudu/client/RemoteTablet.java
index a8db63d..ed8c5cc 100644
--- a/java/kudu-client/src/main/java/org/apache/kudu/client/RemoteTablet.java
+++ b/java/kudu-client/src/main/java/org/apache/kudu/client/RemoteTablet.java
@@ -53,7 +53,7 @@ import org.apache.kudu.master.Master;
  */
 @InterfaceAudience.Private
 @InterfaceStability.Unstable
-class RemoteTablet implements Comparable<RemoteTablet> {
+public class RemoteTablet implements Comparable<RemoteTablet> {
 
   private static final Logger LOG = LoggerFactory.getLogger(RemoteTablet.class);
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/BaseKuduTest.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/BaseKuduTest.java b/java/kudu-client/src/test/java/org/apache/kudu/client/BaseKuduTest.java
deleted file mode 100644
index c410cf7..0000000
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/BaseKuduTest.java
+++ /dev/null
@@ -1,376 +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.kudu.client;
-
-import static org.apache.kudu.util.ClientTestUtil.getBasicSchema;
-import static org.apache.kudu.util.ClientTestUtil.getSchemaWithAllTypes;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
-
-import com.google.common.base.Stopwatch;
-import com.stumbleupon.async.Deferred;
-import org.apache.kudu.junit.RetryRule;
-import org.apache.kudu.util.RandomUtils;
-import org.apache.yetus.audience.InterfaceAudience;
-import org.apache.yetus.audience.InterfaceStability;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.kudu.Common.HostPortPB;
-import org.apache.kudu.Schema;
-import org.apache.kudu.client.LocatedTablet.Replica;
-import org.apache.kudu.master.Master;
-
-@InterfaceAudience.Private
-@InterfaceStability.Unstable
-public class BaseKuduTest {
-
-  protected static final Logger LOG = LoggerFactory.getLogger(BaseKuduTest.class);
-
-  // Default timeout/sleep interval for various client operations, waiting for various jobs/threads
-  // to complete, etc.
-  protected static final int DEFAULT_SLEEP = 50000;
-
-  private final Random randomForTSRestart = RandomUtils.getRandom();
-
-  private static final int NUM_MASTERS = 3;
-  private static final int NUM_TABLET_SERVERS = 3;
-
-  private MiniKuduCluster miniCluster;
-
-  // We create both versions of the client for ease of use.
-  protected AsyncKuduClient client;
-  protected KuduClient syncClient;
-  protected static final Schema basicSchema = getBasicSchema();
-  protected static final Schema allTypesSchema = getSchemaWithAllTypes();
-
-  // Add a rule to rerun tests. We use this with Gradle because it doesn't support
-  // Surefire/Failsafe rerunFailingTestsCount like Maven does.
-  @Rule
-  public RetryRule retryRule = new RetryRule();
-
-  @Before
-  public void setUpBase() throws Exception {
-    FakeDNS.getInstance().install();
-
-    LOG.info("Creating a new MiniKuduCluster...");
-
-    miniCluster = getMiniClusterBuilder().build();
-
-    LOG.info("Creating a new Kudu client...");
-    client = new AsyncKuduClient.AsyncKuduClientBuilder(miniCluster.getMasterAddressesAsString())
-        .defaultAdminOperationTimeoutMs(DEFAULT_SLEEP)
-        .build();
-    syncClient = client.syncClient();
-  }
-
-  @After
-  public void tearDownBase() throws Exception {
-    try {
-      if (client != null) {
-        syncClient.shutdown();
-        // No need to explicitly shutdown the async client,
-        // shutting down the async client effectively does that.
-      }
-    } finally {
-      if (miniCluster != null) {
-        miniCluster.shutdown();
-      }
-    }
-  }
-
-  /**
-   * Returns a MiniKuduClusterBuilder to use when starting the MiniKuduCluster.
-   * Override this method to adjust to the MiniKuduClusterBuilder settings.
-   */
-  protected MiniKuduCluster.MiniKuduClusterBuilder getMiniClusterBuilder() {
-    return new MiniKuduCluster.MiniKuduClusterBuilder()
-        .numMasters(NUM_MASTERS)
-        .numTservers(NUM_TABLET_SERVERS);
-  }
-
-  protected KuduTable createTable(String tableName, Schema schema,
-                                         CreateTableOptions builder) throws KuduException {
-    LOG.info("Creating table: {}", tableName);
-    return client.syncClient().createTable(tableName, schema, builder);
-  }
-
-  /**
-   * Helper method to open a table. It sets the default sleep time when joining on the Deferred.
-   * @param name Name of the table
-   * @return A KuduTable
-   * @throws Exception MasterErrorException if the table doesn't exist
-   */
-  protected KuduTable openTable(String name) throws Exception {
-    Deferred<KuduTable> d = client.openTable(name);
-    return d.join(DEFAULT_SLEEP);
-  }
-
-  /**
-   * Helper method to easily kill a tablet server that serves the given table's only tablet's
-   * leader. The currently running test case will be failed if there's more than one tablet,
-   * if the tablet has no leader after some retries, or if the tablet server was already killed.
-   *
-   * This method is thread-safe.
-   * @param table a KuduTable which will get its single tablet's leader killed.
-   * @throws Exception
-   */
-  protected void killTabletLeader(KuduTable table) throws Exception {
-    List<LocatedTablet> tablets = table.getTabletsLocations(DEFAULT_SLEEP);
-    if (tablets.isEmpty() || tablets.size() > 1) {
-      fail("Currently only support killing leaders for tables containing 1 tablet, table " +
-      table.getName() + " has " + tablets.size());
-    }
-    LocatedTablet tablet = tablets.get(0);
-    if (tablet.getReplicas().size() == 1) {
-      fail("Table " + table.getName() + " only has 1 tablet, please enable replication");
-    }
-
-    HostAndPort hp = findLeaderTabletServer(tablet);
-    miniCluster.killTabletServer(hp);
-  }
-
-  /**
-   * Helper method to kill a tablet server that serves the given tablet's
-   * leader. The currently running test case will be failed if the tablet has no
-   * leader after some retries, or if the tablet server was already killed.
-   *
-   * This method is thread-safe.
-   * @param tablet a RemoteTablet which will get its leader killed
-   * @throws Exception
-   */
-  protected void killTabletLeader(RemoteTablet tablet) throws Exception {
-    killTabletLeader(new LocatedTablet(tablet));
-  }
-
-  /**
-   * Helper method to kill a tablet server that serves the given tablet's
-   * leader. The currently running test case will be failed if the tablet has no
-   * leader after some retries, or if the tablet server was already killed.
-   *
-   * This method is thread-safe.
-   * @param tablet a LocatedTablet which will get its leader killed
-   * @throws Exception
-   */
-  protected void killTabletLeader(LocatedTablet tablet) throws Exception {
-    HostAndPort hp = findLeaderTabletServer(tablet);
-    miniCluster.killTabletServer(hp);
-  }
-
-  /**
-   * Finds the RPC port of the given tablet's leader tserver.
-   * @param tablet a LocatedTablet
-   * @return the host and port of the given tablet's leader tserver
-   * @throws Exception if we are unable to find the leader tserver
-   */
-  protected HostAndPort findLeaderTabletServer(LocatedTablet tablet)
-      throws Exception {
-    LocatedTablet.Replica leader = null;
-    DeadlineTracker deadlineTracker = new DeadlineTracker();
-    deadlineTracker.setDeadline(DEFAULT_SLEEP);
-    while (leader == null) {
-      if (deadlineTracker.timedOut()) {
-        fail("Timed out while trying to find a leader for this table");
-      }
-
-      leader = tablet.getLeaderReplica();
-      if (leader == null) {
-        LOG.info("Sleeping while waiting for a tablet LEADER to arise, currently slept {} ms",
-            deadlineTracker.getElapsedMillis());
-        Thread.sleep(50);
-      }
-    }
-    return new HostAndPort(leader.getRpcHost(), leader.getRpcPort());
-  }
-
-  /**
-   * Helper method to easily kill the leader master.
-   *
-   * This method is thread-safe.
-   * @throws Exception if there is an error finding or killing the leader master.
-   */
-  protected void killLeaderMasterServer() throws Exception {
-    HostAndPort hp = findLeaderMasterServer();
-    miniCluster.killMasterServer(hp);
-  }
-
-  /**
-   * Find the host and port of the leader master.
-   * @return the host and port of the leader master
-   * @throws Exception if we are unable to find the leader master
-   */
-  protected HostAndPort findLeaderMasterServer() throws Exception {
-    Stopwatch sw = Stopwatch.createStarted();
-    while (sw.elapsed(TimeUnit.MILLISECONDS) < DEFAULT_SLEEP) {
-      Deferred<Master.GetTableLocationsResponsePB> masterLocD =
-          client.getMasterTableLocationsPB(null);
-      Master.GetTableLocationsResponsePB r = masterLocD.join(DEFAULT_SLEEP);
-      HostPortPB pb = r.getTabletLocations(0)
-          .getReplicas(0)
-          .getTsInfo()
-          .getRpcAddresses(0);
-      if (pb.getPort() != -1) {
-        return new HostAndPort(pb.getHost(), pb.getPort());
-      }
-    }
-    throw new IOException(String.format("No leader master found after %d ms", DEFAULT_SLEEP));
-  }
-
-  /**
-   * Picks at random a tablet server that serves tablets from the passed table and restarts it.
-   * @param table table to query for a TS to restart
-   * @throws Exception
-   */
-  protected void restartTabletServer(KuduTable table) throws Exception {
-    List<LocatedTablet> tablets = table.getTabletsLocations(DEFAULT_SLEEP);
-    if (tablets.isEmpty()) {
-      fail("Table " + table.getName() + " doesn't have any tablets");
-    }
-
-    LocatedTablet tablet = tablets.get(0);
-    Replica replica = tablet.getReplicas().get(randomForTSRestart.nextInt(tablet.getReplicas().size()));
-    HostAndPort hp = new HostAndPort(replica.getRpcHost(), replica.getRpcPort());
-    miniCluster.killTabletServer(hp);
-    miniCluster.startTabletServer(hp);
-  }
-
-  /**
-   * Kills a tablet server that serves the given tablet's leader and restarts it.
-   * @param tablet a RemoteTablet which will get its leader killed and restarted
-   * @throws Exception
-   */
-  protected void restartTabletServer(RemoteTablet tablet) throws Exception {
-    HostAndPort hp = findLeaderTabletServer(new LocatedTablet(tablet));
-    miniCluster.killTabletServer(hp);
-    miniCluster.startTabletServer(hp);
-  }
-
-  /**
-   * Kills and restarts the leader master.
-   * @throws Exception
-   */
-  protected void restartLeaderMaster() throws Exception {
-    HostAndPort hp = findLeaderMasterServer();
-    miniCluster.killMasterServer(hp);
-    miniCluster.startMasterServer(hp);
-  }
-
-  /**
-   * Return the comma-separated list of "host:port" pairs that describes the master
-   * config for this cluster.
-   * @return The master config string.
-   */
-  protected String getMasterAddressesAsString() {
-    return miniCluster.getMasterAddressesAsString();
-  }
-
-  /**
-   * @return the list of master servers
-   */
-  public List<HostAndPort> getMasterServers() {
-    return miniCluster.getMasterServers();
-  }
-
-  /**
-   * @return the list of tablet servers
-   */
-  public List<HostAndPort> getTabletServers() {
-    return miniCluster.getMasterServers();
-  }
-
-  /**
-   * @return path to the mini cluster root directory
-   */
-  protected String getClusterRoot() {
-    return miniCluster.getClusterRoot();
-  }
-
-  /**
-   * Kills all the master servers.
-   * Does nothing to the servers that are already dead.
-   *
-   * @throws IOException
-   */
-  protected void killAllMasterServers() throws IOException {
-    miniCluster.killAllMasterServers();
-  }
-
-  /**
-   * Starts all the master servers.
-   * Does nothing to the servers that are already running.
-   *
-   * @throws IOException
-   */
-  protected void startAllMasterServers() throws IOException {
-    miniCluster.startAllMasterServers();
-  }
-
-  /**
-   * Kills all the tablet servers.
-   * Does nothing to the servers that are already dead.
-   *
-   * @throws IOException
-   */
-  protected void killAllTabletServers() throws IOException {
-    miniCluster.killAllTabletServers();
-  }
-
-  /**
-   * Starts all the tablet servers.
-   * Does nothing to the servers that are already running.
-   *
-   * @throws IOException
-   */
-  protected void startAllTabletServers() throws IOException {
-    miniCluster.startAllTabletServers();
-  }
-
-  /**
-   * Removes all credentials for all principals from the Kerberos credential cache.
-   */
-  protected void kdestroy() throws IOException {
-    miniCluster.kdestroy();
-  }
-
-  /**
-   * Re-initialize Kerberos credentials for the given username, writing them
-   * into the Kerberos credential cache.
-   * @param username the username to kinit as
-   */
-  protected void kinit(String username) throws IOException {
-    miniCluster.kinit(username);
-  }
-
-  /**
-   * Resets the clients so that their state is completely fresh, including meta
-   * cache, connections, open tables, sessions and scanners, and propagated timestamp.
-   */
-  protected void resetClients() throws IOException {
-    syncClient.shutdown();
-    client = new AsyncKuduClient.AsyncKuduClientBuilder(miniCluster.getMasterAddressesAsString())
-                                .defaultAdminOperationTimeoutMs(DEFAULT_SLEEP)
-                                .build();
-    syncClient = client.syncClient();
-  }
-}

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/ITClient.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/ITClient.java b/java/kudu-client/src/test/java/org/apache/kudu/client/ITClient.java
index 42dae2a..6e379f7 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/ITClient.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/ITClient.java
@@ -23,14 +23,18 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 import com.google.common.collect.ImmutableList;
+import org.apache.kudu.test.KuduTestHarness;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.kudu.test.KuduTestHarness.DEFAULT_SLEEP;
 import static org.apache.kudu.util.ClientTestUtil.countRowsInScan;
 import static org.apache.kudu.util.ClientTestUtil.createBasicSchemaInsert;
+import static org.apache.kudu.util.ClientTestUtil.getBasicSchema;
 
 /**
  * Integration test for the client. RPCs are sent to Kudu from multiple threads while processes
@@ -40,7 +44,7 @@ import static org.apache.kudu.util.ClientTestUtil.createBasicSchemaInsert;
  * in "itclient.runtime.seconds". For example:
  * "mvn test -Dtest=ITClient -Ditclient.runtime.seconds=120".
  */
-public class ITClient extends BaseKuduTest {
+public class ITClient {
 
   private static final Logger LOG = LoggerFactory.getLogger(ITClient.class);
 
@@ -65,6 +69,9 @@ public class ITClient extends BaseKuduTest {
 
   private volatile long sharedWriteTimestamp;
 
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
   @Before
   public void setUp() throws Exception {
 
@@ -80,14 +87,14 @@ public class ITClient extends BaseKuduTest {
 
     // Client we're using has low tolerance for read timeouts but a
     // higher overall operation timeout.
-    localAsyncClient = new AsyncKuduClient.AsyncKuduClientBuilder(getMasterAddressesAsString())
+    localAsyncClient = new AsyncKuduClient.AsyncKuduClientBuilder(harness.getMasterAddressesAsString())
         .defaultSocketReadTimeoutMs(500)
         .build();
     localClient = new KuduClient(localAsyncClient);
 
     CreateTableOptions builder = new CreateTableOptions().setNumReplicas(3);
     builder.setRangePartitionColumns(ImmutableList.of("key"));
-    table = localClient.createTable(TABLE_NAME, basicSchema, builder);
+    table = localClient.createTable(TABLE_NAME, getBasicSchema(), builder);
   }
 
   @Test(timeout = TEST_TIMEOUT_SECONDS)
@@ -175,7 +182,7 @@ public class ITClient extends BaseKuduTest {
 
     /**
      * Failure injection. Picks a random tablet server from the client's cache and force
-     * disconects it.
+     * disconnects it.
      * @return true if successfully completed or didn't find a server to disconnect, false it it
      * encountered a failure
      */
@@ -204,7 +211,7 @@ public class ITClient extends BaseKuduTest {
      */
     private boolean restartTS() {
       try {
-        restartTabletServer(table);
+        harness.restartTabletServer(table);
       } catch (Exception e) {
         reportError("Couldn't restart a TS", e);
         return false;
@@ -218,7 +225,7 @@ public class ITClient extends BaseKuduTest {
      */
     private boolean restartMaster() {
       try {
-        restartLeaderMaster();
+        harness.restartLeaderMaster();
       } catch (Exception e) {
         reportError("Couldn't restart a master", e);
         return false;

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/ITClientStress.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/ITClientStress.java b/java/kudu-client/src/test/java/org/apache/kudu/client/ITClientStress.java
index cd08a94..9b637e6 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/ITClientStress.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/ITClientStress.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.createFourTabletsTableWithNineRows;
 import static org.apache.kudu.util.ClientTestUtil.getBasicCreateTableOptions;
 import static org.junit.Assert.assertFalse;
@@ -33,11 +34,23 @@ import java.util.concurrent.atomic.AtomicReference;
 import com.google.common.base.Stopwatch;
 import com.google.common.base.Supplier;
 
+import org.apache.kudu.Schema;
+import org.apache.kudu.test.KuduTestHarness;
+import org.apache.kudu.util.ClientTestUtil;
+import org.junit.Rule;
 import org.junit.Test;
 import org.apache.kudu.client.SessionConfiguration.FlushMode;
 import org.apache.kudu.util.CapturingLogAppender;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public class ITClientStress extends BaseKuduTest {
+public class ITClientStress {
+  private static final Logger LOG = LoggerFactory.getLogger(ITClientStress.class);
+
+  private static final Schema basicSchema = ClientTestUtil.getBasicSchema();
+
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
 
   @SuppressWarnings("FutureReturnValueIgnored")
   private void runTasks(int numThreads, int secondsToRun,
@@ -97,7 +110,7 @@ public class ITClientStress extends BaseKuduTest {
     final String TABLE_NAME = "testManyClients";
     final int SECONDS_TO_RUN = 10;
     final int NUM_THREADS = 80;
-    createFourTabletsTableWithNineRows(client, TABLE_NAME, DEFAULT_SLEEP);
+    createFourTabletsTableWithNineRows(harness.getAsyncClient(), TABLE_NAME, DEFAULT_SLEEP);
 
     runTasks(NUM_THREADS, SECONDS_TO_RUN, new Supplier<Callable<Void>>() {
       @Override
@@ -106,7 +119,7 @@ public class ITClientStress extends BaseKuduTest {
           @Override
           public Void call() throws Exception {
             try (AsyncKuduClient client =
-                  new AsyncKuduClient.AsyncKuduClientBuilder(getMasterAddressesAsString())
+                  new AsyncKuduClient.AsyncKuduClientBuilder(harness.getMasterAddressesAsString())
                   .defaultAdminOperationTimeoutMs(DEFAULT_SLEEP)
                   .build()) {
               KuduTable t = client.openTable(TABLE_NAME).join();
@@ -128,7 +141,7 @@ public class ITClientStress extends BaseKuduTest {
     final String TABLE_NAME = "testMultipleSessions";
     final int SECONDS_TO_RUN = 10;
     final int NUM_THREADS = 60;
-    final KuduTable table = createTable(TABLE_NAME, basicSchema,
+    final KuduTable table = harness.getClient().createTable(TABLE_NAME, basicSchema,
         getBasicCreateTableOptions());
     final AtomicInteger numUpserted = new AtomicInteger(0);
     runTasks(NUM_THREADS, SECONDS_TO_RUN, new Supplier<Callable<Void>>() {
@@ -137,7 +150,7 @@ public class ITClientStress extends BaseKuduTest {
         return new Callable<Void>() {
           @Override
           public Void call() throws Exception {
-            KuduSession s = syncClient.newSession();
+            KuduSession s = harness.getClient().newSession();
             s.setFlushMode(FlushMode.AUTO_FLUSH_SYNC);
             try {
               for (int i = 0; i < 100; i++) {

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/ITNonFaultTolerantScanner.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/ITNonFaultTolerantScanner.java b/java/kudu-client/src/test/java/org/apache/kudu/client/ITNonFaultTolerantScanner.java
index 0f196fb..f34653b 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/ITNonFaultTolerantScanner.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/ITNonFaultTolerantScanner.java
@@ -33,7 +33,7 @@ public class ITNonFaultTolerantScanner extends ITScannerMultiTablet {
    */
   @Test(timeout = 100000)
   public void testKudu1343() throws Exception {
-    KuduScanner scanner = syncClient.newScannerBuilder(table)
+    KuduScanner scanner = harness.getClient().newScannerBuilder(table)
         .batchSizeBytes(1) // Just a hint, won't actually be that small
         .build();
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/ITScannerMultiTablet.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/ITScannerMultiTablet.java b/java/kudu-client/src/test/java/org/apache/kudu/client/ITScannerMultiTablet.java
index dbaaefd..02d8dcc 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/ITScannerMultiTablet.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/ITScannerMultiTablet.java
@@ -23,15 +23,17 @@ import static org.junit.Assert.assertTrue;
 import java.util.Random;
 
 import com.google.common.collect.Lists;
+import org.apache.kudu.test.KuduTestHarness;
 import org.junit.Before;
 
 import org.apache.kudu.Schema;
+import org.junit.Rule;
 
 /**
  * Integration test that inserts enough data to trigger flushes and getting multiple data
  * blocks.
  */
-public class ITScannerMultiTablet extends BaseKuduTest {
+public class ITScannerMultiTablet {
 
   private static final String TABLE_NAME =
       ITScannerMultiTablet.class.getName()+"-"+System.currentTimeMillis();
@@ -43,6 +45,9 @@ public class ITScannerMultiTablet extends BaseKuduTest {
 
   private static Random random = new Random(1234);
 
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
   @Before
   public void setUp() throws Exception {
     CreateTableOptions builder = new CreateTableOptions();
@@ -51,9 +56,9 @@ public class ITScannerMultiTablet extends BaseKuduTest {
         Lists.newArrayList(schema.getColumnByIndex(0).getName()),
         TABLET_COUNT);
 
-    table = createTable(TABLE_NAME, schema, builder);
+    table = harness.getClient().createTable(TABLE_NAME, schema, builder);
 
-    KuduSession session = syncClient.newSession();
+    KuduSession session = harness.getClient().newSession();
     session.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_BACKGROUND);
 
     // Getting meaty rows.
@@ -90,7 +95,7 @@ public class ITScannerMultiTablet extends BaseKuduTest {
    */
   void serverFaultInjection(boolean restart, boolean isFaultTolerant,
       boolean finishFirstScan) throws Exception {
-    KuduScanner scanner = syncClient.newScannerBuilder(table)
+    KuduScanner scanner = harness.getClient().newScannerBuilder(table)
         .setFaultTolerant(isFaultTolerant)
         .batchSizeBytes(1)
         .setProjectedColumnIndexes(Lists.newArrayList(0)).build();
@@ -113,9 +118,9 @@ public class ITScannerMultiTablet extends BaseKuduTest {
 
       if (!finishFirstScan) {
         if (restart) {
-          restartTabletServer(scanner.currentTablet());
+          harness.restartTabletServer(scanner.currentTablet());
         } else {
-          killTabletLeader(scanner.currentTablet());
+          harness.killTabletLeader(scanner.currentTablet());
         }
       }
 
@@ -128,9 +133,9 @@ public class ITScannerMultiTablet extends BaseKuduTest {
             tableBoundariesCount++;
             if (finishFirstScan && !failureInjected) {
               if (restart) {
-                restartTabletServer(scanner.currentTablet());
+                harness.restartTabletServer(scanner.currentTablet());
               } else {
-                killTabletLeader(scanner.currentTablet());
+                harness.killTabletLeader(scanner.currentTablet());
               }
               failureInjected = true;
             }
@@ -155,7 +160,7 @@ public class ITScannerMultiTablet extends BaseKuduTest {
    * @throws Exception
    */
   void clientFaultInjection(boolean isFaultTolerant) throws KuduException {
-    KuduScanner scanner = syncClient.newScannerBuilder(table)
+    KuduScanner scanner = harness.getClient().newScannerBuilder(table)
         .setFaultTolerant(isFaultTolerant)
         .batchSizeBytes(1)
         .build();
@@ -171,7 +176,7 @@ public class ITScannerMultiTablet extends BaseKuduTest {
 
       // Forcefully disconnects the current connection and fails all outstanding RPCs
       // in the middle of scanning.
-      client.newRpcProxy(scanner.currentTablet().getReplicaSelectedServerInfo(
+      harness.getAsyncClient().newRpcProxy(scanner.currentTablet().getReplicaSelectedServerInfo(
           scanner.getReplicaSelection())).getConnection().disconnect();
 
       while (scanner.hasMoreRows()) {

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/MiniKuduCluster.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/MiniKuduCluster.java b/java/kudu-client/src/test/java/org/apache/kudu/client/MiniKuduCluster.java
index dfa5ea7..95b310f 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/MiniKuduCluster.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/MiniKuduCluster.java
@@ -38,6 +38,7 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
 import org.apache.kudu.Common;
+import org.apache.kudu.test.KuduTestHarness;
 import org.apache.kudu.tools.Tool.ControlShellRequestPB;
 import org.apache.kudu.tools.Tool.ControlShellResponsePB;
 import org.apache.kudu.tools.Tool.CreateClusterRequestPB.MiniKdcOptionsPB;
@@ -61,8 +62,8 @@ import org.slf4j.LoggerFactory;
 
 /**
  * Utility class to start and manipulate Kudu clusters. Depends on precompiled
- * kudu, kudu-master, and kudu-tserver binaries. {@link BaseKuduTest} should be
- * extended instead of directly using this class in almost all cases.
+ * kudu, kudu-master, and kudu-tserver binaries. {@link KuduTestHarness}
+ * should be used instead of directly using this class in almost all cases.
  */
 @InterfaceAudience.Private
 @InterfaceStability.Unstable
@@ -546,23 +547,23 @@ public class MiniKuduCluster implements AutoCloseable {
    */
   public static class MiniKuduClusterBuilder {
 
-    private int numMasters = 1;
-    private int numTservers = 3;
+    private int numMasterServers = 1;
+    private int numTabletServers = 3;
     private boolean enableKerberos = false;
-    private final List<String> extraTserverFlags = new ArrayList<>();
-    private final List<String> extraMasterFlags = new ArrayList<>();
+    private final List<String> extraTabletServerFlags = new ArrayList<>();
+    private final List<String> extraMasterServerFlags = new ArrayList<>();
     private String clusterRoot = null;
 
     private MiniKdcOptionsPB.Builder kdcOptionsPb = MiniKdcOptionsPB.newBuilder();
     private Common.HmsMode hmsMode = Common.HmsMode.NONE;
 
-    public MiniKuduClusterBuilder numMasters(int numMasters) {
-      this.numMasters = numMasters;
+    public MiniKuduClusterBuilder numMasterServers(int numMasterServers) {
+      this.numMasterServers = numMasterServers;
       return this;
     }
 
-    public MiniKuduClusterBuilder numTservers(int numTservers) {
-      this.numTservers = numTservers;
+    public MiniKuduClusterBuilder numTabletServers(int numTabletServers) {
+      this.numTabletServers = numTabletServers;
       return this;
     }
 
@@ -584,8 +585,8 @@ public class MiniKuduCluster implements AutoCloseable {
      * Adds a new flag to be passed to the Tablet Server daemons on start.
      * @return this instance
      */
-    public MiniKuduClusterBuilder addTserverFlag(String flag) {
-      this.extraTserverFlags.add(flag);
+    public MiniKuduClusterBuilder addTabletServerFlag(String flag) {
+      this.extraTabletServerFlags.add(flag);
       return this;
     }
 
@@ -593,8 +594,8 @@ public class MiniKuduCluster implements AutoCloseable {
      * Adds a new flag to be passed to the Master daemons on start.
      * @return this instance
      */
-    public MiniKuduClusterBuilder addMasterFlag(String flag) {
-      this.extraMasterFlags.add(flag);
+    public MiniKuduClusterBuilder addMasterServerFlag(String flag) {
+      this.extraMasterServerFlags.add(flag);
       return this;
     }
 
@@ -625,8 +626,8 @@ public class MiniKuduCluster implements AutoCloseable {
     public MiniKuduCluster build() throws IOException {
       MiniKuduCluster cluster =
           new MiniKuduCluster(enableKerberos,
-              numMasters, numTservers,
-              extraTserverFlags, extraMasterFlags,
+              numMasterServers, numTabletServers,
+              extraTabletServerFlags, extraMasterServerFlags,
               kdcOptionsPb.build(), clusterRoot, hmsMode);
       try {
         cluster.start();

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestAlterTable.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestAlterTable.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestAlterTable.java
index 78fb9c3..8227fce 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestAlterTable.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestAlterTable.java
@@ -31,7 +31,9 @@ import java.util.List;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
+import org.apache.kudu.test.KuduTestHarness;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 
 import org.apache.kudu.ColumnSchema;
@@ -41,11 +43,16 @@ import org.apache.kudu.Schema;
 import org.apache.kudu.Type;
 import org.apache.kudu.util.Pair;
 
-public class TestAlterTable extends BaseKuduTest {
+public class TestAlterTable {
   private String tableName;
+  private KuduClient client;
+
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
 
   @Before
-  public void setTableName() {
+  public void setUp() {
+    client = harness.getClient();
     tableName = TestKuduClient.class.getName() + "-" + System.currentTimeMillis();
   }
 
@@ -80,7 +87,7 @@ public class TestAlterTable extends BaseKuduTest {
       createOptions.addRangePartition(lower, upper);
     }
 
-    return createTable(tableName, schema, createOptions);
+    return client.createTable(tableName, schema, createOptions);
   }
 
   /**
@@ -91,7 +98,7 @@ public class TestAlterTable extends BaseKuduTest {
    * @param end the exclusive end key
    */
   private void insertRows(KuduTable table, int start, int end) throws KuduException {
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_BACKGROUND);
     for (int i = start; i < end; i++) {
       Insert insert = table.newInsert();
@@ -111,17 +118,17 @@ public class TestAlterTable extends BaseKuduTest {
     insertRows(table, 0, 100);
     assertEquals(100, countRowsInTable(table));
 
-    syncClient.alterTable(tableName, new AlterTableOptions()
+    client.alterTable(tableName, new AlterTableOptions()
         .addColumn("addNonNull", Type.INT32, 100)
         .addNullableColumn("addNullable", Type.INT32)
         .addNullableColumn("addNullableDef", Type.INT32, 200));
 
     // Reopen table for the new schema.
-    table = syncClient.openTable(tableName);
+    table = client.openTable(tableName);
     assertEquals(5, table.getSchema().getColumnCount());
 
     // Add a row with addNullableDef=null
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     Insert insert = table.newInsert();
     PartialRow row = insert.getRow();
     row.addInt("c0", 101);
@@ -160,13 +167,13 @@ public class TestAlterTable extends BaseKuduTest {
     assertEquals(null, col.getDefaultValue());
 
     // Alter the table.
-    syncClient.alterTable(tableName, new AlterTableOptions()
+    client.alterTable(tableName, new AlterTableOptions()
         .changeCompressionAlgorithm(col.getName(), CompressionAlgorithm.SNAPPY)
         .changeEncoding(col.getName(), Encoding.RLE)
         .changeDefault(col.getName(), 0));
 
     // Check for new values.
-    table = syncClient.openTable(tableName);
+    table = client.openTable(tableName);
     col = table.getSchema().getColumns().get(1);
     assertEquals(CompressionAlgorithm.SNAPPY, col.getCompressionAlgorithm());
     assertEquals(Encoding.RLE, col.getEncoding());
@@ -179,12 +186,12 @@ public class TestAlterTable extends BaseKuduTest {
     insertRows(table, 0, 100);
     assertEquals(100, countRowsInTable(table));
 
-    syncClient.alterTable(tableName, new AlterTableOptions()
+    client.alterTable(tableName, new AlterTableOptions()
             .renameColumn("c0", "c0Key"));
 
     // scanning with the old schema
     try {
-      KuduScanner scanner = syncClient.newScannerBuilder(table)
+      KuduScanner scanner = client.newScannerBuilder(table)
               .setProjectedColumnNames(Lists.newArrayList("c0", "c1")).build();
       while (scanner.hasMoreRows()) {
         scanner.nextRows();
@@ -197,12 +204,12 @@ public class TestAlterTable extends BaseKuduTest {
     }
 
     // Reopen table for the new schema.
-    table = syncClient.openTable(tableName);
+    table = client.openTable(tableName);
     assertEquals("c0Key", table.getSchema().getPrimaryKeyColumns().get(0).getName());
     assertEquals(2, table.getSchema().getColumnCount());
 
     // Add a row
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     Insert insert = table.newInsert();
     PartialRow row = insert.getRow();
     row.addInt("c0Key", 101);
@@ -212,7 +219,7 @@ public class TestAlterTable extends BaseKuduTest {
     RowError[] rowErrors = session.getPendingErrors().getRowErrors();
     assertEquals(String.format("row errors: %s", Arrays.toString(rowErrors)), 0, rowErrors.length);
 
-    KuduScanner scanner = syncClient.newScannerBuilder(table)
+    KuduScanner scanner = client.newScannerBuilder(table)
             .setProjectedColumnNames(Lists.newArrayList("c0Key", "c1")).build();
     while (scanner.hasMoreRows()) {
       RowResultIterator it = scanner.nextRows();
@@ -232,13 +239,13 @@ public class TestAlterTable extends BaseKuduTest {
     assertEquals(100, countRowsInTable(table));
     PartialRow lower = schema.newPartialRow();
     PartialRow upper = schema.newPartialRow();
-    syncClient.alterTable(tableName, new AlterTableOptions().dropRangePartition(lower, upper));
+    client.alterTable(tableName, new AlterTableOptions().dropRangePartition(lower, upper));
     assertEquals(0, countRowsInTable(table));
 
     // Add new range partition and insert rows.
     lower.addInt("c0", 0);
     upper.addInt("c0", 100);
-    syncClient.alterTable(tableName, new AlterTableOptions().addRangePartition(lower, upper));
+    client.alterTable(tableName, new AlterTableOptions().addRangePartition(lower, upper));
     insertRows(table, 0, 100);
     assertEquals(100, countRowsInTable(table));
 
@@ -248,13 +255,13 @@ public class TestAlterTable extends BaseKuduTest {
     lower.addInt("c0", 50);
     upper.addInt("c0", 150);
     options.addRangePartition(lower, upper);
-    syncClient.alterTable(tableName, options);
+    client.alterTable(tableName, options);
     assertEquals(0, countRowsInTable(table));
     insertRows(table, 50, 125);
     assertEquals(75, countRowsInTable(table));
 
     // Replace the range partition with the same one.
-    syncClient.alterTable(tableName, new AlterTableOptions().dropRangePartition(lower, upper)
+    client.alterTable(tableName, new AlterTableOptions().dropRangePartition(lower, upper)
                                                             .addRangePartition(lower, upper));
     assertEquals(0, countRowsInTable(table));
     insertRows(table, 50, 125);
@@ -263,13 +270,13 @@ public class TestAlterTable extends BaseKuduTest {
     // Alter table partitioning + alter table schema
     lower.addInt("c0", 200);
     upper.addInt("c0", 300);
-    syncClient.alterTable(tableName, new AlterTableOptions().addRangePartition(lower, upper)
+    client.alterTable(tableName, new AlterTableOptions().addRangePartition(lower, upper)
                                                             .renameTable(tableName + "-renamed")
                                                             .addNullableColumn("c2", Type.INT32));
     tableName = tableName + "-renamed";
     insertRows(table, 200, 300);
     assertEquals(175, countRowsInTable(table));
-    assertEquals(3, openTable(tableName).getSchema().getColumnCount());
+    assertEquals(3, client.openTable(tableName).getSchema().getColumnCount());
 
     // Drop all range partitions + alter table schema. This also serves to test
     // specifying range bounds with a subset schema (since a column was
@@ -280,9 +287,9 @@ public class TestAlterTable extends BaseKuduTest {
     upper.addInt("c0", 150);
     options.dropRangePartition(lower, upper);
     options.dropColumn("c2");
-    syncClient.alterTable(tableName, options);
+    client.alterTable(tableName, options);
     assertEquals(0, countRowsInTable(table));
-    assertEquals(2, openTable(tableName).getSchema().getColumnCount());
+    assertEquals(2, client.openTable(tableName).getSchema().getColumnCount());
   }
 
   /**
@@ -314,11 +321,11 @@ public class TestAlterTable extends BaseKuduTest {
                                     RangePartitionBound.EXCLUSIVE_BOUND,
                                     RangePartitionBound.INCLUSIVE_BOUND);
 
-    KuduTable table = createTable(tableName, schema, createOptions);
+    KuduTable table = client.createTable(tableName, schema, createOptions);
 
     lower.addInt("c0", 199);
     upper.addInt("c0", 299);
-    syncClient.alterTable(tableName, new AlterTableOptions().addRangePartition(
+    client.alterTable(tableName, new AlterTableOptions().addRangePartition(
         lower, upper, RangePartitionBound.EXCLUSIVE_BOUND, RangePartitionBound.INCLUSIVE_BOUND));
 
     // Insert some rows, and then drop the partition and ensure that the table is empty.
@@ -337,7 +344,7 @@ public class TestAlterTable extends BaseKuduTest {
     alter.dropRangePartition(lower, upper,
                              RangePartitionBound.EXCLUSIVE_BOUND,
                              RangePartitionBound.INCLUSIVE_BOUND);
-    syncClient.alterTable(tableName, alter);
+    client.alterTable(tableName, alter);
 
     assertEquals(0, countRowsInTable(table));
   }
@@ -356,7 +363,7 @@ public class TestAlterTable extends BaseKuduTest {
     lower.addInt("c0", 0);
     upper.addInt("c0", 100);
     try {
-      syncClient.alterTable(tableName, new AlterTableOptions().addRangePartition(lower, upper));
+      client.alterTable(tableName, new AlterTableOptions().addRangePartition(lower, upper));
       fail();
     } catch (KuduException e) {
       assertTrue(e.getStatus().isInvalidArgument());
@@ -369,7 +376,7 @@ public class TestAlterTable extends BaseKuduTest {
     lower.addInt("c0", 50);
     upper.addInt("c0", 150);
     try {
-      syncClient.alterTable(tableName, new AlterTableOptions().addRangePartition(lower, upper));
+      client.alterTable(tableName, new AlterTableOptions().addRangePartition(lower, upper));
       fail();
     } catch (KuduException e) {
       assertTrue(e.getStatus().isInvalidArgument());
@@ -382,7 +389,7 @@ public class TestAlterTable extends BaseKuduTest {
     lower.addInt("c0", -50);
     upper.addInt("c0", 50);
     try {
-      syncClient.alterTable(tableName, new AlterTableOptions().addRangePartition(lower, upper));
+      client.alterTable(tableName, new AlterTableOptions().addRangePartition(lower, upper));
       fail();
     } catch (KuduException e) {
       assertTrue(e.getStatus().isInvalidArgument());
@@ -401,7 +408,7 @@ public class TestAlterTable extends BaseKuduTest {
     upper.addInt("c0", 150);
     options.addRangePartition(lower, upper);
     try {
-      syncClient.alterTable(tableName, options);
+      client.alterTable(tableName, options);
       fail();
     } catch (KuduException e) {
       assertTrue(e.getStatus().isInvalidArgument());
@@ -412,7 +419,7 @@ public class TestAlterTable extends BaseKuduTest {
 
     // DROP [<start>, <end>)
     try {
-      syncClient.alterTable(tableName,
+      client.alterTable(tableName,
                             new AlterTableOptions().dropRangePartition(schema.newPartialRow(),
                                                                        schema.newPartialRow()));
       fail();
@@ -428,7 +435,7 @@ public class TestAlterTable extends BaseKuduTest {
     lower.addInt("c0", 50);
     upper.addInt("c0", 150);
     try {
-      syncClient.alterTable(tableName, new AlterTableOptions().dropRangePartition(lower, upper)
+      client.alterTable(tableName, new AlterTableOptions().dropRangePartition(lower, upper)
                                                               .renameTable("foo"));
       fail();
     } catch (KuduException e) {
@@ -437,7 +444,7 @@ public class TestAlterTable extends BaseKuduTest {
           "No range partition found for drop range partition step"));
     }
     assertEquals(100, countRowsInTable(table));
-    assertFalse(syncClient.tableExists("foo"));
+    assertFalse(client.tableExists("foo"));
 
     // DROP [0, 100)
     // ADD  [100, 200)
@@ -463,7 +470,7 @@ public class TestAlterTable extends BaseKuduTest {
     upper.addInt("c0", 10);
     options.dropRangePartition(lower, upper);
     try {
-      syncClient.alterTable(tableName, options);
+      client.alterTable(tableName, options);
       fail();
     } catch (KuduException e) {
       assertTrue(e.getStatus().isInvalidArgument());

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestAsyncKuduClient.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestAsyncKuduClient.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestAsyncKuduClient.java
index 6c793bf..9a0feac 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestAsyncKuduClient.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestAsyncKuduClient.java
@@ -17,6 +17,7 @@
 package org.apache.kudu.client;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.kudu.test.KuduTestHarness.DEFAULT_SLEEP;
 import static org.apache.kudu.util.ClientTestUtil.countRowsInScan;
 import static org.apache.kudu.util.ClientTestUtil.createBasicSchemaInsert;
 import static org.apache.kudu.util.ClientTestUtil.getBasicCreateTableOptions;
@@ -32,7 +33,11 @@ import java.util.concurrent.TimeUnit;
 import com.google.common.base.Stopwatch;
 import com.google.protobuf.ByteString;
 import com.stumbleupon.async.Deferred;
+import org.apache.kudu.test.KuduTestHarness;
+import org.apache.kudu.util.ClientTestUtil;
 import org.apache.kudu.util.ProtobufUtils;
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 
 import org.apache.kudu.ColumnSchema;
@@ -42,13 +47,27 @@ import org.apache.kudu.Type;
 import org.apache.kudu.consensus.Metadata;
 import org.apache.kudu.master.Master;
 
-public class TestAsyncKuduClient extends BaseKuduTest {
+public class TestAsyncKuduClient {
+
+  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 testDisconnect() throws Exception {
     // Set to 1 to always test disconnecting the right server.
     CreateTableOptions options = getBasicCreateTableOptions().setNumReplicas(1);
-    KuduTable table = createTable(
+    KuduTable table = client.createTable(
         "testDisconnect-" + System.currentTimeMillis(),
         basicSchema,
         options);
@@ -65,7 +84,7 @@ public class TestAsyncKuduClient extends BaseKuduTest {
 
     // Test that we can reconnect to a TS while scanning.
     // 1. Insert enough rows to have to call next() multiple times.
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_BACKGROUND);
     int rowCount = 200;
     for (int i = 0; i < rowCount; i++) {
@@ -74,7 +93,7 @@ public class TestAsyncKuduClient extends BaseKuduTest {
     session.flush();
 
     // 2. Start a scanner with a small max num bytes.
-    AsyncKuduScanner scanner = client.newScannerBuilder(table)
+    AsyncKuduScanner scanner = asyncClient.newScannerBuilder(table)
         .batchSizeBytes(1)
         .build();
     Deferred<RowResultIterator> rri = scanner.nextRows();
@@ -92,15 +111,15 @@ public class TestAsyncKuduClient extends BaseKuduTest {
   }
 
   private void disconnectAndWait() throws InterruptedException {
-    for (Connection c : client.getConnectionListCopy()) {
+    for (Connection c : asyncClient.getConnectionListCopy()) {
       c.disconnect();
     }
     Stopwatch sw = Stopwatch.createStarted();
     boolean disconnected = false;
     while (sw.elapsed(TimeUnit.MILLISECONDS) < DEFAULT_SLEEP) {
       boolean sleep = false;
-      if (!client.getConnectionListCopy().isEmpty()) {
-        for (Connection c : client.getConnectionListCopy()) {
+      if (!asyncClient.getConnectionListCopy().isEmpty()) {
+        for (Connection c : asyncClient.getConnectionListCopy()) {
           if (!c.isTerminated()) {
             sleep = true;
             break;
@@ -150,9 +169,9 @@ public class TestAsyncKuduClient extends BaseKuduTest {
 
     // Test that a tablet full of unreachable replicas won't make us retry.
     try {
-      KuduTable badTable = new KuduTable(client, "Invalid table name",
+      KuduTable badTable = new KuduTable(asyncClient, "Invalid table name",
           "Invalid table ID", null, null, 3);
-      client.discoverTablets(badTable, null, requestBatchSize, tabletLocations, 1000);
+      asyncClient.discoverTablets(badTable, null, requestBatchSize, tabletLocations, 1000);
       fail("This should have failed quickly");
     } catch (NonRecoverableException ex) {
       assertTrue(ex.getMessage().contains(badHostname));
@@ -163,13 +182,13 @@ public class TestAsyncKuduClient extends BaseKuduTest {
   public void testNoLeader() throws Exception {
     final int requestBatchSize = 10;
     CreateTableOptions options = getBasicCreateTableOptions();
-    KuduTable table = createTable(
+    KuduTable table = client.createTable(
         "testNoLeader-" + System.currentTimeMillis(),
         basicSchema,
         options);
 
     // Lookup the current locations so that we can pass some valid information to discoverTablets.
-    List<LocatedTablet> tablets = client
+    List<LocatedTablet> tablets = asyncClient
         .locateTable(table, null, null, requestBatchSize, DEFAULT_SLEEP)
         .join(DEFAULT_SLEEP);
     LocatedTablet tablet = tablets.get(0);
@@ -184,7 +203,7 @@ public class TestAsyncKuduClient extends BaseKuduTest {
         "master", leader.getRpcHost(), leader.getRpcPort(), Metadata.RaftPeerPB.Role.FOLLOWER));
     tabletLocations.add(tabletPb.build());
     try {
-      client.discoverTablets(table, new byte[0], requestBatchSize, tabletLocations, 1000);
+      asyncClient.discoverTablets(table, new byte[0], requestBatchSize, tabletLocations, 1000);
       fail("discoverTablets should throw an exception if there's no leader");
     } catch (NoLeaderFoundException ex) {
       // Expected.
@@ -194,19 +213,19 @@ public class TestAsyncKuduClient extends BaseKuduTest {
   @Test
   public void testConnectionRefused() throws Exception {
     CreateTableOptions options = getBasicCreateTableOptions();
-    KuduTable table = createTable(
+    KuduTable table = client.createTable(
         "testConnectionRefused-" + System.currentTimeMillis(),
         basicSchema,
         options);
 
     // Warm up the caches.
-    assertEquals(0, countRowsInScan(syncClient.newScannerBuilder(table).build()));
+    assertEquals(0, countRowsInScan(client.newScannerBuilder(table).build()));
 
     // Make it impossible to use Kudu.
-    killAllTabletServers();
+    harness.killAllTabletServers();
 
     // Create a scan with a short timeout.
-    KuduScanner scanner = syncClient.newScannerBuilder(table).scanRequestTimeout(1000).build();
+    KuduScanner scanner = client.newScannerBuilder(table).scanRequestTimeout(1000).build();
 
     // Check it fails.
     try {
@@ -219,7 +238,7 @@ public class TestAsyncKuduClient extends BaseKuduTest {
     }
 
     // Try the same thing with an insert.
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setTimeoutMillis(1000);
     OperationResponse response = session.apply(createBasicSchemaInsert(table, 1));
     assertTrue(response.hasRowError());
@@ -241,7 +260,7 @@ public class TestAsyncKuduClient extends BaseKuduTest {
     columns.add(new ColumnSchema.ColumnSchemaBuilder("column4_b", Type.BOOL).build());
     Schema schema = new Schema(columns);
     try {
-      client.createTable("testCreateTableOutOfOrderPrimaryKeys-" + System.currentTimeMillis(),
+      asyncClient.createTable("testCreateTableOutOfOrderPrimaryKeys-" + System.currentTimeMillis(),
           schema,
           getBasicCreateTableOptions()).join();
       fail();

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestAsyncKuduSession.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestAsyncKuduSession.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestAsyncKuduSession.java
index 1bf8c63..ae4f161 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestAsyncKuduSession.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestAsyncKuduSession.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.countRowsInScan;
 import static org.apache.kudu.util.ClientTestUtil.createBasicSchemaInsert;
 import static org.apache.kudu.util.ClientTestUtil.defaultErrorCB;
@@ -33,7 +34,9 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import com.stumbleupon.async.Callback;
 import com.stumbleupon.async.Deferred;
+import org.apache.kudu.test.KuduTestHarness;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 
 import org.apache.kudu.Schema;
@@ -51,17 +54,23 @@ import org.apache.kudu.tserver.Tserver.TabletServerErrorPB;
  *
  * The test creates a table with a unique(ish) name which it deletes at the end.
  */
-public class TestAsyncKuduSession extends BaseKuduTest {
+public class TestAsyncKuduSession {
   // Generate a unique table name
   private static final String TABLE_NAME =
       TestAsyncKuduSession.class.getName()+"-"+System.currentTimeMillis();
 
-  private static Schema schema = getBasicSchema();
+  private static final Schema schema = getBasicSchema();
+
+  private static AsyncKuduClient client;
   private static KuduTable table;
 
+  @Rule
+  public KuduTestHarness harness = new KuduTestHarness();
+
   @Before
   public void setUp() throws Exception {
-    table = createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
+    client = harness.getAsyncClient();
+    table = harness.getClient().createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
   }
 
   @Test(timeout = 100000)
@@ -158,14 +167,14 @@ public class TestAsyncKuduSession extends BaseKuduTest {
       assertTrue(response.hasRowError());
       assertTrue(response.getRowError().getErrorStatus().isNotFound());
     } finally {
-      table = createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
+      table = harness.getClient().createTable(TABLE_NAME, schema, getBasicCreateTableOptions());
     }
   }
 
   /** Regression test for a failure to correctly handle a timeout when flushing a batch. */
   @Test
   public void testInsertIntoUnavailableTablet() throws Exception {
-    killAllTabletServers();
+    harness.killAllTabletServers();
     try {
       AsyncKuduSession session = client.newSession();
       session.setTimeoutMillis(1);
@@ -180,7 +189,7 @@ public class TestAsyncKuduSession extends BaseKuduTest {
       assertEquals(1, responses.size());
       assertTrue(responses.get(0).getRowError().getErrorStatus().isTimedOut());
     } finally {
-      startAllTabletServers();
+      harness.startAllTabletServers();
     }
   }
 
@@ -195,9 +204,9 @@ public class TestAsyncKuduSession extends BaseKuduTest {
     // we're sure when we reconnect to the leader after restarting
     // the tablet servers, it's definitely the same leader we wrote
     // to before.
-    KuduTable nonReplicatedTable = createTable(
+    KuduTable nonReplicatedTable = harness.getClient().createTable(
         "non-replicated",
-        basicSchema,
+        schema,
         getBasicCreateTableOptions().setNumReplicas(1));
 
     try {
@@ -210,8 +219,8 @@ public class TestAsyncKuduSession extends BaseKuduTest {
       int numClientsBefore = client.getConnectionListCopy().size();
 
       // Restart all the tablet servers.
-      killAllTabletServers();
-      startAllTabletServers();
+      harness.killAllTabletServers();
+      harness.startAllTabletServers();
 
       // Perform another write, which will require reconnecting to the same
       // tablet server that we wrote to above.
@@ -221,7 +230,7 @@ public class TestAsyncKuduSession extends BaseKuduTest {
       int numClientsAfter = client.getConnectionListCopy().size();
       assertEquals(numClientsBefore, numClientsAfter);
     } finally {
-      startAllTabletServers();
+      harness.startAllTabletServers();
 
       client.deleteTable("non-replicated").join();
     }

http://git-wip-us.apache.org/repos/asf/kudu/blob/dc8ae799/java/kudu-client/src/test/java/org/apache/kudu/client/TestAuthnTokenReacquire.java
----------------------------------------------------------------------
diff --git a/java/kudu-client/src/test/java/org/apache/kudu/client/TestAuthnTokenReacquire.java b/java/kudu-client/src/test/java/org/apache/kudu/client/TestAuthnTokenReacquire.java
index 2bbe695..5b765f8 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestAuthnTokenReacquire.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestAuthnTokenReacquire.java
@@ -32,31 +32,51 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * This test contains scenarios to verify that client re-acquires authn token upon expiration
  * of the current one and automatically retries the call.
  */
-public class TestAuthnTokenReacquire extends BaseKuduTest {
+public class TestAuthnTokenReacquire {
+  private static final Logger LOG = LoggerFactory.getLogger(TestAuthnTokenReacquire.class);
 
   private static final String TABLE_NAME = "TestAuthnTokenReacquire-table";
   private static final int TOKEN_TTL_SEC = 1;
   private static final int OP_TIMEOUT_MS = 60 * TOKEN_TTL_SEC * 1000;
 
-  @Override
-  protected MiniKuduCluster.MiniKuduClusterBuilder getMiniClusterBuilder() {
-    // Inject additional INVALID_AUTHENTICATION_TOKEN responses from both the master and tablet
-    // servers, even for not-yet-expired tokens.
-    return super.getMiniClusterBuilder()
-        .enableKerberos()
-        .addMasterFlag(String.format("--authn_token_validity_seconds=%d", TOKEN_TTL_SEC))
-        .addMasterFlag("--rpc_inject_invalid_authn_token_ratio=0.5")
-        .addTserverFlag("--rpc_inject_invalid_authn_token_ratio=0.5");
+  private static final Schema basicSchema = ClientTestUtil.getBasicSchema();
+
+  // Inject additional INVALID_AUTHENTICATION_TOKEN responses from both the master and tablet
+  // servers, even for not-yet-expired tokens.
+  private static final MiniKuduClusterBuilder clusterBuilder = KuduTestHarness.getBaseClusterBuilder()
+      .enableKerberos()
+      .addMasterServerFlag(String.format("--authn_token_validity_seconds=%d", TOKEN_TTL_SEC))
+      .addMasterServerFlag("--rpc_inject_invalid_authn_token_ratio=0.5")
+      .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();
     }
   }
@@ -82,24 +102,24 @@ public class TestAuthnTokenReacquire extends BaseKuduTest {
         public void run() {
           final String tableName = "TestAuthnTokenReacquire-table-" + threadIdx;
           try {
-            ListTabletServersResponse response = syncClient.listTabletServers();
+            ListTabletServersResponse response = client.listTabletServers();
             assertNotNull(response);
             dropConnectionsAndExpireToken();
 
-            ListTablesResponse tableList = syncClient.getTablesList(tableName);
+            ListTablesResponse tableList = client.getTablesList(tableName);
             assertNotNull(tableList);
             assertTrue(tableList.getTablesList().isEmpty());
             dropConnectionsAndExpireToken();
 
-            syncClient.createTable(tableName, basicSchema, getBasicCreateTableOptions());
+            client.createTable(tableName, basicSchema, getBasicCreateTableOptions());
             dropConnectionsAndExpireToken();
 
-            KuduTable table = syncClient.openTable(tableName);
+            KuduTable table = client.openTable(tableName);
             assertEquals(basicSchema.getColumnCount(), table.getSchema().getColumnCount());
             dropConnectionsAndExpireToken();
 
-            syncClient.deleteTable(tableName);
-            assertFalse(syncClient.tableExists(tableName));
+            client.deleteTable(tableName);
+            assertFalse(client.tableExists(tableName));
           } catch (Throwable e) {
             //noinspection ThrowableResultOfMethodCallIgnored
             exceptions.put(threadIdx, e);
@@ -122,11 +142,11 @@ public class TestAuthnTokenReacquire extends BaseKuduTest {
 
   @Test
   public void testBasicWorkflow() throws Exception {
-    KuduTable table = syncClient.createTable(TABLE_NAME, basicSchema,
+    KuduTable table = client.createTable(TABLE_NAME, basicSchema,
         getBasicCreateTableOptions());
     dropConnectionsAndExpireToken();
 
-    KuduSession session = syncClient.newSession();
+    KuduSession session = client.newSession();
     session.setTimeoutMillis(OP_TIMEOUT_MS);
     session.apply(createBasicSchemaInsert(table, 1));
     session.flush();
@@ -135,14 +155,14 @@ public class TestAuthnTokenReacquire extends BaseKuduTest {
     assertEquals(0, session.countPendingErrors());
     dropConnectionsAndExpireToken();
 
-    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(1, countRowsInScan(scanner));
     dropConnectionsAndExpireToken();
 
-    syncClient.deleteTable(TABLE_NAME);
-    assertFalse(syncClient.tableExists(TABLE_NAME));
+    client.deleteTable(TABLE_NAME);
+    assertFalse(client.tableExists(TABLE_NAME));
   }
 }


Mime
View raw message