HBASE-15792 Add on a test for locating a region

Summary:
Add on a TestUtil class that will start a cluster.
Add on the ability to run a shell command in a cluster.
Throw an exception if the table isn't the correct table when looking up a 
region.
Add a test to test that getting a region throws when the table doesn't exist.
Add a test to make sure that getting a region location works when the table 
does exist.

Test Plan:
Added unit tests.
Changed unit tests.

Differential Revision: https://reviews.facebook.net/D57891


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

Branch: refs/heads/HBASE-14850
Commit: 92db344d4deff83dcf1e17023b1fa4a593c82bde
Parents: 1e69eda
Author: Elliott Clark <ecl...@apache.org>
Authored: Mon May 9 12:06:54 2016 -0700
Committer: Elliott Clark <ecl...@apache.org>
Committed: Fri May 13 14:36:28 2016 -0700

----------------------------------------------------------------------
 hbase-native-client/bin/start-local-hbase.sh    |  5 +-
 .../connection/client-handler.cc                |  3 +-
 hbase-native-client/core/BUCK                   |  4 +-
 hbase-native-client/core/client.cc              |  1 +
 hbase-native-client/core/location-cache-test.cc | 29 ++++++++++-
 hbase-native-client/core/location-cache.cc      | 10 +++-
 hbase-native-client/core/location-cache.h       | 10 +++-
 hbase-native-client/core/test-env.cc            | 45 ----------------
 hbase-native-client/test-util/BUCK              | 29 +++++++++++
 hbase-native-client/test-util/test-util.cc      | 54 ++++++++++++++++++++
 hbase-native-client/test-util/test-util.h       | 51 ++++++++++++++++++
 11 files changed, 187 insertions(+), 54 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/92db344d/hbase-native-client/bin/start-local-hbase.sh
----------------------------------------------------------------------
diff --git a/hbase-native-client/bin/start-local-hbase.sh 
b/hbase-native-client/bin/start-local-hbase.sh
index cfc71f9..49637d6 100755
--- a/hbase-native-client/bin/start-local-hbase.sh
+++ b/hbase-native-client/bin/start-local-hbase.sh
@@ -21,7 +21,8 @@
 rm -rf /tmp/hbase-*
 
 # Start the master/regionservers.
