You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ya...@apache.org on 2014/04/15 00:48:54 UTC

git commit: Added a benchmark test for Registrar which is enabled by 'make bench'.

Repository: mesos
Updated Branches:
  refs/heads/master 0d4548cb6 -> 0802b3c79


Added a benchmark test for Registrar which is enabled by 'make bench'.

Review: https://reviews.apache.org/r/19761


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

Branch: refs/heads/master
Commit: 0802b3c797a04d9bbd339777accbc77c3b7e39a0
Parents: 0d4548c
Author: Jiang Yan Xu <ya...@jxu.me>
Authored: Thu Mar 27 11:22:08 2014 -0700
Committer: Jiang Yan Xu <ya...@jxu.me>
Committed: Mon Apr 14 15:42:54 2014 -0700

----------------------------------------------------------------------
 src/tests/registrar_tests.cpp | 146 ++++++++++++++++++++++++++++++++++---
 1 file changed, 136 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/0802b3c7/src/tests/registrar_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/registrar_tests.cpp b/src/tests/registrar_tests.cpp
index 67c26aa..c0ef0ca 100644
--- a/src/tests/registrar_tests.cpp
+++ b/src/tests/registrar_tests.cpp
@@ -16,14 +16,19 @@
  * limitations under the License.
  */
 
+#include <algorithm>
 #include <map>
 #include <string>
+#include <vector>
 
 #include <process/gmock.hpp>
 #include <process/gtest.hpp>
 #include <process/pid.hpp>
 #include <process/process.hpp>
 
+#include <stout/bytes.hpp>
+#include <stout/stopwatch.hpp>
+
 #include "common/protobuf_utils.hpp"
 #include "common/type_utils.hpp"
 
@@ -31,6 +36,7 @@
 #include "master/master.hpp"
 #include "master/registrar.hpp"
 
+#include "state/in_memory.hpp"
 #include "state/leveldb.hpp"
 #include "state/protobuf.hpp"
 #include "state/storage.hpp"
@@ -42,6 +48,7 @@ using namespace process;
 
 using std::map;
 using std::string;
+using std::vector;
 
 using testing::_;
 using testing::Eq;
@@ -55,16 +62,16 @@ class RegistrarTest : public ::testing::TestWithParam<bool>
 public:
   RegistrarTest()
     : storage(NULL),
-      state(NULL),
-      path(os::getcwd() + "/.state") {}
+      state(NULL) {}
 
 protected:
   virtual void SetUp()
   {
-    os::rmdir(path);
-    // TODO(bmahler): Only use LevelDBStorage or LogStorage for
-    // performance testing, otherwise just use InMemoryStorage.
-    storage = new state::LevelDBStorage(path);
+    // We use InMemoryStorage to test Registrar correctness and
+    // LevelDBStorage to test performance.
+    // TODO(xujyan): Use LogStorage to exercise what we're using in
+    // production.
+    storage = new state::InMemoryStorage();
     state = new state::protobuf::State(storage);
     master.CopyFrom(protobuf::createMasterInfo(UPID("master@127.0.0.1:5050")));
     flags.registry_strict = GetParam();
@@ -74,16 +81,12 @@ protected:
   {
     delete state;
     delete storage;
-    os::rmdir(path);
   }
 
   state::Storage* storage;
   state::protobuf::State* state;
   MasterInfo master;
   Flags flags;
-
-private:
-  const std::string path;
 };
 
 
@@ -281,6 +284,129 @@ TEST_P(RegistrarTest, bootstrap)
   }
 }
 
