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

[4/6] kudu git commit: mini-cluster: new module for the mini cluster implementations

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/internal_mini_cluster.h
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/internal_mini_cluster.h b/src/kudu/integration-tests/internal_mini_cluster.h
deleted file mode 100644
index 9081479..0000000
--- a/src/kudu/integration-tests/internal_mini_cluster.h
+++ /dev/null
@@ -1,219 +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.
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <glog/logging.h>
-
-#include "kudu/client/shared_ptr.h"
-#include "kudu/gutil/macros.h"
-#include "kudu/integration-tests/mini_cluster.h"
-
-namespace kudu {
-
-class Env;
-class HostPort;
-class Status;
-
-namespace client {
-class KuduClient;
-class KuduClientBuilder;
-}
-
-namespace master {
-class MasterServiceProxy;
-class MiniMaster;
-class TSDescriptor;
-}
-
-namespace rpc {
-class Messenger;
-}
-
-namespace tserver {
-class MiniTabletServer;
-}
-
-struct InternalMiniClusterOptions {
-  InternalMiniClusterOptions();
-
-  // Number of master servers.
-  // Default: 1
-  int num_masters;
-
-  // Number of TS to start.
-  // Default: 1
-  int num_tablet_servers;
-
-  // Number of data dirs for each daemon.
-  // Default: 1 (this will place the wals in the same dir)
-  int num_data_dirs;
-
-  // Directory in which to store data.
-  // Default: "", which auto-generates a unique path for this cluster.
-  // The default may only be used from a gtest unit test.
-  std::string data_root;
-
-  MiniCluster::BindMode bind_mode;
-
-  // List of RPC ports for the master to run on.
-  // Defaults to an empty list.
-  // In single-master mode, an empty list implies port 0 (transient port).
-  // In multi-master mode, an empty list is illegal and will result in a CHECK failure.
-  std::vector<uint16_t> master_rpc_ports;
-
-  // List of RPC ports for the tservers to run on.
-  // Defaults to an empty list.
-  // When adding a tablet server to the cluster via AddTabletServer(), if the
-  // index of that tablet server in the cluster is greater than the number of
-  // elements in this list, a transient port (port 0) will be used.
-  std::vector<uint16_t> tserver_rpc_ports;
-};
-
-// An in-process cluster with a MiniMaster and a configurable
-// number of MiniTabletServers for use in tests.
-class InternalMiniCluster : public MiniCluster {
- public:
-  InternalMiniCluster(Env* env, InternalMiniClusterOptions options);
-  virtual ~InternalMiniCluster();
-
-  // Start a cluster with a Master and 'num_tablet_servers' TabletServers.
-  // All servers run on the loopback interface with ephemeral ports.
-  Status Start() override;
-
-  // Like the previous method but performs initialization synchronously, i.e.
-  // this will wait for all TS's to be started and initialized. Tests should
-  // use this if they interact with tablets immediately after Start();
-  Status StartSync();
-
-  void ShutdownNodes(ClusterNodes nodes) override;
-
-  // Setup a consensus configuration of distributed masters, with count specified in
-  // 'options'. Requires that a reserve RPC port is specified in
-  // 'options' for each master.
-  Status StartDistributedMasters();
-
-  // Add a new standalone master to the cluster. The new master is started.
-  Status StartSingleMaster();
-
-  // Add a new TS to the cluster. The new TS is started.
-  // Requires that the master is already running.
-  Status AddTabletServer();
-
-  // If this cluster is configured for a single non-distributed
-  // master, return the single master. Exits with a CHECK failure if
-  // there are multiple masters.
-  master::MiniMaster* mini_master() const {
-    CHECK_EQ(mini_masters_.size(), 1);
-    return mini_master(0);
-  }
-
-  // Returns the Master at index 'idx' for this InternalMiniCluster.
-  master::MiniMaster* mini_master(int idx) const;
-
-  // Return number of mini masters.
-  int num_masters() const override {
-    return mini_masters_.size();
-  }
-
-  // Returns the TabletServer at index 'idx' of this InternalMiniCluster.
-  // 'idx' must be between 0 and 'num_tablet_servers' -1.
-  tserver::MiniTabletServer* mini_tablet_server(int idx) const;
-
-  int num_tablet_servers() const override {
-    return mini_tablet_servers_.size();
-  }
-
-  BindMode bind_mode() const override {
-    return opts_.bind_mode;
-  }
-
-  std::vector<uint16_t> master_rpc_ports() const override {
-    return opts_.master_rpc_ports;
-  }
-
-  std::vector<HostPort> master_rpc_addrs() const override;
-
-  std::string GetMasterFsRoot(int idx) const;
-
-  std::string GetTabletServerFsRoot(int idx) const;
-
-  // Wait until the number of registered tablet servers reaches the given
-  // count on all masters. Returns Status::TimedOut if the desired count is not
-  // achieved within kRegistrationWaitTimeSeconds.
-  enum class MatchMode {
-    // Ensure that the tservers retrieved from each master match up against the
-    // tservers defined in this cluster. The matching is done via
-    // NodeInstancePBs comparisons. If even one match fails, the retrieved
-    // response is considered to be malformed and is retried.
-    //
-    // Note: tservers participate in matching even if they are shut down.
-    MATCH_TSERVERS,
-
-    // Do not perform any matching on the retrieved tservers.
-    DO_NOT_MATCH_TSERVERS,
-  };
-  Status WaitForTabletServerCount(int count) const;
-  Status WaitForTabletServerCount(int count, MatchMode mode,
-                                  std::vector<std::shared_ptr<master::TSDescriptor>>* descs) const;
-
-  Status CreateClient(client::KuduClientBuilder* builder,
-                      client::sp::shared_ptr<client::KuduClient>* client) const override;
-
-  // Determine the leader master of the cluster. Upon successful completion,
-  // sets 'idx' to the leader master's index. The result index index can be used
-  // as an argument for calls to mini_master().
-  //
-  // It's possible to use 'nullptr' instead of providing a valid placeholder
-  // for the result master index. That's for use cases when it's enough
-  // to determine if the cluster has established leader master
-  // without intent to get the actual index.
-  //
-  // Note: if a leader election occurs after this method is executed, the
-  // last result may not be valid.
-  Status GetLeaderMasterIndex(int* idx) const;
-
-  std::shared_ptr<rpc::Messenger> messenger() const override;
-  std::shared_ptr<master::MasterServiceProxy> master_proxy() const override;
-  std::shared_ptr<master::MasterServiceProxy> master_proxy(int idx) const override;
-
- private:
-  enum {
-    kRegistrationWaitTimeSeconds = 15,
-    kMasterStartupWaitTimeSeconds = 30,
-  };
-
-  Env* const env_;
-
-  InternalMiniClusterOptions opts_;
-
-  bool running_;
-
-  std::vector<std::shared_ptr<master::MiniMaster> > mini_masters_;
-  std::vector<std::shared_ptr<tserver::MiniTabletServer> > mini_tablet_servers_;
-
-  std::shared_ptr<rpc::Messenger> messenger_;
-
-  DISALLOW_COPY_AND_ASSIGN(InternalMiniCluster);
-};
-
-} // namespace kudu

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/linked_list-test-util.h
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/linked_list-test-util.h b/src/kudu/integration-tests/linked_list-test-util.h
index ccc00d7..5bcf348 100644
--- a/src/kudu/integration-tests/linked_list-test-util.h
+++ b/src/kudu/integration-tests/linked_list-test-util.h
@@ -36,7 +36,7 @@
 #include "kudu/gutil/strings/split.h"
 #include "kudu/gutil/strings/substitute.h"
 #include "kudu/gutil/walltime.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/tablet/tablet.h"
 #include "kudu/util/atomic.h"
 #include "kudu/util/blocking_queue.h"