-$PWD/../bin/start-hbase.sh
+T_DIR=${1:-"/tmp/hbase-testing"}
+$PWD/../bin/start-hbase.sh -Dhbase.tmp.dir="${T_DIR}"
 
 until [ $(curl -s -o /dev/null -I -w "%{http_code}" 
http://localhost:16010/jmx) == "200" ]
 do
@@ -30,4 +31,4 @@ do
 done
 
 # This sucks, but master can easily be up and meta not be assigned yet.
-sleep 30
+sleep 10

http://git-wip-us.apache.org/repos/asf/hbase/blob/92db344d/hbase-native-client/connection/client-handler.cc
----------------------------------------------------------------------
diff --git a/hbase-native-client/connection/client-handler.cc 
b/hbase-native-client/connection/client-handler.cc
index 2e3fcd3..3409b80 100644
--- a/hbase-native-client/connection/client-handler.cc
+++ b/hbase-native-client/connection/client-handler.cc
@@ -37,7 +37,8 @@ using hbase::pb::GetResponse;
 using google::protobuf::Message;
 
 ClientHandler::ClientHandler(std::string user_name)
-    : user_name_(user_name), serde_(), 
once_flag_(std::make_unique<std::once_flag>()),
+    : user_name_(user_name), serde_(),
+      once_flag_(std::make_unique<std::once_flag>()),
       resp_msgs_(
           make_unique<folly::AtomicHashMap<
               uint32_t, std::shared_ptr<google::protobuf::Message>>>(5000)) {}

http://git-wip-us.apache.org/repos/asf/hbase/blob/92db344d/hbase-native-client/core/BUCK
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/BUCK b/hbase-native-client/core/BUCK
index 485f9ba..1c926e3 100644
--- a/hbase-native-client/core/BUCK
+++ b/hbase-native-client/core/BUCK
@@ -46,10 +46,10 @@ cxx_library(
     ], )
 cxx_test(name="location-cache-test",
          srcs=[
-             "test-env.cc",
              "location-cache-test.cc",
          ],
-         deps=[":core", ],
+         deps=[":core",
+               "//test-util:test-util", ],
          run_test_separately=True, )
 cxx_binary(name="simple-client",
            srcs=["simple-client.cc", ],

http://git-wip-us.apache.org/repos/asf/hbase/blob/92db344d/hbase-native-client/core/client.cc
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/client.cc 
b/hbase-native-client/core/client.cc
index 1e80998..82ecd22 100644
--- a/hbase-native-client/core/client.cc
+++ b/hbase-native-client/core/client.cc
@@ -22,6 +22,7 @@
 #include <glog/logging.h>
 
 #include <string>
+#include <unistd.h>
 
 using namespace folly;
 using namespace std;

http://git-wip-us.apache.org/repos/asf/hbase/blob/92db344d/hbase-native-client/core/location-cache-test.cc
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/location-cache-test.cc 
b/hbase-native-client/core/location-cache-test.cc
index 8bc6383..53db6fc 100644
--- a/hbase-native-client/core/location-cache-test.cc
+++ b/hbase-native-client/core/location-cache-test.cc
@@ -16,14 +16,22 @@
  * limitations under the License.
  *
  */
+#include "core/location-cache.h"
+
 #include <folly/Memory.h>
 #include <gtest/gtest.h>
 
-#include "location-cache.h"
+#include <chrono>
+
+#include "if/HBase.pb.h"
+#include "serde/table-name.h"
+#include "test-util/test-util.h"
 using namespace hbase;
+using namespace std::chrono;
 
 TEST(LocationCacheTest, TestGetMetaNodeContents) {
-  // TODO(elliott): need to make a test utility for this.
+  TestUtil test_util{};
+
   auto cpu = std::make_shared<wangle::CPUThreadPoolExecutor>(4);
   auto io = std::make_shared<wangle::IOThreadPoolExecutor>(4);
   LocationCache cache{"localhost:2181", cpu, io};
@@ -33,3 +41,20 @@ TEST(LocationCacheTest, TestGetMetaNodeContents) {
   ASSERT_TRUE(result.has_port());
   ASSERT_TRUE(result.has_host_name());
 }
+
+TEST(LocationCacheTest, TestGetRegionLocation) {
+  TestUtil test_util{};
+  auto cpu = std::make_shared<wangle::CPUThreadPoolExecutor>(4);
+  auto io = std::make_shared<wangle::IOThreadPoolExecutor>(4);
+  LocationCache cache{"localhost:2181", cpu, io};
+
+  // If there is no table this should throw an exception
+  auto tn = folly::to<hbase::pb::TableName>("t");
+  auto row = "test";
+  ASSERT_ANY_THROW(cache.LocateFromMeta(tn, row).get(milliseconds(1000)));
+  test_util.RunShellCmd("create 't', 'd'");
+  auto loc = cache.LocateFromMeta(tn, row).get(milliseconds(1000));
+  ASSERT_TRUE(loc != nullptr);
+  cpu->stop();
+  io->stop();
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/92db344d/hbase-native-client/core/location-cache.cc
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/location-cache.cc 
b/hbase-native-client/core/location-cache.cc
index 6c018f9..9f2a0ef 100644
--- a/hbase-native-client/core/location-cache.cc
+++ b/hbase-native-client/core/location-cache.cc
@@ -116,7 +116,7 @@ LocationCache::LocateFromMeta(const TableName &tn, const 
string &row) {
   return this->LocateMeta()
       .via(cpu_executor_.get())
       .then([this](ServerName sn) { return this->cp_.get(sn); })
-      .then([&](std::shared_ptr<HBaseService> service) {
+    .then([tn, row, this](std::shared_ptr<HBaseService> service) {
         return (*service)(std::move(meta_util_.MetaRequest(tn, row)));
       })
       .then([this](Response resp) {
@@ -124,6 +124,14 @@ LocationCache::LocateFromMeta(const TableName &tn, const 
string &row) {
         // a region location.
         return this->CreateLocation(std::move(resp));
       })
+      .then([tn, this](std::shared_ptr<RegionLocation> rl) {
+        // Make sure that the correct location was found.
+        if (rl->region_info().table_name().namespace_() != tn.namespace_() ||
+            rl->region_info().table_name().qualifier() != tn.qualifier()) {
+          throw std::runtime_error("Doesn't look like table exists.");
+        }
+        return rl;
+      })
       .then([this](std::shared_ptr<RegionLocation> rl) {
         // Now fill out the connection.
         rl->set_service(cp_.get(rl->server_name()));

http://git-wip-us.apache.org/repos/asf/hbase/blob/92db344d/hbase-native-client/core/location-cache.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/location-cache.h 
b/hbase-native-client/core/location-cache.h
index e077750..d435530 100644
--- a/hbase-native-client/core/location-cache.h
+++ b/hbase-native-client/core/location-cache.h
@@ -50,7 +50,9 @@ public:
   /**
    * Constructor.
    * @param quorum_spec Where to connect for Zookeeper.
-   * @param executor The cpu executor to run on.
+   * @param cpu_executor executor used to run non network IO based
+   * continuations.
+   * @param io_executor executor used to talk to the network
    */
   LocationCache(std::string quorum_spec,
                 std::shared_ptr<wangle::CPUThreadPoolExecutor> cpu_exector,
@@ -70,6 +72,12 @@ public:
 
   /**
    * Go read meta and find out where a region is located.
+   *
+   * @param tn Table name of the table to look up. This object must live until
+   * after the future is returned
+   *
+   * @param row of the table to look up. This object must live until after the
+   * future is returned
    */
   folly::Future<std::shared_ptr<RegionLocation>>
   LocateFromMeta(const hbase::pb::TableName &tn, const std::string &row);

http://git-wip-us.apache.org/repos/asf/hbase/blob/92db344d/hbase-native-client/core/test-env.cc
----------------------------------------------------------------------
diff --git a/hbase-native-client/core/test-env.cc 
b/hbase-native-client/core/test-env.cc
deleted file mode 100644
index 277abd9..0000000
--- a/hbase-native-client/core/test-env.cc
+++ /dev/null
@@ -1,45 +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 <gtest/gtest.h>
-
-namespace {
-
-class NativeClientTestEnv : public ::testing::Environment {
-public:
-  void SetUp() override {
-    // start local HBase cluster to be reused by all tests
-    auto result = system("bin/start-local-hbase.sh");
-    ASSERT_EQ(0, result);
-  }
-
-  void TearDown() override {
-    // shutdown local HBase cluster
-    auto result = system("bin/stop-local-hbase.sh");
-    ASSERT_EQ(0, result);
-  }
-};
-
-} // anonymous
-
-int main(int argc, char **argv) {
-  testing::InitGoogleTest(&argc, argv);
-  ::testing::AddGlobalTestEnvironment(new NativeClientTestEnv());
-  return RUN_ALL_TESTS();
-}

http://git-wip-us.apache.org/repos/asf/hbase/blob/92db344d/hbase-native-client/test-util/BUCK
----------------------------------------------------------------------
diff --git a/hbase-native-client/test-util/BUCK 
b/hbase-native-client/test-util/BUCK
new file mode 100644
index 0000000..e5e6ea2
--- /dev/null
+++ b/hbase-native-client/test-util/BUCK
@@ -0,0 +1,29 @@
+##
+# 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.
+
+cxx_library(name="test-util",
+  exported_headers=[
+    "test-util.h",
+  ],
+  srcs=["test-util.cc"],
+  deps=[
+    "//third-party:folly",
+    ],
+              visibility=[
+                'PUBLIC',
+            ],
+    )
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hbase/blob/92db344d/hbase-native-client/test-util/test-util.cc
----------------------------------------------------------------------
diff --git a/hbase-native-client/test-util/test-util.cc 
b/hbase-native-client/test-util/test-util.cc
new file mode 100644
index 0000000..e5fba48
--- /dev/null
+++ b/hbase-native-client/test-util/test-util.cc
@@ -0,0 +1,54 @@
+/*
+ * 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 "test-util/test-util.h"
+
+#include <folly/Format.h>
+
+using hbase::TestUtil;
+using folly::Random;
+
+const static int STR_LEN = 32;
+
+std::string TestUtil::RandString() {
+  auto s = std::string(STR_LEN, 'z');
+
+  for (int i = 0; i < STR_LEN; i++) {
+    auto r = Random::rand32('a', 'z');
+    s[i] = static_cast<char>(r);
+  }
+  return s;
+}
+
+TestUtil::TestUtil() : temp_dir_(TestUtil::RandString()) {
+  auto p = temp_dir_.path().string();
+  auto cmd = std::string{"bin/start-local-hbase.sh " + p};
+  auto res_code = std::system(cmd.c_str());
+  CHECK(res_code == 0);
+}
+TestUtil::~TestUtil() {
+  auto res_code = std::system("bin/stop-local-hbase.sh");
+  CHECK(res_code == 0);
+}
+
+void TestUtil::RunShellCmd(const std::string& command) {
+  auto cmd_string = folly::sformat("echo \"{}\" | ../bin/hbase shell", 
command);
+  auto res_code = std::system(cmd_string.c_str());
+  CHECK(res_code == 0);
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/92db344d/hbase-native-client/test-util/test-util.h
----------------------------------------------------------------------
diff --git a/hbase-native-client/test-util/test-util.h 
b/hbase-native-client/test-util/test-util.h
new file mode 100644
index 0000000..395b157
--- /dev/null
+++ b/hbase-native-client/test-util/test-util.h
@@ -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.
+ *
+ */
+#pragma once
+
+#include <folly/experimental/TestUtil.h>
+#include <folly/Random.h>
+
+#include <cstdlib>
+#include <string>
+
+namespace hbase {
+/**
+ * @brief Class to deal with a local instance cluster for testing.
+ */
+class TestUtil {
+public:
+
+  /**
+   * Creating a TestUtil will spin up a cluster.
+   */
+  TestUtil();
+  /**
+   * Destroying a TestUtil will spin down a cluster.
+   */
+  ~TestUtil();
+  /**
+   * Run a command in the hbase shell.
+   */
+  void RunShellCmd(const std::string& command);
+  static std::string RandString();
+
+private:
+  folly::test::TemporaryDirectory temp_dir_;
+};
+} // namespace hbase

Reply via email to