+
+// We are not inheriting from RegistrarTest because this test fixture
+// derives from a different instantiation of the TestWithParam template.
+class Registrar_BENCHMARK_Test : public ::testing::TestWithParam<size_t>
+{
+public:
+  Registrar_BENCHMARK_Test()
+    : storage(NULL),
+      state(NULL),
+      path(os::getcwd() + "/.state") {}
+
+protected:
+  virtual void SetUp()
+  {
+    os::rmdir(path);
+
+    // We use InMemoryStorage to test Registrar correctness and
+    // LevelDBStorage to test performance.
+    storage = new state::LevelDBStorage(path);
+    state = new state::protobuf::State(storage);
+    master.CopyFrom(protobuf::createMasterInfo(UPID("master@127.0.0.1:5050")));
+
+    // Strictness is not important in our benchmark tests so it's
+    // just set to false here.
+    flags.registry_strict = false;
+  }
+
+  virtual void TearDown()
+  {
+    delete state;
+    delete storage;
+    os::rmdir(path);
+  }
+
+  state::Storage* storage;
+  state::protobuf::State* state;
+  MasterInfo master;
+  Flags flags;
+
+private:
+  const std::string path;
+};
+
+
+// The Registrar benchmark tests are parameterized by the number of slaves.
+INSTANTIATE_TEST_CASE_P(
+    SlaveCount,
+    Registrar_BENCHMARK_Test,
+    ::testing::Values(10000U, 20000U, 30000U, 50000U));
+
+
+TEST_P(Registrar_BENCHMARK_Test, performance)
+{
+  Registrar registrar(flags, state);
+  AWAIT_READY(registrar.recover(master));
+
+  vector<SlaveInfo> infos;
+
+  Attributes attributes = Attributes::parse("foo:bar;baz:quux");
+  Resources resources =
+    Resources::parse("cpus(*):1.0;mem(*):512;disk(*):2048").get();
+
+  size_t slaveCount = GetParam();
+
+  // Create slaves.
+  for (size_t i = 0; i < slaveCount; ++i) {
+    // Simulate real slave information.
+    SlaveInfo info;
+    info.set_hostname("localhost");
+    info.mutable_id()->set_value(
+        std::string("201310101658-2280333834-5050-48574-") + stringify(i));
+    info.mutable_resources()->MergeFrom(resources);
+    info.mutable_attributes()->MergeFrom(attributes);
+    infos.push_back(info);
+  }
+
+  // Admit slaves.
+  Stopwatch watch;
+  watch.start();
+  Future<bool> result;
+  foreach (const SlaveInfo& info, infos) {
+    result = registrar.apply(Owned<Operation>(new AdmitSlave(info)));
+  }
+  AWAIT_READY_FOR(result, Minutes(5));
+  LOG(INFO) << "Admitted " << slaveCount << " slaves in " << watch.elapsed();
+
+  // Shuffle the slaves so we are readmitting them in random order (
+  // same as in production).
+  std::random_shuffle(infos.begin(), infos.end());
+
+  // Readmit slaves.
+  watch.start();
+  foreach (const SlaveInfo& info, infos) {
+    result = registrar.apply(Owned<Operation>(new ReadmitSlave(info)));
+  }
+  AWAIT_READY_FOR(result, Minutes(5));
+  LOG(INFO) << "Readmitted " << slaveCount << " slaves in " << watch.elapsed();
+
+  // Recover slaves.
+  Registrar registrar2(flags, state);
+  watch.start();
+  MasterInfo info;
+  info.set_id("master");
+  info.set_ip(10000000);
+  info.set_port(5050);
+  Future<Registry> registry = registrar2.recover(info);
+  AWAIT_READY(registry);
+  LOG(INFO) << "Recovered " << slaveCount << " slaves ("
+            << Bytes(registry.get().ByteSize()) << ") in " << watch.elapsed();
+
+  // Shuffle the slaves so we are removing them in random order (same
+  // as in production).
+  std::random_shuffle(infos.begin(), infos.end());
+
+  // Remove slaves.
+  watch.start();
+  foreach (const SlaveInfo& info, infos) {
+    result = registrar2.apply(Owned<Operation>(new RemoveSlave(info)));
+  }
+  AWAIT_READY_FOR(result, Minutes(5));
+  LOG(INFO) << "Removed " << slaveCount << " slaves in " << watch.elapsed();
+}
+
 } // namespace master {
 } // namespace internal {
 } // namespace mesos {