@@ -304,7 +304,7 @@ class ScopedRowUpdater {
 // linked list test.
 class PeriodicWebUIChecker {
  public:
-  PeriodicWebUIChecker(const ExternalMiniCluster& cluster,
+  PeriodicWebUIChecker(const cluster::ExternalMiniCluster& cluster,
                        const std::string& tablet_id, MonoDelta period)
       : period_(period), is_running_(true) {
     // List of master and ts web pages to fetch

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/linked_list-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/linked_list-test.cc b/src/kudu/integration-tests/linked_list-test.cc
index dd8a52f..f7479d7 100644
--- a/src/kudu/integration-tests/linked_list-test.cc
+++ b/src/kudu/integration-tests/linked_list-test.cc
@@ -47,22 +47,16 @@
 #include "kudu/gutil/gscoped_ptr.h"
 #include "kudu/gutil/port.h"
 #include "kudu/integration-tests/cluster_itest_util.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/linked_list-test-util.h"
-#include "kudu/integration-tests/mini_cluster.h"
 #include "kudu/integration-tests/ts_itest-base.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
+#include "kudu/mini-cluster/mini_cluster.h"
 #include "kudu/tserver/tablet_server-test-base.h"
 #include "kudu/util/monotime.h"
 #include "kudu/util/status.h"
 #include "kudu/util/test_macros.h"
 #include "kudu/util/test_util.h"
 
-using kudu::client::KuduClient;
-using kudu::client::sp::shared_ptr;
-using kudu::itest::TServerDetails;
-using std::string;
-using std::vector;
-
 DEFINE_int32(seconds_to_run, 5, "Number of seconds for which to run the test");
 
 DEFINE_int32(num_chains, 50, "Number of parallel chains to generate");
@@ -79,7 +73,14 @@ namespace kudu {
 
 namespace client {
 class KuduClient;
-}
+} // namespace client
+
+using client::KuduClient;
+using client::sp::shared_ptr;
+using cluster::ClusterNodes;
+using itest::TServerDetails;
+using std::string;
+using std::vector;
 
 class LinkedListTest : public tserver::TabletServerIntegrationTestBase {
  public:

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/log-rolling-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/log-rolling-itest.cc b/src/kudu/integration-tests/log-rolling-itest.cc
index 7eb3a45..a23719b 100644
--- a/src/kudu/integration-tests/log-rolling-itest.cc
+++ b/src/kudu/integration-tests/log-rolling-itest.cc
@@ -26,7 +26,7 @@
 #include <gtest/gtest.h>
 
 #include "kudu/gutil/strings/substitute.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/util/env.h"
 #include "kudu/util/status.h"
 #include "kudu/util/test_macros.h"
@@ -38,6 +38,9 @@ using strings::Substitute;
 
 namespace kudu {
 
+using cluster::ExternalMiniCluster;
+using cluster::ExternalMiniClusterOptions;
+
 class LogRollingITest : public KuduTest {};
 
 static int64_t CountInfoLogs(const string& log_dir) {

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/log_verifier.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/log_verifier.cc b/src/kudu/integration-tests/log_verifier.cc
index 668fa4b..58f960e 100644
--- a/src/kudu/integration-tests/log_verifier.cc
+++ b/src/kudu/integration-tests/log_verifier.cc
@@ -40,8 +40,8 @@
 #include "kudu/gutil/map-util.h"
 #include "kudu/gutil/ref_counted.h"
 #include "kudu/gutil/strings/substitute.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/external_mini_cluster_fs_inspector.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/util/env.h"
 #include "kudu/util/metrics.h"
 #include "kudu/util/status.h"
@@ -56,6 +56,8 @@ using strings::Substitute;
 
 namespace kudu {
 
+using cluster::ExternalMiniCluster;
+using cluster::ExternalTabletServer;
 using consensus::OpId;
 using log::LogReader;
 using itest::ExternalMiniClusterFsInspector;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/log_verifier.h
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/log_verifier.h b/src/kudu/integration-tests/log_verifier.h
index 4f95235..7f3d293 100644
--- a/src/kudu/integration-tests/log_verifier.h
+++ b/src/kudu/integration-tests/log_verifier.h
@@ -26,8 +26,11 @@
 
 namespace kudu {
 
+namespace cluster {
 class ExternalMiniCluster;
 class ExternalTabletServer;
+} // namespace cluster
+
 class FsManager;
 
 namespace consensus {
@@ -37,7 +40,7 @@ class OpId;
 // Verifies correctness of the logs in an external mini-cluster.
 class LogVerifier {
  public:
-  explicit LogVerifier(ExternalMiniCluster* cluster);
+  explicit LogVerifier(cluster::ExternalMiniCluster* cluster);
   ~LogVerifier();
 
   // Verify that, for every tablet in the cluster, the logs of each of that tablet's replicas
@@ -55,20 +58,21 @@ class LogVerifier {
 
   // Scans the WAL on the given tablet server to find the COMMIT message with the highest
   // index.
-  Status ScanForHighestCommittedOpIdInLog(ExternalTabletServer* ets,
+  Status ScanForHighestCommittedOpIdInLog(cluster::ExternalTabletServer* ets,
                                           const std::string& tablet_id,
                                           consensus::OpId* commit_id);
 
  private:
   // Open an FsManager for the given tablet server.
-  Status OpenFsManager(ExternalTabletServer* ets, std::unique_ptr<FsManager>* fs);
+  Status OpenFsManager(cluster::ExternalTabletServer* ets,
+                       std::unique_ptr<FsManager>* fs);
 
   // Scan the WALs for tablet 'tablet_id' on the given 'fs'. Sets entries
   // in '*index_to_term' for each COMMIT entry found in the WALs.
   Status ScanForCommittedOpIds(FsManager* fs, const std::string& tablet_id,
                                std::map<int64_t, int64_t>* index_to_term);
 
-  ExternalMiniCluster* const cluster_;
+  cluster::ExternalMiniCluster* const cluster_;
 
   DISALLOW_COPY_AND_ASSIGN(LogVerifier);
 };

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/master-stress-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/master-stress-test.cc b/src/kudu/integration-tests/master-stress-test.cc
index 7efd5d7..3ad044d 100644
--- a/src/kudu/integration-tests/master-stress-test.cc
+++ b/src/kudu/integration-tests/master-stress-test.cc
@@ -34,9 +34,9 @@
 #include "kudu/common/wire_protocol.h"
 #include "kudu/gutil/strings/substitute.h"
 #include "kudu/gutil/strings/util.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/master/master.pb.h"
 #include "kudu/master/master.proxy.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/rpc/messenger.h"
 #include "kudu/rpc/rpc_controller.h"
 #include "kudu/util/atomic.h"
@@ -67,9 +67,11 @@ using client::KuduClientBuilder;
 using client::KuduColumnSchema;
 using client::KuduSchema;
 using client::KuduSchemaBuilder;
-using client::KuduTable;
 using client::KuduTableAlterer;
 using client::KuduTableCreator;
+using cluster::ExternalMaster;
+using cluster::ExternalMiniCluster;
+using cluster::ExternalMiniClusterOptions;
 using master::MasterServiceProxy;
 using master::ListTablesRequestPB;
 using master::ListTablesResponsePB;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/master_cert_authority-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/master_cert_authority-itest.cc b/src/kudu/integration-tests/master_cert_authority-itest.cc
index e8239c2..109f3f0 100644
--- a/src/kudu/integration-tests/master_cert_authority-itest.cc
+++ b/src/kudu/integration-tests/master_cert_authority-itest.cc
@@ -26,12 +26,12 @@
 #include "kudu/common/wire_protocol.pb.h"
 #include "kudu/gutil/gscoped_ptr.h"
 #include "kudu/gutil/port.h"
-#include "kudu/integration-tests/internal_mini_cluster.h"
 #include "kudu/master/master.h"
 #include "kudu/master/master.pb.h"
 #include "kudu/master/master.proxy.h"
 #include "kudu/master/master_cert_authority.h"
 #include "kudu/master/mini_master.h"
+#include "kudu/mini-cluster/internal_mini_cluster.h"
 #include "kudu/rpc/messenger.h"
 #include "kudu/rpc/rpc_controller.h"
 #include "kudu/security/ca/cert_management.h"
@@ -50,6 +50,8 @@ using std::shared_ptr;
 
 namespace kudu {
 
+using cluster::InternalMiniCluster;
+using cluster::InternalMiniClusterOptions;
 using security::ca::CertRequestGenerator;
 using security::Cert;
 using security::CertSignRequest;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/master_failover-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/master_failover-itest.cc b/src/kudu/integration-tests/master_failover-itest.cc
index 6780449..01d9c32 100644
--- a/src/kudu/integration-tests/master_failover-itest.cc
+++ b/src/kudu/integration-tests/master_failover-itest.cc
@@ -33,8 +33,8 @@
 #include "kudu/gutil/strings/split.h"
 #include "kudu/gutil/strings/strip.h"
 #include "kudu/gutil/strings/substitute.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/master/sys_catalog.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/util/metrics.h"
 #include "kudu/util/monotime.h"
 #include "kudu/util/net/net_util.h"
@@ -55,6 +55,11 @@ namespace client {
 
 const int kNumTabletServerReplicas = 3;
 
+using cluster::ExternalDaemon;
+using cluster::ExternalMaster;
+using cluster::ExternalMiniCluster;
+using cluster::ExternalMiniClusterOptions;
+using cluster::ScopedResumeExternalDaemon;
 using sp::shared_ptr;
 using std::set;
 using std::string;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/master_migration-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/master_migration-itest.cc b/src/kudu/integration-tests/master_migration-itest.cc
index d58d419..f0a43f4 100644
--- a/src/kudu/integration-tests/master_migration-itest.cc
+++ b/src/kudu/integration-tests/master_migration-itest.cc
@@ -30,9 +30,9 @@
 #include "kudu/gutil/port.h"
 #include "kudu/gutil/strings/strip.h"
 #include "kudu/gutil/strings/substitute.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
-#include "kudu/integration-tests/mini_cluster.h"
 #include "kudu/master/sys_catalog.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
+#include "kudu/mini-cluster/mini_cluster.h"
 #include "kudu/util/env.h"
 #include "kudu/util/net/net_util.h"
 #include "kudu/util/path_util.h"
@@ -50,6 +50,9 @@ using kudu::client::KuduSchemaBuilder;
 using kudu::client::KuduTable;
 using kudu::client::KuduTableCreator;
 using kudu::client::sp::shared_ptr;
+using kudu::cluster::ExternalMiniCluster;
+using kudu::cluster::ExternalMiniClusterOptions;
+using kudu::cluster::ScopedResumeExternalDaemon;
 using kudu::master::SysCatalogTable;
 using std::pair;
 using std::string;
@@ -196,7 +199,8 @@ TEST_F(MasterMigrationTest, TestEndToEndMigration) {
   // Bring down the old cluster configuration and bring up the new one.
   cluster_->Shutdown();
   ExternalMiniClusterOptions opts;
-  opts.bind_mode = MiniCluster::LOOPBACK; // Required since we use 127.0.0.1 in the config above.
+  // Required since we use 127.0.0.1 in the config above.
+  opts.bind_mode = cluster::MiniCluster::LOOPBACK;
   opts.master_rpc_ports = kMasterRpcPorts;
   opts.num_masters = kMasterRpcPorts.size();
   ExternalMiniCluster migrated_cluster(std::move(opts));

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/master_replication-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/master_replication-itest.cc b/src/kudu/integration-tests/master_replication-itest.cc
index e58fe25..80728ad 100644
--- a/src/kudu/integration-tests/master_replication-itest.cc
+++ b/src/kudu/integration-tests/master_replication-itest.cc
@@ -32,12 +32,12 @@
 #include "kudu/gutil/gscoped_ptr.h"
 #include "kudu/gutil/port.h"
 #include "kudu/gutil/ref_counted.h"
-#include "kudu/integration-tests/internal_mini_cluster.h"
 #include "kudu/master/catalog_manager.h"
 #include "kudu/master/master.h"
 #include "kudu/master/master.pb.h"
 #include "kudu/master/master.proxy.h"
 #include "kudu/master/mini_master.h"
+#include "kudu/mini-cluster/internal_mini_cluster.h"
 #include "kudu/rpc/messenger.h"
 #include "kudu/rpc/rpc_controller.h"
 #include "kudu/util/monotime.h"
@@ -60,12 +60,12 @@ class TSDescriptor;
 using client::KuduClient;
 using client::KuduClientBuilder;
 using client::KuduColumnSchema;
-using client::KuduScanner;
 using client::KuduSchema;
 using client::KuduSchemaBuilder;
-using client::KuduTable;
 using client::KuduTableCreator;
 using client::sp::shared_ptr;
+using cluster::InternalMiniCluster;
+using cluster::InternalMiniClusterOptions;
 
 const char * const kTableId1 = "testMasterReplication-1";
 const char * const kTableId2 = "testMasterReplication-2";

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/mini_cluster.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/mini_cluster.cc b/src/kudu/integration-tests/mini_cluster.cc
deleted file mode 100644
index 06fe10a..0000000
--- a/src/kudu/integration-tests/mini_cluster.cc
+++ /dev/null
@@ -1,55 +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.
-
-#include "kudu/integration-tests/mini_cluster.h"
-
-#include <unistd.h>
-
-#include <cstdint>
-#include <ostream>
-#include <string>
-
-#include <glog/logging.h>
-
-#include "kudu/gutil/strings/substitute.h"
-
-using std::string;
-using strings::Substitute;
-
-namespace kudu {
-
-string MiniCluster::GetBindIpForDaemon(DaemonType type, int index, BindMode bind_mode) {
-  switch (bind_mode) {
-    case UNIQUE_LOOPBACK: {
-      // IP address last octet range: [1 - 254].
-      uint8_t last_octet = (type == TSERVER) ? index + 1 : UINT8_MAX - 1 - index;
-      CHECK_GE(last_octet, 1);
-      CHECK_LE(last_octet, 254);
-      pid_t p = getpid();
-      CHECK_LE(p, UINT16_MAX) << "Cannot run on systems with >16-bit pid";
-      return Substitute("127.$0.$1.$2", p >> 8, p & 0xff, last_octet);
-    }
-    case WILDCARD:
-      return kWildcardIpAddr;
-    case LOOPBACK:
-      return kLoopbackIpAddr;
-    default:
-      LOG(FATAL) << bind_mode;
-  }
-}
-
-} // namespace kudu

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/mini_cluster.h
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/mini_cluster.h b/src/kudu/integration-tests/mini_cluster.h
deleted file mode 100644
index 267d9d3..0000000
--- a/src/kudu/integration-tests/mini_cluster.h
+++ /dev/null
@@ -1,158 +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.
-#pragma once
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "kudu/client/shared_ptr.h"
-#include "kudu/util/status.h"
-
-namespace kudu {
-
-class HostPort;
-
-namespace client {
-class KuduClient;
-class KuduClientBuilder;
-} // namespace client
-
-namespace master {
-class MasterServiceProxy;
-} // namespace master
-
-namespace rpc {
-class Messenger;
-} // namespace rpc
-
-// Mode to which node types a certain action (like Shutdown()) should apply.
-enum class ClusterNodes {
-  ALL,
-  MASTERS_ONLY,
-  TS_ONLY
-};
-
-// Base class for MiniCluster implementations. Provides some commonly-used
-// virtual methods that allow for abstracting the details of whether the
-// mini-cluster implementation is in-process or out-of-process.
-class MiniCluster {
- public:
-  // BindMode lets you specify the socket binding mode for RPC and/or HTTP server.
-  // A) LOOPBACK binds each server to loopback ip address "127.0.0.1".
-  //
-  // B) WILDCARD specifies "0.0.0.0" as the ip to bind to, which means sockets
-  // can be bound to any interface on the local host.
-  // For example, if a host has two interfaces with addresses
-  // 192.168.0.10 and 192.168.0.11, the server process can accept connection
-  // requests addressed to 192.168.0.10 or 192.168.0.11.
-  //
-  // C) UNIQUE_LOOPBACK binds each tablet server to a different loopback address.
-  // This affects the server's RPC server, and also forces the server to
-  // only use this IP address for outgoing socket connections as well.
-  // This allows the use of iptables on the localhost to simulate network
-  // partitions.
-  //
-  // The addresses used are 127.<A>.<B>.<C> where:
-  // - <A,B> are the high and low bytes of the pid of the process running the
-  //   minicluster (not the daemon itself).
-  // - <C> is the index of the server within this minicluster.
-  //
-  // This requires that the system is set up such that processes may bind
-  // to any IP address in the localhost netblock (127.0.0.0/8). This seems
-  // to be the case on common Linux distributions. You can verify by running
-  // 'ip addr | grep 127.0.0.1' and checking that the address is listed as
-  // '127.0.0.1/8'.
-  //
-  // Note: UNIQUE_LOOPBACK is not supported on macOS.
-  //
-  // Default: UNIQUE_LOOPBACK on Linux, LOOPBACK on macOS.
-  enum BindMode {
-    UNIQUE_LOOPBACK,
-    WILDCARD,
-    LOOPBACK
-  };
-
-#if defined(__APPLE__)
-  static constexpr const BindMode kDefaultBindMode = BindMode::LOOPBACK;
-#else
-  static constexpr const BindMode kDefaultBindMode = BindMode::UNIQUE_LOOPBACK;
-#endif
-
-  enum DaemonType {
-    MASTER,
-    TSERVER
-  };
-
-  static constexpr const char* const kWildcardIpAddr = "0.0.0.0";
-  static constexpr const char* const kLoopbackIpAddr = "127.0.0.1";
-
-  MiniCluster() {}
-  virtual ~MiniCluster() {}
-
-  // Start the cluster.
-  virtual Status Start() = 0;
-
-  // Convenience method for shutting down the whole cluster.
-  virtual void Shutdown() final {
-    ShutdownNodes(ClusterNodes::ALL);
-  }
-
-  // Shuts down the whole cluster or part of it, depending on the selected
-  // 'nodes'.
-  virtual void ShutdownNodes(ClusterNodes nodes) = 0;
-
-  virtual int num_masters() const = 0;
-
-  virtual int num_tablet_servers() const = 0;
-
-  virtual BindMode bind_mode() const = 0;
-
-  virtual std::vector<uint16_t> master_rpc_ports() const = 0;
-
-  virtual std::vector<HostPort> master_rpc_addrs() const = 0;
-
-  // Create a client configured to talk to this cluster. 'builder' may contain
-  // override options for the client. The master address will be overridden to
-  // talk to the running master(s). If 'builder' is a nullptr, default options
-  // will be used.
-  //
-  // REQUIRES: the cluster must have already been Start()ed.
-  virtual Status CreateClient(client::KuduClientBuilder* builder,
-                              client::sp::shared_ptr<client::KuduClient>* client) const = 0;
-
-  // Return a messenger for use by clients.
-  virtual std::shared_ptr<rpc::Messenger> messenger() const = 0;
-
-  // If the cluster is configured for a single non-distributed master,
-  // return a proxy to that master. Requires that the single master is
-  // running.
-  virtual std::shared_ptr<master::MasterServiceProxy> master_proxy() const = 0;
-
-  // Returns an RPC proxy to the master at 'idx'. Requires that the
-  // master at 'idx' is running.
-  virtual std::shared_ptr<master::MasterServiceProxy> master_proxy(int idx) const = 0;
-
- protected:
-  // Return the IP address that the daemon with the given index will bind to.
-  // If bind_mode is LOOPBACK, this will be 127.0.0.1 and if it is WILDCARD it
-  // will be 0.0.0.0. Otherwise, it is another IP in the local netblock.
-  static std::string GetBindIpForDaemon(DaemonType type, int index, BindMode bind_mode);
-};
-
-} // namespace kudu

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/minidump_generation-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/minidump_generation-itest.cc b/src/kudu/integration-tests/minidump_generation-itest.cc
index 9e51a95..6dccc45 100644
--- a/src/kudu/integration-tests/minidump_generation-itest.cc
+++ b/src/kudu/integration-tests/minidump_generation-itest.cc
@@ -20,26 +20,26 @@
 #include <string>
 #include <vector>
 
-#include <gflags/gflags_declare.h>
 #include <gtest/gtest.h>
 
 #include "kudu/gutil/strings/substitute.h"
 #include "kudu/integration-tests/external_mini_cluster-itest-base.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/util/env.h"
 #include "kudu/util/path_util.h"
 #include "kudu/util/subprocess.h"
 #include "kudu/util/test_macros.h"
 #include "kudu/util/test_util.h"
 
-DECLARE_string(minidump_path);
-
 using std::string;
 using std::vector;
 using strings::Substitute;
 
 namespace kudu {
 
+using cluster::ExternalMaster;
+using cluster::ExternalTabletServer;
+
 // Test the creation of minidumps upon process crash.
 class MinidumpGenerationITest : public ExternalMiniClusterITestBase {
  protected:

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/multidir_cluster-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/multidir_cluster-itest.cc b/src/kudu/integration-tests/multidir_cluster-itest.cc
index 19a288c..41cbd3c 100644
--- a/src/kudu/integration-tests/multidir_cluster-itest.cc
+++ b/src/kudu/integration-tests/multidir_cluster-itest.cc
@@ -25,9 +25,9 @@
 
 #include "kudu/gutil/map-util.h"
 #include "kudu/integration-tests/external_mini_cluster-itest-base.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/external_mini_cluster_fs_inspector.h"
 #include "kudu/integration-tests/test_workload.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/util/path_util.h"
 #include "kudu/util/status.h"
 #include "kudu/util/test_macros.h"
@@ -35,6 +35,7 @@
 
 namespace kudu {
 
+using cluster::ExternalTabletServer;
 using std::map;
 using std::string;
 using std::vector;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/open-readonly-fs-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/open-readonly-fs-itest.cc b/src/kudu/integration-tests/open-readonly-fs-itest.cc
index c4b9b92..6ccdbff 100644
--- a/src/kudu/integration-tests/open-readonly-fs-itest.cc
+++ b/src/kudu/integration-tests/open-readonly-fs-itest.cc
@@ -33,7 +33,7 @@
 #include "kudu/common/partial_row.h"
 #include "kudu/fs/fs_manager.h"
 #include "kudu/gutil/strings/substitute.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/util/env.h"
 #include "kudu/util/monotime.h"
 #include "kudu/util/random.h"
@@ -50,6 +50,8 @@ using kudu::client::KuduTable;
 using kudu::client::KuduTableCreator;
 using kudu::client::KuduWriteOperation;
 using kudu::client::sp::shared_ptr;
+using kudu::cluster::ExternalMiniCluster;
+using kudu::cluster::ExternalMiniClusterOptions;
 
 using std::unique_ptr;
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/raft_config_change-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/raft_config_change-itest.cc b/src/kudu/integration-tests/raft_config_change-itest.cc
index a7bc9e8..ae5bb88 100644
--- a/src/kudu/integration-tests/raft_config_change-itest.cc
+++ b/src/kudu/integration-tests/raft_config_change-itest.cc
@@ -30,10 +30,10 @@
 #include "kudu/gutil/strings/substitute.h"
 #include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/integration-tests/external_mini_cluster-itest-base.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/external_mini_cluster_fs_inspector.h"
 #include "kudu/integration-tests/test_workload.h"
 #include "kudu/master/master.pb.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/util/monotime.h"
 #include "kudu/util/status.h"
 #include "kudu/util/test_macros.h"

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/raft_consensus-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/raft_consensus-itest.cc b/src/kudu/integration-tests/raft_consensus-itest.cc
index 8e4cf8a..5f59b4d 100644
--- a/src/kudu/integration-tests/raft_consensus-itest.cc
+++ b/src/kudu/integration-tests/raft_consensus-itest.cc
@@ -61,12 +61,12 @@
 #include "kudu/gutil/strings/util.h"
 #include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/integration-tests/cluster_verifier.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/external_mini_cluster_fs_inspector.h"
 #include "kudu/integration-tests/log_verifier.h"
 #include "kudu/integration-tests/test_workload.h"
 #include "kudu/integration-tests/ts_itest-base.h"
 #include "kudu/master/master.pb.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/rpc/messenger.h"
 #include "kudu/rpc/rpc_controller.h"
 #include "kudu/server/server_base.pb.h"
@@ -113,6 +113,7 @@ using client::KuduInsert;
 using client::KuduSession;
 using client::KuduTable;
 using client::sp::shared_ptr;
+using cluster::ExternalTabletServer;
 using consensus::ConsensusRequestPB;
 using consensus::ConsensusResponsePB;
 using consensus::ConsensusServiceProxy;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/registration-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/registration-test.cc b/src/kudu/integration-tests/registration-test.cc
index 6fc8902..d330da8 100644
--- a/src/kudu/integration-tests/registration-test.cc
+++ b/src/kudu/integration-tests/registration-test.cc
@@ -32,7 +32,6 @@
 #include "kudu/gutil/gscoped_ptr.h"
 #include "kudu/gutil/ref_counted.h"
 #include "kudu/gutil/strings/substitute.h"
-#include "kudu/integration-tests/internal_mini_cluster.h"
 #include "kudu/master/catalog_manager.h"
 #include "kudu/master/master-test-util.h"
 #include "kudu/master/master.h"
@@ -40,6 +39,7 @@
 #include "kudu/master/mini_master.h"
 #include "kudu/master/sys_catalog.h"
 #include "kudu/master/ts_descriptor.h"
+#include "kudu/mini-cluster/internal_mini_cluster.h"
 #include "kudu/security/test/test_certs.h"
 #include "kudu/security/tls_context.h"
 #include "kudu/security/token_verifier.h"
@@ -70,6 +70,7 @@ using std::vector;
 
 namespace kudu {
 
+using cluster::InternalMiniCluster;
 using master::CatalogManager;
 using master::CreateTableRequestPB;
 using master::CreateTableResponsePB;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/security-faults-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/security-faults-itest.cc b/src/kudu/integration-tests/security-faults-itest.cc
index 41da3a5..ecfa84f 100644
--- a/src/kudu/integration-tests/security-faults-itest.cc
+++ b/src/kudu/integration-tests/security-faults-itest.cc
@@ -35,7 +35,7 @@
 #include "kudu/common/partial_row.h"
 #include "kudu/gutil/gscoped_ptr.h"
 #include "kudu/gutil/strings/substitute.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/security/test/mini_kdc.h"
 #include "kudu/tablet/key_value_test_schema.h"
 #include "kudu/util/monotime.h"
@@ -52,6 +52,8 @@ using kudu::client::KuduSchema;
 using kudu::client::KuduSession;
 using kudu::client::KuduTable;
 using kudu::client::KuduTableCreator;
+using kudu::cluster::ExternalMiniCluster;
+using kudu::cluster::ExternalMiniClusterOptions;
 using std::string;
 using std::unique_ptr;
 using std::vector;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/security-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/security-itest.cc b/src/kudu/integration-tests/security-itest.cc
index dcca26c..74a3ba9 100644
--- a/src/kudu/integration-tests/security-itest.cc
+++ b/src/kudu/integration-tests/security-itest.cc
@@ -22,7 +22,6 @@
 #include <string>
 #include <vector>
 
-#include <gflags/gflags_declare.h>
 #include <glog/logging.h>
 #include <gtest/gtest.h>
 
@@ -35,9 +34,9 @@
 #include "kudu/common/wire_protocol.pb.h"
 #include "kudu/gutil/gscoped_ptr.h"
 #include "kudu/gutil/strings/substitute.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/master/master.pb.h"
 #include "kudu/master/master.proxy.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/rpc/messenger.h"
 #include "kudu/rpc/rpc_controller.h"
 #include "kudu/security/test/mini_kdc.h"
@@ -59,17 +58,14 @@ using kudu::client::KuduSchema;
 using kudu::client::KuduSession;
 using kudu::client::KuduTable;
 using kudu::client::KuduTableCreator;
+using kudu::cluster::ExternalMiniCluster;
+using kudu::cluster::ExternalMiniClusterOptions;
 using kudu::rpc::Messenger;
 using std::string;
 using std::unique_ptr;
 using std::vector;
 using strings::Substitute;
 
-DECLARE_string(keytab_file);
-DECLARE_string(rpc_private_key_file);
-DECLARE_string(rpc_certificate_file);
-DECLARE_string(rpc_ca_certificate_file);
-
 namespace kudu {
 
 class SecurityITest : public KuduTest {

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/security-unknown-tsk-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/security-unknown-tsk-itest.cc b/src/kudu/integration-tests/security-unknown-tsk-itest.cc
index 5875e95..2c13977 100644
--- a/src/kudu/integration-tests/security-unknown-tsk-itest.cc
+++ b/src/kudu/integration-tests/security-unknown-tsk-itest.cc
@@ -40,10 +40,10 @@
 #include "kudu/gutil/gscoped_ptr.h"
 #include "kudu/gutil/stl_util.h"
 #include "kudu/gutil/walltime.h"
-#include "kudu/integration-tests/internal_mini_cluster.h"
 #include "kudu/integration-tests/test_workload.h"
 #include "kudu/master/master.h"
 #include "kudu/master/mini_master.h"
+#include "kudu/mini-cluster/internal_mini_cluster.h"
 #include "kudu/rpc/messenger.h"
 #include "kudu/security/crypto.h"
 #include "kudu/security/openssl_util.h"
@@ -58,7 +58,6 @@
 #include "kudu/util/test_util.h"
 
 DECLARE_bool(rpc_reopen_outbound_connections);
-DECLARE_bool(rpc_trace_negotiation);
 DECLARE_int32(heartbeat_interval_ms);
 
 using std::atomic;
@@ -79,6 +78,8 @@ using client::KuduSession;
 using client::KuduTable;
 using client::KuduTableCreator;
 using client::sp::shared_ptr;
+using cluster::InternalMiniCluster;
+using cluster::InternalMiniClusterOptions;
 using security::DataFormat;
 using security::PrivateKey;
 using security::SignedTokenPB;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/table_locations-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/table_locations-itest.cc b/src/kudu/integration-tests/table_locations-itest.cc
index ddbef72..751a109 100644
--- a/src/kudu/integration-tests/table_locations-itest.cc
+++ b/src/kudu/integration-tests/table_locations-itest.cc
@@ -28,10 +28,10 @@
 #include "kudu/common/schema.h"
 #include "kudu/common/wire_protocol.h"
 #include "kudu/common/wire_protocol.pb.h"
-#include "kudu/integration-tests/internal_mini_cluster.h"
 #include "kudu/master/master.pb.h"
 #include "kudu/master/master.proxy.h"
 #include "kudu/master/mini_master.h"
+#include "kudu/mini-cluster/internal_mini_cluster.h"
 #include "kudu/rpc/messenger.h"
 #include "kudu/rpc/rpc_controller.h"
 #include "kudu/util/monotime.h"
@@ -41,6 +41,8 @@
 #include "kudu/util/test_macros.h"
 #include "kudu/util/test_util.h"
 
+using kudu::cluster::InternalMiniCluster;
+using kudu::cluster::InternalMiniClusterOptions;
 using kudu::pb_util::SecureDebugString;
 using kudu::rpc::Messenger;
 using kudu::rpc::MessengerBuilder;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/tablet_copy-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/tablet_copy-itest.cc b/src/kudu/integration-tests/tablet_copy-itest.cc
index 2bfeefd..88a9350 100644
--- a/src/kudu/integration-tests/tablet_copy-itest.cc
+++ b/src/kudu/integration-tests/tablet_copy-itest.cc
@@ -56,10 +56,10 @@
 #include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/integration-tests/cluster_verifier.h"
 #include "kudu/integration-tests/external_mini_cluster-itest-base.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/external_mini_cluster_fs_inspector.h"
 #include "kudu/integration-tests/test_workload.h"
 #include "kudu/master/master.pb.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/tablet/metadata.pb.h"
 #include "kudu/tablet/tablet.pb.h"
 #include "kudu/tablet/tablet_metadata.h"
@@ -96,6 +96,7 @@ DEFINE_int32(test_delete_leader_num_writer_threads, 1,
 using kudu::client::KuduSchema;
 using kudu::client::KuduSchemaFromSchema;
 using kudu::client::KuduTableCreator;
+using kudu::cluster::ExternalTabletServer;
 using kudu::consensus::COMMITTED_OPID;
 using kudu::consensus::ConsensusMetadataManager;
 using kudu::consensus::ConsensusMetadataPB;
@@ -123,7 +124,6 @@ using std::unordered_map;
 using std::vector;
 using strings::Substitute;
 
-METRIC_DECLARE_entity(tablet);
 METRIC_DECLARE_histogram(handler_latency_kudu_consensus_ConsensusService_UpdateConsensus);
 METRIC_DECLARE_counter(glog_info_messages);
 METRIC_DECLARE_counter(glog_warning_messages);
@@ -132,8 +132,6 @@ METRIC_DECLARE_counter(tablet_copy_bytes_fetched);
 METRIC_DECLARE_counter(tablet_copy_bytes_sent);
 METRIC_DECLARE_gauge_int32(tablet_copy_open_client_sessions);
 METRIC_DECLARE_gauge_int32(tablet_copy_open_source_sessions);
-METRIC_DECLARE_gauge_size(on_disk_data_size);
-METRIC_DECLARE_gauge_size(on_disk_size);
 METRIC_DECLARE_gauge_uint64(log_block_manager_blocks_under_management);
 
 namespace kudu {

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/tablet_copy_client_session-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/tablet_copy_client_session-itest.cc b/src/kudu/integration-tests/tablet_copy_client_session-itest.cc
index 0625905..e24dcb0 100644
--- a/src/kudu/integration-tests/tablet_copy_client_session-itest.cc
+++ b/src/kudu/integration-tests/tablet_copy_client_session-itest.cc
@@ -35,9 +35,9 @@
 #include "kudu/gutil/strings/substitute.h"
 #include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/integration-tests/external_mini_cluster-itest-base.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/external_mini_cluster_fs_inspector.h"
 #include "kudu/integration-tests/test_workload.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/tablet/metadata.pb.h"
 #include "kudu/tablet/tablet.pb.h"
 #include "kudu/tserver/tserver.pb.h"

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/tablet_history_gc-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/tablet_history_gc-itest.cc b/src/kudu/integration-tests/tablet_history_gc-itest.cc
index 7952675..e2ec09b 100644
--- a/src/kudu/integration-tests/tablet_history_gc-itest.cc
+++ b/src/kudu/integration-tests/tablet_history_gc-itest.cc
@@ -50,9 +50,9 @@
 #include "kudu/gutil/port.h"
 #include "kudu/gutil/ref_counted.h"
 #include "kudu/gutil/strings/substitute.h"
-#include "kudu/integration-tests/internal_mini_cluster.h"
 #include "kudu/integration-tests/internal_mini_cluster-itest-base.h"
 #include "kudu/integration-tests/test_workload.h"
+#include "kudu/mini-cluster/internal_mini_cluster.h"
 #include "kudu/tablet/local_tablet_writer.h"
 #include "kudu/tablet/rowset.h"
 #include "kudu/tablet/tablet.h"
@@ -95,7 +95,6 @@ DECLARE_int32(safe_time_max_lag_ms);
 DECLARE_int32(scanner_ttl_ms);
 DECLARE_int32(tablet_history_max_age_sec);
 DECLARE_int32(undo_delta_block_gc_init_budget_millis);
-DECLARE_string(block_manager);
 
 DEFINE_int32(test_num_rounds, 200, "Number of rounds to loop "
                                    "RandomizedTabletHistoryGcITest.TestRandomHistoryGCWorkload");

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/tablet_replacement-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/tablet_replacement-itest.cc b/src/kudu/integration-tests/tablet_replacement-itest.cc
index ab68318..8bdfd3d 100644
--- a/src/kudu/integration-tests/tablet_replacement-itest.cc
+++ b/src/kudu/integration-tests/tablet_replacement-itest.cc
@@ -38,9 +38,9 @@
 #include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/integration-tests/cluster_verifier.h"
 #include "kudu/integration-tests/external_mini_cluster-itest-base.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/external_mini_cluster_fs_inspector.h"
 #include "kudu/integration-tests/test_workload.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/rpc/rpc_controller.h"
 #include "kudu/tablet/metadata.pb.h"
 #include "kudu/tablet/tablet.pb.h"

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/test_workload.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/test_workload.cc b/src/kudu/integration-tests/test_workload.cc
index 12dae45..a1f39ba 100644
--- a/src/kudu/integration-tests/test_workload.cc
+++ b/src/kudu/integration-tests/test_workload.cc
@@ -34,8 +34,8 @@
 #include "kudu/gutil/mathlimits.h"
 #include "kudu/gutil/port.h"
 #include "kudu/gutil/stl_util.h"
+#include "kudu/mini-cluster/mini_cluster.h"
 #include "kudu/tools/data_gen_util.h"
-#include "kudu/integration-tests/mini_cluster.h"
 #include "kudu/util/random.h"
 #include "kudu/util/status.h"
 #include "kudu/util/test_util.h"
@@ -54,6 +54,7 @@ using client::KuduTable;
 using client::KuduTableCreator;
 using client::KuduUpdate;
 using client::sp::shared_ptr;
+using cluster::MiniCluster;
 
 const char* const TestWorkload::kDefaultTableName = "test-workload";
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/test_workload.h
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/test_workload.h b/src/kudu/integration-tests/test_workload.h
index 6e3dc1a..a26cf45 100644
--- a/src/kudu/integration-tests/test_workload.h
+++ b/src/kudu/integration-tests/test_workload.h
@@ -37,9 +37,12 @@
 
 namespace kudu {
 
-class MiniCluster;
 class Status;
 
+namespace cluster {
+class MiniCluster;
+} // namespace cluster
+
 // Utility class for generating a workload against a test cluster.
 //
 // The actual data inserted is random, and thus can't be verified for
@@ -54,7 +57,7 @@ class TestWorkload {
  public:
   static const char* const kDefaultTableName;
 
-  explicit TestWorkload(MiniCluster* cluster);
+  explicit TestWorkload(cluster::MiniCluster* cluster);
   ~TestWorkload();
 
   void set_payload_bytes(int n) {
@@ -208,7 +211,7 @@ class TestWorkload {
   void WriteThread();
   void ReadThread();
 
-  MiniCluster* cluster_;
+  cluster::MiniCluster* cluster_;
   client::KuduClientBuilder client_builder_;
   client::sp::shared_ptr<client::KuduClient> client_;
   ThreadSafeRandom rng_;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/token_signer-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/token_signer-itest.cc b/src/kudu/integration-tests/token_signer-itest.cc
index 5c95914..103b4c7 100644
--- a/src/kudu/integration-tests/token_signer-itest.cc
+++ b/src/kudu/integration-tests/token_signer-itest.cc
@@ -28,9 +28,9 @@
 #include <gtest/gtest.h>
 
 #include "kudu/gutil/walltime.h"
-#include "kudu/integration-tests/internal_mini_cluster.h"
 #include "kudu/master/master.h"
 #include "kudu/master/mini_master.h"
+#include "kudu/mini-cluster/internal_mini_cluster.h"
 #include "kudu/rpc/messenger.h"
 #include "kudu/security/token.pb.h"
 #include "kudu/security/token_signer.h"
@@ -49,6 +49,8 @@ DECLARE_int32(heartbeat_interval_ms);
 using std::string;
 using std::unique_ptr;
 using std::vector;
+using kudu::cluster::InternalMiniCluster;
+using kudu::cluster::InternalMiniClusterOptions;
 using kudu::security::TokenPB;
 using kudu::security::TokenSigningPublicKeyPB;
 using kudu::security::SignedTokenPB;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/tombstoned_voting-imc-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/tombstoned_voting-imc-itest.cc b/src/kudu/integration-tests/tombstoned_voting-imc-itest.cc
index ab070a8..4b440f8 100644
--- a/src/kudu/integration-tests/tombstoned_voting-imc-itest.cc
+++ b/src/kudu/integration-tests/tombstoned_voting-imc-itest.cc
@@ -36,8 +36,8 @@
 #include "kudu/gutil/ref_counted.h"
 #include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/integration-tests/internal_mini_cluster-itest-base.h"
-#include "kudu/integration-tests/internal_mini_cluster.h"
 #include "kudu/integration-tests/test_workload.h"
+#include "kudu/mini-cluster/internal_mini_cluster.h"
 #include "kudu/tablet/metadata.pb.h"
 #include "kudu/tablet/tablet_replica.h"
 #include "kudu/tserver/mini_tablet_server.h"

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/tombstoned_voting-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/tombstoned_voting-itest.cc b/src/kudu/integration-tests/tombstoned_voting-itest.cc
index 978f7fc..575e493 100644
--- a/src/kudu/integration-tests/tombstoned_voting-itest.cc
+++ b/src/kudu/integration-tests/tombstoned_voting-itest.cc
@@ -29,10 +29,10 @@
 #include "kudu/gutil/map-util.h"
 #include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/integration-tests/external_mini_cluster-itest-base.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/external_mini_cluster_fs_inspector.h"
 #include "kudu/integration-tests/test_workload.h"
 #include "kudu/master/master.pb.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/tablet/metadata.pb.h"
 #include "kudu/util/metrics.h"
 #include "kudu/util/monotime.h"
@@ -42,6 +42,8 @@
 
 METRIC_DECLARE_histogram(handler_latency_kudu_master_MasterService_TSHeartbeat);
 
+using kudu::cluster::ExternalMaster;
+using kudu::cluster::ExternalTabletServer;
 using kudu::consensus::MakeOpId;
 using kudu::itest::TServerDetails;
 using kudu::tablet::TABLET_DATA_COPYING;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/tombstoned_voting-stress-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/tombstoned_voting-stress-test.cc b/src/kudu/integration-tests/tombstoned_voting-stress-test.cc
index 2c1cecb..9a6c52e 100644
--- a/src/kudu/integration-tests/tombstoned_voting-stress-test.cc
+++ b/src/kudu/integration-tests/tombstoned_voting-stress-test.cc
@@ -37,9 +37,9 @@
 #include "kudu/gutil/macros.h"
 #include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/integration-tests/external_mini_cluster-itest-base.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/external_mini_cluster_fs_inspector.h"
 #include "kudu/integration-tests/test_workload.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/tablet/metadata.pb.h"
 #include "kudu/util/condition_variable.h"
 #include "kudu/util/monotime.h"

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/ts_itest-base.h
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/ts_itest-base.h b/src/kudu/integration-tests/ts_itest-base.h
index 7346ac3..7ecfba1 100644
--- a/src/kudu/integration-tests/ts_itest-base.h
+++ b/src/kudu/integration-tests/ts_itest-base.h
@@ -29,10 +29,10 @@
 #include "kudu/gutil/strings/split.h"
 #include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/integration-tests/cluster_verifier.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/external_mini_cluster_fs_inspector.h"
 #include "kudu/master/master.pb.h"
 #include "kudu/master/master.proxy.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/tserver/tablet_server-test-base.h"
 #include "kudu/util/pb_util.h"
 #include "kudu/util/random.h"
@@ -85,7 +85,7 @@ class TabletServerIntegrationTestBase : public TabletServerTestBase {
     LOG(INFO) << FLAGS_num_replicas << " replicas per TS";
     LOG(INFO) << "--------------";
 
-    ExternalMiniClusterOptions opts;
+    cluster::ExternalMiniClusterOptions opts;
     opts.num_tablet_servers = FLAGS_num_tablet_servers;
     opts.data_root = GetTestPath(data_root_path);
     opts.num_data_dirs = num_data_dirs;
@@ -110,7 +110,7 @@ class TabletServerIntegrationTestBase : public TabletServerTestBase {
     AddExtraFlags(FLAGS_ts_flags, &opts.extra_tserver_flags);
     AddExtraFlags(FLAGS_master_flags, &opts.extra_master_flags);
 
-    cluster_.reset(new ExternalMiniCluster(std::move(opts)));
+    cluster_.reset(new cluster::ExternalMiniCluster(std::move(opts)));
     ASSERT_OK(cluster_->Start());
     inspect_.reset(new itest::ExternalMiniClusterFsInspector(cluster_.get()));
     CreateTSProxies();
@@ -189,7 +189,7 @@ class TabletServerIntegrationTestBase : public TabletServerTestBase {
     // reached, the wait here is best effort only. That is, if the wait
     // deadline expires, the resulting timeout failure is ignored.
     for (int i = 0; i < cluster_->num_tablet_servers(); i++) {
-      ExternalTabletServer* ts = cluster_->tablet_server(i);
+      cluster::ExternalTabletServer* ts = cluster_->tablet_server(i);
       int expected_tablet_count = 0;
       for (const auto& e : tablet_replicas_) {
         if (ts->uuid() == e.second->uuid()) {
@@ -421,7 +421,7 @@ class TabletServerIntegrationTestBase : public TabletServerTestBase {
 
   Status ShutdownServerWithUUID(const std::string& uuid) {
     for (int i = 0; i < cluster_->num_tablet_servers(); i++) {
-      ExternalTabletServer* ts = cluster_->tablet_server(i);
+      cluster::ExternalTabletServer* ts = cluster_->tablet_server(i);
       if (ts->instance_id().permanent_uuid() == uuid) {
         ts->Shutdown();
         return Status::OK();
@@ -432,7 +432,7 @@ class TabletServerIntegrationTestBase : public TabletServerTestBase {
 
   Status RestartServerWithUUID(const std::string& uuid) {
     for (int i = 0; i < cluster_->num_tablet_servers(); i++) {
-      ExternalTabletServer* ts = cluster_->tablet_server(i);
+      cluster::ExternalTabletServer* ts = cluster_->tablet_server(i);
       if (ts->instance_id().permanent_uuid() == uuid) {
         ts->Shutdown();
         RETURN_NOT_OK(CheckTabletServersAreAlive(tablet_servers_.size()-1));
@@ -541,7 +541,7 @@ class TabletServerIntegrationTestBase : public TabletServerTestBase {
   }
 
  protected:
-  gscoped_ptr<ExternalMiniCluster> cluster_;
+  gscoped_ptr<cluster::ExternalMiniCluster> cluster_;
   gscoped_ptr<itest::ExternalMiniClusterFsInspector> inspect_;
 
   // Maps server uuid to TServerDetails

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/ts_recovery-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/ts_recovery-itest.cc b/src/kudu/integration-tests/ts_recovery-itest.cc
index a70a3ec..e682691 100644
--- a/src/kudu/integration-tests/ts_recovery-itest.cc
+++ b/src/kudu/integration-tests/ts_recovery-itest.cc
@@ -52,8 +52,8 @@
 #include "kudu/integration-tests/cluster_itest_util.h"
 #include "kudu/integration-tests/cluster_verifier.h"
 #include "kudu/integration-tests/external_mini_cluster-itest-base.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/test_workload.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/tablet/metadata.pb.h"
 #include "kudu/tablet/tablet.pb.h"
 #include "kudu/tserver/tserver.pb.h"

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/ts_tablet_manager-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/ts_tablet_manager-itest.cc b/src/kudu/integration-tests/ts_tablet_manager-itest.cc
index 6755065..98b0e26 100644
--- a/src/kudu/integration-tests/ts_tablet_manager-itest.cc
+++ b/src/kudu/integration-tests/ts_tablet_manager-itest.cc
@@ -37,11 +37,11 @@
 #include "kudu/gutil/stl_util.h"
 #include "kudu/gutil/strings/substitute.h"
 #include "kudu/integration-tests/cluster_itest_util.h"
-#include "kudu/integration-tests/internal_mini_cluster.h"
 #include "kudu/integration-tests/test_workload.h"
 #include "kudu/master/master.pb.h"
 #include "kudu/master/master.proxy.h"
 #include "kudu/master/mini_master.h"
+#include "kudu/mini-cluster/internal_mini_cluster.h"
 #include "kudu/rpc/messenger.h"
 #include "kudu/tablet/metadata.pb.h"
 #include "kudu/tablet/tablet_replica.h"
@@ -70,6 +70,8 @@ using client::KuduClient;
 using client::KuduSchema;
 using client::KuduTable;
 using client::KuduTableCreator;
+using cluster::InternalMiniCluster;
+using cluster::InternalMiniClusterOptions;
 using consensus::GetConsensusRole;
 using consensus::RaftPeerPB;
 using itest::SimpleIntKeyKuduSchema;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/update_scan_delta_compact-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/update_scan_delta_compact-test.cc b/src/kudu/integration-tests/update_scan_delta_compact-test.cc
index 2b498cd..f6bcf64 100644
--- a/src/kudu/integration-tests/update_scan_delta_compact-test.cc
+++ b/src/kudu/integration-tests/update_scan_delta_compact-test.cc
@@ -38,8 +38,8 @@
 #include "kudu/gutil/port.h"
 #include "kudu/gutil/ref_counted.h"
 #include "kudu/gutil/strings/strcat.h"
-#include "kudu/integration-tests/internal_mini_cluster.h"
 #include "kudu/master/mini_master.h"
+#include "kudu/mini-cluster/internal_mini_cluster.h"
 #include "kudu/tserver/mini_tablet_server.h"
 #include "kudu/util/async_util.h"
 #include "kudu/util/countdown_latch.h"
@@ -82,6 +82,8 @@ using client::KuduTable;
 using client::KuduTableCreator;
 using client::KuduUpdate;
 using client::sp::shared_ptr;
+using cluster::InternalMiniCluster;
+using cluster::InternalMiniClusterOptions;
 
 // This integration test tries to trigger all the update-related bits while also serving as a
 // foundation for benchmarking. It first inserts 'row_count' rows and then starts two threads,

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/version_migration-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/version_migration-test.cc b/src/kudu/integration-tests/version_migration-test.cc
index 6c87165..26d1244 100644
--- a/src/kudu/integration-tests/version_migration-test.cc
+++ b/src/kudu/integration-tests/version_migration-test.cc
@@ -27,9 +27,9 @@
 #include <gtest/gtest.h>
 
 #include "kudu/client/shared_ptr.h"
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/linked_list-test-util.h"
 #include "kudu/integration-tests/log_verifier.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/util/monotime.h"
 #include "kudu/util/test_macros.h"
 #include "kudu/util/test_util.h"
@@ -54,6 +54,9 @@ const int kNumTabletServers = 3;
 
 namespace kudu {
 
+using cluster::ExternalMiniCluster;
+using cluster::ExternalMiniClusterOptions;
+
 namespace client {
 class KuduClient;
 }

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/integration-tests/webserver-stress-itest.cc
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/webserver-stress-itest.cc b/src/kudu/integration-tests/webserver-stress-itest.cc
index b9503de..08ed172 100644
--- a/src/kudu/integration-tests/webserver-stress-itest.cc
+++ b/src/kudu/integration-tests/webserver-stress-itest.cc
@@ -21,15 +21,17 @@
 
 #include <gtest/gtest.h>
 
-#include "kudu/integration-tests/external_mini_cluster.h"
 #include "kudu/integration-tests/linked_list-test-util.h"
 #include "kudu/integration-tests/test_workload.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
 #include "kudu/util/monotime.h"
 #include "kudu/util/test_macros.h"
 #include "kudu/util/test_util.h"
 
 namespace kudu {
 
+using cluster::ExternalMiniCluster;
+using cluster::ExternalMiniClusterOptions;
 using std::string;
 using std::unique_ptr;
 using std::vector;

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/mini-cluster/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/mini-cluster/CMakeLists.txt b/src/kudu/mini-cluster/CMakeLists.txt
new file mode 100644
index 0000000..e43d10b
--- /dev/null
+++ b/src/kudu/mini-cluster/CMakeLists.txt
@@ -0,0 +1,51 @@
+# 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.
+
+set(MINI_CLUSTER_SRCS
+  external_mini_cluster.cc
+  internal_mini_cluster.cc
+  mini_cluster.cc
+)
+
+add_library(mini-cluster ${MINI_CLUSTER_SRCS})
+target_link_libraries(mini-cluster
+  gflags
+  glog
+  gmock
+  gutil
+  kudu_client
+  kudu_common
+  kudu_curl_util
+  kudu_util
+  krpc
+  master
+  master_proto
+  security-test
+  server_base_proto
+  tablet_proto
+  tserver
+  tserver_proto
+  tserver_service_proto
+  wire_protocol_proto
+)
+add_dependencies(mini-cluster
+  kudu-tserver
+  kudu-master)
+
+# Tests
+set(KUDU_TEST_LINK_LIBS mini-cluster ${KUDU_MIN_TEST_LIBS})
+ADD_KUDU_TEST(external_mini_cluster-test RESOURCE_LOCK "master-rpc-ports")

http://git-wip-us.apache.org/repos/asf/kudu/blob/350c8a79/src/kudu/mini-cluster/external_mini_cluster-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/mini-cluster/external_mini_cluster-test.cc b/src/kudu/mini-cluster/external_mini_cluster-test.cc
new file mode 100644
index 0000000..584591a
--- /dev/null
+++ b/src/kudu/mini-cluster/external_mini_cluster-test.cc
@@ -0,0 +1,213 @@
+// 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.
+
+#include <cstdint>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <glog/logging.h>
+#include <gtest/gtest.h>
+
+#include "kudu/gutil/strings/substitute.h"
+#include "kudu/gutil/strings/util.h"
+#include "kudu/mini-cluster/external_mini_cluster.h"
+#include "kudu/mini-cluster/mini_cluster.h"
+#include "kudu/security/test/mini_kdc.h"
+#include "kudu/util/metrics.h"
+#include "kudu/util/monotime.h"
+#include "kudu/util/net/net_util.h"
+#include "kudu/util/status.h"
+#include "kudu/util/test_macros.h"
+#include "kudu/util/test_util.h"
+
+METRIC_DECLARE_gauge_uint64(threads_running);
+
+namespace kudu {
+
+namespace cluster {
+
+using std::string;
+using strings::Substitute;
+
+enum KerberosMode {
+  WITHOUT_KERBEROS, WITH_KERBEROS
+};
+
+class ExternalMiniClusterTest : public KuduTest,
+                                public testing::WithParamInterface<KerberosMode> {};
+
+INSTANTIATE_TEST_CASE_P(KerberosOnAndOff,
+                        ExternalMiniClusterTest,
+                        ::testing::Values(WITHOUT_KERBEROS, WITH_KERBEROS));
+
+void SmokeTestKerberizedCluster(ExternalMiniClusterOptions opts) {
+  ASSERT_TRUE(opts.enable_kerberos);
+  int num_tservers = opts.num_tablet_servers;
+
+  ExternalMiniCluster cluster(std::move(opts));
+  ASSERT_OK(cluster.Start());
+
+  // Sleep long enough to ensure that the tserver's ticket would have expired
+  // if not for the renewal thread doing its thing.
+  SleepFor(MonoDelta::FromSeconds(16));
+
+  // Re-kinit for the client, since the client's ticket would have expired as well
+  // since the renewal thread doesn't run for the test client.
+  ASSERT_OK(cluster.kdc()->Kinit("test-admin"));
+
+  // Restart the master, and make sure the tserver is still able to reconnect and
+  // authenticate.
+  cluster.master(0)->Shutdown();
+  ASSERT_OK(cluster.master(0)->Restart());
+  // Ensure that all of the tablet servers can register with the masters.
+  ASSERT_OK(cluster.WaitForTabletServerCount(num_tservers, MonoDelta::FromSeconds(30)));
+  cluster.Shutdown();
+}
+
+TEST_F(ExternalMiniClusterTest, TestKerberosReacquire) {
+  if (!AllowSlowTests()) return;
+
+  ExternalMiniClusterOptions opts;
+  opts.enable_kerberos = true;
+  // Set the kerberos ticket lifetime as 15 seconds to force ticket reacquisition every 15 seconds.
+  // Note that we do not renew tickets but always acquire a new one.
+  opts.mini_kdc_options.ticket_lifetime = "15s";
+  opts.num_tablet_servers = 1;
+
+  SmokeTestKerberizedCluster(std::move(opts));
+}
+
+TEST_P(ExternalMiniClusterTest, TestBasicOperation) {
+  ExternalMiniClusterOptions opts;
+  opts.enable_kerberos = GetParam() == WITH_KERBEROS;
+
+  // Hard-coded RPC ports for the masters. This is safe, as this unit test
+  // runs under a resource lock (see CMakeLists.txt in this directory).
+  // TODO(af) we should have a generic method to obtain n free ports.
+  opts.master_rpc_ports = { 11010, 11011, 11012 };
+  opts.num_masters = opts.master_rpc_ports.size();
+  opts.num_tablet_servers = 3;
+
+  ExternalMiniCluster cluster(opts);
+  ASSERT_OK(cluster.Start());
+
+  // Verify each of the masters.
+  for (int i = 0; i < opts.num_masters; i++) {
+    SCOPED_TRACE(i);
+    ExternalMaster* master = CHECK_NOTNULL(cluster.master(i));
+    HostPort master_rpc = master->bound_rpc_hostport();
+    string expected_prefix = Substitute("$0:", cluster.GetBindIpForMaster(i));
+    if (cluster.bind_mode() == MiniCluster::UNIQUE_LOOPBACK) {
+      EXPECT_NE(expected_prefix, "127.0.0.1:") << "Should bind to unique per-server hosts";
+    }
+    EXPECT_TRUE(HasPrefixString(master_rpc.ToString(), expected_prefix)) << master_rpc.ToString();
+
+    HostPort master_http = master->bound_http_hostport();
+    EXPECT_TRUE(HasPrefixString(master_http.ToString(), expected_prefix)) << master_http.ToString();
+
+    // Retrieve a thread metric, which should always be present on any master.
+    int64_t value;
+    ASSERT_OK(master->GetInt64Metric(&METRIC_ENTITY_server,
+                                     "kudu.master",
+                                     &METRIC_threads_running,
+                                     "value",
+                                     &value));
+    EXPECT_GT(value, 0);
+  }
+
+  // Verify each of the tablet servers.
+  for (int i = 0; i < opts.num_tablet_servers; i++) {
+    SCOPED_TRACE(i);
+    ExternalTabletServer* ts = CHECK_NOTNULL(cluster.tablet_server(i));
+    HostPort ts_rpc = ts->bound_rpc_hostport();
+    string expected_prefix = Substitute("$0:", cluster.GetBindIpForTabletServer(i));
+    if (cluster.bind_mode() == MiniCluster::UNIQUE_LOOPBACK) {
+      EXPECT_NE(expected_prefix, "127.0.0.1:") << "Should bind to unique per-server hosts";
+    }
+    EXPECT_TRUE(HasPrefixString(ts_rpc.ToString(), expected_prefix)) << ts_rpc.ToString();
+
+    HostPort ts_http = ts->bound_http_hostport();
+    EXPECT_TRUE(HasPrefixString(ts_http.ToString(), expected_prefix)) << ts_http.ToString();
+
+    // Retrieve a thread metric, which should always be present on any TS.
+    int64_t value;
+    ASSERT_OK(ts->GetInt64Metric(&METRIC_ENTITY_server,
+                                 "kudu.tabletserver",
+                                 &METRIC_threads_running,
+                                 "value",
+                                 &value));
+    EXPECT_GT(value, 0);
+  }
+
+  // Ensure that all of the tablet servers can register with the masters.
+  ASSERT_OK(cluster.WaitForTabletServerCount(opts.num_tablet_servers, MonoDelta::FromSeconds(30)));
+
+  // Restart a master and a tablet server. Make sure they come back up with the same ports.
+  ExternalMaster* master = cluster.master(0);
+  HostPort master_rpc = master->bound_rpc_hostport();
+  HostPort master_http = master->bound_http_hostport();
+
+  master->Shutdown();
+  ASSERT_OK(master->Restart());
+
+  ASSERT_EQ(master_rpc.ToString(), master->bound_rpc_hostport().ToString());
+  ASSERT_EQ(master_http.ToString(), master->bound_http_hostport().ToString());
+
+  ExternalTabletServer* ts = cluster.tablet_server(0);
+
+  HostPort ts_rpc = ts->bound_rpc_hostport();
+  HostPort ts_http = ts->bound_http_hostport();
+
+  ts->Shutdown();
+  ASSERT_OK(ts->Restart());
+
+  ASSERT_EQ(ts_rpc.ToString(), ts->bound_rpc_hostport().ToString());
+  ASSERT_EQ(ts_http.ToString(), ts->bound_http_hostport().ToString());
+
+  // Verify that, in a Kerberized cluster, if we drop our Kerberos environment,
+  // we can't make RPCs to a server.
+  if (opts.enable_kerberos) {
+    ASSERT_OK(cluster.kdc()->Kdestroy());
+    Status s = cluster.SetFlag(ts, "foo", "bar");
+    // The error differs depending on the version of Kerberos, so we match
+    // either message.
+    ASSERT_STR_MATCHES(s.ToString(), "Not authorized.*"
+                       "(Credentials cache file.*not found|"
+                        "No Kerberos credentials|"
+                        ".*No such file or directory)");
+  }
+
+  // Test that if we inject a fault into a tablet server's boot process
+  // ExternalTabletServer::Restart() still returns OK, even if the tablet server crashed.
+  ts->Shutdown();
+  ts->mutable_flags()->push_back("--fault_before_start=1.0");
+  ASSERT_OK(ts->Restart());
+  ASSERT_FALSE(ts->IsProcessAlive());
+  // Since the process should have already crashed, waiting for an injected crash with no
+  // timeout should still return OK.
+  ASSERT_OK(ts->WaitForInjectedCrash(MonoDelta::FromSeconds(0)));
+  ts->mutable_flags()->pop_back();
+  ts->Shutdown();
+  ASSERT_OK(ts->Restart());
+  ASSERT_TRUE(ts->IsProcessAlive());
+
+  cluster.Shutdown();
+}
+
+} // namespace cluster
+} // namespace kudu