You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2013/05/26 18:57:26 UTC
[01/28] git commit: Renamed tests/zookeeper_test.hpp|cpp to
zookeeper.hpp|cpp.
Updated Branches:
refs/heads/master 304835d76 -> 4392c6e3b
Renamed tests/zookeeper_test.hpp|cpp to zookeeper.hpp|cpp.
Review: https://reviews.apache.org/r/11272
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/b553a075
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/b553a075
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/b553a075
Branch: refs/heads/master
Commit: b553a075caa13086a7be936f2feb088ab0a42f5a
Parents: 1d71e42
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sun May 5 16:31:47 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Fri May 24 22:05:05 2013 -0700
----------------------------------------------------------------------
src/Makefile.am | 4 +-
src/tests/allocator_zookeeper_tests.cpp | 2 +-
src/tests/group_tests.cpp | 2 +-
src/tests/master_detector_tests.cpp | 2 +-
src/tests/state_tests.cpp | 2 +-
src/tests/zookeeper.cpp | 173 ++++++++++++++++++++++++++
src/tests/zookeeper.hpp | 137 ++++++++++++++++++++
src/tests/zookeeper_test.cpp | 173 --------------------------
src/tests/zookeeper_test.hpp | 137 --------------------
src/tests/zookeeper_tests.cpp | 2 +-
10 files changed, 317 insertions(+), 317 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/b553a075/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index fe31707..bc0c5c6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -230,7 +230,7 @@ libmesos_no_third_party_la_SOURCES += common/attributes.hpp \
slave/reaper.hpp \
slave/slave.hpp \
tests/environment.hpp tests/script.hpp \
- tests/zookeeper_test.hpp tests/flags.hpp tests/utils.hpp \
+ tests/zookeeper.hpp tests/flags.hpp tests/utils.hpp \
tests/cluster.hpp \
tests/isolator.hpp \
tests/zookeeper_test_server.hpp zookeeper/authentication.hpp \
@@ -823,7 +823,7 @@ if OS_LINUX
endif
if HAS_JAVA
- mesos_tests_SOURCES += tests/zookeeper_test.cpp \
+ mesos_tests_SOURCES += tests/zookeeper.cpp \
tests/zookeeper_test_server.cpp \
tests/zookeeper_tests.cpp \
tests/allocator_zookeeper_tests.cpp
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/b553a075/src/tests/allocator_zookeeper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/allocator_zookeeper_tests.cpp b/src/tests/allocator_zookeeper_tests.cpp
index 962e876..d03a564 100644
--- a/src/tests/allocator_zookeeper_tests.cpp
+++ b/src/tests/allocator_zookeeper_tests.cpp
@@ -27,8 +27,8 @@
#include "master/allocator.hpp"
#include "master/master.hpp"
-#include "tests/zookeeper_test.hpp"
#include "tests/utils.hpp"
+#include "tests/zookeeper.hpp"
#include "zookeeper/url.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/b553a075/src/tests/group_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/group_tests.cpp b/src/tests/group_tests.cpp
index 3e442cd..d32b74f 100644
--- a/src/tests/group_tests.cpp
+++ b/src/tests/group_tests.cpp
@@ -27,7 +27,7 @@
#include <stout/option.hpp>
#include "tests/utils.hpp"
-#include "tests/zookeeper_test.hpp"
+#include "tests/zookeeper.hpp"
#include "zookeeper/authentication.hpp"
#include "zookeeper/group.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/b553a075/src/tests/master_detector_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_detector_tests.cpp b/src/tests/master_detector_tests.cpp
index 1739823..c9d6d20 100644
--- a/src/tests/master_detector_tests.cpp
+++ b/src/tests/master_detector_tests.cpp
@@ -50,7 +50,7 @@
#include "tests/utils.hpp"
#ifdef MESOS_HAS_JAVA
-#include "tests/zookeeper_test.hpp"
+#include "tests/zookeeper.hpp"
#endif
using namespace mesos;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/b553a075/src/tests/state_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/state_tests.cpp b/src/tests/state_tests.cpp
index eb124fd..9066025 100644
--- a/src/tests/state_tests.cpp
+++ b/src/tests/state_tests.cpp
@@ -41,7 +41,7 @@
#include "tests/utils.hpp"
#ifdef MESOS_HAS_JAVA
-#include "tests/zookeeper_test.hpp"
+#include "tests/zookeeper.hpp"
#endif
using namespace mesos;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/b553a075/src/tests/zookeeper.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper.cpp b/src/tests/zookeeper.cpp
new file mode 100644
index 0000000..3d11209
--- /dev/null
+++ b/src/tests/zookeeper.cpp
@@ -0,0 +1,173 @@
+/**
+ * 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 <signal.h>
+
+#include <gtest/gtest.h>
+
+#include <queue>
+
+#include <tr1/functional>
+
+#include <jvm/jvm.hpp>
+
+#include <jvm/org/apache/log4j.hpp>
+#include <jvm/org/apache/log4j.hpp>
+
+#include <stout/lambda.hpp>
+
+#include "common/lock.hpp"
+
+#include "logging/logging.hpp"
+
+#include "tests/utils.hpp"
+#include "tests/zookeeper.hpp"
+#include "tests/zookeeper_test_server.hpp"
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+const Duration ZooKeeperTest::NO_TIMEOUT = Milliseconds(5000);
+
+
+void ZooKeeperTest::SetUpTestCase()
+{
+ if (!Jvm::created()) {
+ std::string zkHome = flags.build_dir +
+ "/third_party/zookeeper-" ZOOKEEPER_VERSION;
+
+ std::string classpath = "-Djava.class.path=" +
+ zkHome + "/zookeeper-" ZOOKEEPER_VERSION ".jar:" +
+ zkHome + "/lib/log4j-1.2.15.jar";
+
+ LOG(INFO) << "Using classpath setup: " << classpath << std::endl;
+
+ std::vector<std::string> options;
+ options.push_back(classpath);
+ Try<Jvm*> jvm = Jvm::create(options);
+ CHECK_SOME(jvm);
+
+ if (!flags.verbose) {
+ // Silence server logs.
+ org::apache::log4j::Logger::getRootLogger()
+ .setLevel(org::apache::log4j::Level::OFF);
+
+ // Silence client logs.
+ // TODO(jsirois): Create C++ ZooKeeper::setLevel.
+ zoo_set_debug_level(ZOO_LOG_LEVEL_ERROR);
+ }
+ }
+}
+
+
+void ZooKeeperTest::SetUp()
+{
+ server->startNetwork();
+}
+
+
+ZooKeeperTest::TestWatcher::TestWatcher()
+{
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
+ pthread_mutex_init(&mutex, &attr);
+ pthread_mutexattr_destroy(&attr);
+ pthread_cond_init(&cond, 0);
+}
+
+
+ZooKeeperTest::TestWatcher::~TestWatcher()
+{
+ pthread_mutex_destroy(&mutex);
+ pthread_cond_destroy(&cond);
+}
+
+
+void ZooKeeperTest::TestWatcher::process(
+ ZooKeeper* zk,
+ int type,
+ int state,
+ const std::string& path)
+{
+ Lock lock(&mutex);
+ events.push(Event(type, state, path));
+ pthread_cond_signal(&cond);
+}
+
+
+static bool isSessionState(
+ const ZooKeeperTest::TestWatcher::Event& event,
+ int state)
+{
+ return event.type == ZOO_SESSION_EVENT && event.state == state;
+}
+
+
+void ZooKeeperTest::TestWatcher::awaitSessionEvent(int state)
+{
+ awaitEvent(lambda::bind(&isSessionState, lambda::_1, state));
+}
+
+
+static bool isCreated(
+ const ZooKeeperTest::TestWatcher::Event& event,
+ const std::string& path)
+{
+ return event.type == ZOO_CHILD_EVENT && event.path == path;
+}
+
+
+void ZooKeeperTest::TestWatcher::awaitCreated(const std::string& path)
+{
+ awaitEvent(lambda::bind(&isCreated, lambda::_1, path));
+}
+
+
+ZooKeeperTest::TestWatcher::Event
+ZooKeeperTest::TestWatcher::awaitEvent()
+{
+ Lock lock(&mutex);
+ while (true) {
+ while (events.empty()) {
+ pthread_cond_wait(&cond, &mutex);
+ }
+ Event event = events.front();
+ events.pop();
+ return event;
+ }
+}
+
+
+ZooKeeperTest::TestWatcher::Event
+ZooKeeperTest::TestWatcher::awaitEvent(
+ const std::tr1::function<bool(Event)>& matches)
+{
+ while (true) {
+ Event event = awaitEvent();
+ if (matches(event)) {
+ return event;
+ }
+ }
+}
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {
+
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/b553a075/src/tests/zookeeper.hpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper.hpp b/src/tests/zookeeper.hpp
new file mode 100644
index 0000000..17e0886
--- /dev/null
+++ b/src/tests/zookeeper.hpp
@@ -0,0 +1,137 @@
+/**
+ * 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.
+ */
+
+#ifndef __TESTS_ZOOKEEPER_HPP__
+#define __TESTS_ZOOKEEPER_HPP__
+
+#include <pthread.h>
+
+#include <gtest/gtest.h>
+
+#include <queue>
+
+#include <tr1/functional>
+
+#include <stout/duration.hpp>
+
+#include "tests/utils.hpp"
+#include "tests/zookeeper_test_server.hpp"
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+// Helper for invoking ZooKeeper::get(path, ...) in order to check the
+// data stored at a specified znode path.
+inline ::testing::AssertionResult AssertZKGet(
+ const char* expectedExpr,
+ const char* zkExpr,
+ const char* pathExpr,
+ const std::string& expected,
+ ZooKeeper* zk,
+ const std::string& path)
+{
+ std::string result;
+ int code = zk->get(path, false, &result, NULL);
+ if (code == ZOK) {
+ if (expected == result) {
+ return ::testing::AssertionSuccess();
+ } else {
+ return ::testing::AssertionFailure()
+ << "Expected data at znode '" << pathExpr << "' "
+ << "to be '" << expected << "', but actually '" << result << "'";
+ }
+ } else {
+ return ::testing::AssertionFailure()
+ << "(" << zkExpr << ").get(" << pathExpr << ", ...): "
+ << zk->message(code);
+ }
+}
+
+#define ASSERT_ZK_GET(expected, zk, path) \
+ ASSERT_PRED_FORMAT3(mesos::internal::tests::AssertZKGet, expected, zk, path)
+
+
+// A fixture for tests that need to interact with a ZooKeeper server
+// ensemble. Tests can access the in process ZooKeeperTestServer via
+// the variable 'server'. This test fixture ensures the server is
+// started before each test and shutdown after it so that each test is
+// presented with a ZooKeeper ensemble with no data or watches.
+class ZooKeeperTest : public MesosTest
+{
+public:
+ // A watcher that is useful to install in a ZooKeeper client for
+ // tests. Allows easy blocking on expected events.
+ class TestWatcher : public Watcher
+ {
+ public:
+ // Encapsulates all the state of a ZooKeeper watcher event.
+ struct Event {
+ Event(int _type, int _state, const std::string& _path)
+ : type(_type), state(_state), path(_path) {}
+ const int type;
+ const int state;
+ const std::string path;
+ };
+
+ TestWatcher();
+ virtual ~TestWatcher();
+
+ virtual void process(
+ ZooKeeper* zk,
+ int type,
+ int state,
+ const std::string& path);
+
+ // Blocks until the session event of the given state fires.
+ void awaitSessionEvent(int state);
+
+ // Blocks until a node appears at the given path.
+ void awaitCreated(const std::string& path);
+
+ // Blocks until an event is fired matching the given predicate.
+ Event awaitEvent(const std::tr1::function<bool(Event)>& matches);
+
+ // Blocks until an event is fired.
+ Event awaitEvent();
+
+ private:
+ std::queue<Event> events;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ };
+
+ ZooKeeperTest() : server(new ZooKeeperTestServer()) {}
+ virtual ~ZooKeeperTest() { delete server; }
+
+ static void SetUpTestCase();
+
+protected:
+ virtual void SetUp();
+
+ // A very long session timeout that simulates no timeout for test cases.
+ static const Duration NO_TIMEOUT;
+
+ ZooKeeperTestServer* server;
+};
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __ZOOKEEPER_TEST_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/b553a075/src/tests/zookeeper_test.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_test.cpp b/src/tests/zookeeper_test.cpp
deleted file mode 100644
index 90c6aba..0000000
--- a/src/tests/zookeeper_test.cpp
+++ /dev/null
@@ -1,173 +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 <signal.h>
-
-#include <gtest/gtest.h>
-
-#include <queue>
-
-#include <tr1/functional>
-
-#include <jvm/jvm.hpp>
-
-#include <jvm/org/apache/log4j.hpp>
-#include <jvm/org/apache/log4j.hpp>
-
-#include <stout/lambda.hpp>
-
-#include "common/lock.hpp"
-
-#include "logging/logging.hpp"
-
-#include "tests/utils.hpp"
-#include "tests/zookeeper_test.hpp"
-#include "tests/zookeeper_test_server.hpp"
-
-namespace mesos {
-namespace internal {
-namespace tests {
-
-const Duration ZooKeeperTest::NO_TIMEOUT = Milliseconds(5000);
-
-
-void ZooKeeperTest::SetUpTestCase()
-{
- if (!Jvm::created()) {
- std::string zkHome = flags.build_dir +
- "/third_party/zookeeper-" ZOOKEEPER_VERSION;
-
- std::string classpath = "-Djava.class.path=" +
- zkHome + "/zookeeper-" ZOOKEEPER_VERSION ".jar:" +
- zkHome + "/lib/log4j-1.2.15.jar";
-
- LOG(INFO) << "Using classpath setup: " << classpath << std::endl;
-
- std::vector<std::string> options;
- options.push_back(classpath);
- Try<Jvm*> jvm = Jvm::create(options);
- CHECK_SOME(jvm);
-
- if (!flags.verbose) {
- // Silence server logs.
- org::apache::log4j::Logger::getRootLogger()
- .setLevel(org::apache::log4j::Level::OFF);
-
- // Silence client logs.
- // TODO(jsirois): Create C++ ZooKeeper::setLevel.
- zoo_set_debug_level(ZOO_LOG_LEVEL_ERROR);
- }
- }
-}
-
-
-void ZooKeeperTest::SetUp()
-{
- server->startNetwork();
-}
-
-
-ZooKeeperTest::TestWatcher::TestWatcher()
-{
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
- pthread_mutex_init(&mutex, &attr);
- pthread_mutexattr_destroy(&attr);
- pthread_cond_init(&cond, 0);
-}
-
-
-ZooKeeperTest::TestWatcher::~TestWatcher()
-{
- pthread_mutex_destroy(&mutex);
- pthread_cond_destroy(&cond);
-}
-
-
-void ZooKeeperTest::TestWatcher::process(
- ZooKeeper* zk,
- int type,
- int state,
- const std::string& path)
-{
- Lock lock(&mutex);
- events.push(Event(type, state, path));
- pthread_cond_signal(&cond);
-}
-
-
-static bool isSessionState(
- const ZooKeeperTest::TestWatcher::Event& event,
- int state)
-{
- return event.type == ZOO_SESSION_EVENT && event.state == state;
-}
-
-
-void ZooKeeperTest::TestWatcher::awaitSessionEvent(int state)
-{
- awaitEvent(lambda::bind(&isSessionState, lambda::_1, state));
-}
-
-
-static bool isCreated(
- const ZooKeeperTest::TestWatcher::Event& event,
- const std::string& path)
-{
- return event.type == ZOO_CHILD_EVENT && event.path == path;
-}
-
-
-void ZooKeeperTest::TestWatcher::awaitCreated(const std::string& path)
-{
- awaitEvent(lambda::bind(&isCreated, lambda::_1, path));
-}
-
-
-ZooKeeperTest::TestWatcher::Event
-ZooKeeperTest::TestWatcher::awaitEvent()
-{
- Lock lock(&mutex);
- while (true) {
- while (events.empty()) {
- pthread_cond_wait(&cond, &mutex);
- }
- Event event = events.front();
- events.pop();
- return event;
- }
-}
-
-
-ZooKeeperTest::TestWatcher::Event
-ZooKeeperTest::TestWatcher::awaitEvent(
- const std::tr1::function<bool(Event)>& matches)
-{
- while (true) {
- Event event = awaitEvent();
- if (matches(event)) {
- return event;
- }
- }
-}
-
-} // namespace tests {
-} // namespace internal {
-} // namespace mesos {
-
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/b553a075/src/tests/zookeeper_test.hpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_test.hpp b/src/tests/zookeeper_test.hpp
deleted file mode 100644
index 7bd396b..0000000
--- a/src/tests/zookeeper_test.hpp
+++ /dev/null
@@ -1,137 +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.
- */
-
-#ifndef __ZOOKEEPER_TEST_HPP__
-#define __ZOOKEEPER_TEST_HPP__
-
-#include <pthread.h>
-
-#include <gtest/gtest.h>
-
-#include <queue>
-
-#include <tr1/functional>
-
-#include <stout/duration.hpp>
-
-#include "tests/utils.hpp"
-#include "tests/zookeeper_test_server.hpp"
-
-namespace mesos {
-namespace internal {
-namespace tests {
-
-// Helper for invoking ZooKeeper::get(path, ...) in order to check the
-// data stored at a specified znode path.
-inline ::testing::AssertionResult AssertZKGet(
- const char* expectedExpr,
- const char* zkExpr,
- const char* pathExpr,
- const std::string& expected,
- ZooKeeper* zk,
- const std::string& path)
-{
- std::string result;
- int code = zk->get(path, false, &result, NULL);
- if (code == ZOK) {
- if (expected == result) {
- return ::testing::AssertionSuccess();
- } else {
- return ::testing::AssertionFailure()
- << "Expected data at znode '" << pathExpr << "' "
- << "to be '" << expected << "', but actually '" << result << "'";
- }
- } else {
- return ::testing::AssertionFailure()
- << "(" << zkExpr << ").get(" << pathExpr << ", ...): "
- << zk->message(code);
- }
-}
-
-#define ASSERT_ZK_GET(expected, zk, path) \
- ASSERT_PRED_FORMAT3(mesos::internal::tests::AssertZKGet, expected, zk, path)
-
-
-// A fixture for tests that need to interact with a ZooKeeper server
-// ensemble. Tests can access the in process ZooKeeperTestServer via
-// the variable 'server'. This test fixture ensures the server is
-// started before each test and shutdown after it so that each test is
-// presented with a ZooKeeper ensemble with no data or watches.
-class ZooKeeperTest : public MesosTest
-{
-public:
- // A watcher that is useful to install in a ZooKeeper client for
- // tests. Allows easy blocking on expected events.
- class TestWatcher : public Watcher
- {
- public:
- // Encapsulates all the state of a ZooKeeper watcher event.
- struct Event {
- Event(int _type, int _state, const std::string& _path)
- : type(_type), state(_state), path(_path) {}
- const int type;
- const int state;
- const std::string path;
- };
-
- TestWatcher();
- virtual ~TestWatcher();
-
- virtual void process(
- ZooKeeper* zk,
- int type,
- int state,
- const std::string& path);
-
- // Blocks until the session event of the given state fires.
- void awaitSessionEvent(int state);
-
- // Blocks until a node appears at the given path.
- void awaitCreated(const std::string& path);
-
- // Blocks until an event is fired matching the given predicate.
- Event awaitEvent(const std::tr1::function<bool(Event)>& matches);
-
- // Blocks until an event is fired.
- Event awaitEvent();
-
- private:
- std::queue<Event> events;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- };
-
- ZooKeeperTest() : server(new ZooKeeperTestServer()) {}
- virtual ~ZooKeeperTest() { delete server; }
-
- static void SetUpTestCase();
-
-protected:
- virtual void SetUp();
-
- // A very long session timeout that simulates no timeout for test cases.
- static const Duration NO_TIMEOUT;
-
- ZooKeeperTestServer* server;
-};
-
-} // namespace tests {
-} // namespace internal {
-} // namespace mesos {
-
-#endif // __ZOOKEEPER_TEST_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/b553a075/src/tests/zookeeper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_tests.cpp b/src/tests/zookeeper_tests.cpp
index 5193d03..27a6048 100644
--- a/src/tests/zookeeper_tests.cpp
+++ b/src/tests/zookeeper_tests.cpp
@@ -25,7 +25,7 @@
#include <stout/strings.hpp>
#include "tests/utils.hpp"
-#include "tests/zookeeper_test.hpp"
+#include "tests/zookeeper.hpp"
using namespace mesos::internal;
using namespace mesos::internal::tests;
[22/28] git commit: Refactored base 'State' implementation to be
serialization agnostic and use a 'Storage' instance. Changed the LevelDB and
ZooKeeper implementations to implement 'Storage' instead of 'State'. Provided
a protobuf specific implementation
Posted by be...@apache.org.
Refactored base 'State' implementation to be serialization agnostic
and use a 'Storage' instance. Changed the LevelDB and ZooKeeper
implementations to implement 'Storage' instead of 'State'. Provided a
protobuf specific implementation on top of 'State'. Updated code
(including JNI) and tests accordingly.
Review: https://reviews.apache.org/r/11308
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/33f4ff4b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/33f4ff4b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/33f4ff4b
Branch: refs/heads/master
Commit: 33f4ff4b138dbe11abd2014e1e2b44dd8444a0b3
Parents: 1e35e9e
Author: Benjamin Hindman <be...@twitter.com>
Authored: Mon Jan 14 15:45:29 2013 -0800
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 09:28:36 2013 -0700
----------------------------------------------------------------------
src/Makefile.am | 20 +-
src/java/jni/org_apache_mesos_state_Variable.cpp | 22 +-
.../jni/org_apache_mesos_state_ZooKeeperState.cpp | 318 ++++++++++---
.../src/org/apache/mesos/state/InMemoryState.java | 21 +-
src/java/src/org/apache/mesos/state/State.java | 22 +-
.../src/org/apache/mesos/state/ZooKeeperState.java | 113 +++--
src/master/registry.hpp | 24 +
src/master/registry.proto | 32 ++
src/messages/messages.hpp | 40 ++
src/messages/messages.proto | 6 -
src/state/leveldb.cpp | 77 +++-
src/state/leveldb.hpp | 77 ++--
src/state/protobuf.hpp | 166 +++++++
src/state/serializer.hpp | 67 ---
src/state/state.hpp | 183 +++----
src/state/storage.hpp | 60 +++
src/state/zookeeper.cpp | 175 +++++--
src/state/zookeeper.hpp | 99 ++--
src/tests/state_tests.cpp | 383 ++++++++++-----
19 files changed, 1330 insertions(+), 575 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 0f7794e..7c740fd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -129,6 +129,10 @@ STATE_PROTOS = messages/state.pb.cc messages/state.pb.h
BUILT_SOURCES += $(STATE_PROTOS)
CLEANFILES += $(STATE_PROTOS)
+REGISTRY_PROTOS = master/registry.pb.cc master/registry.pb.h
+
+BUILT_SOURCES += $(REGISTRY_PROTOS)
+CLEANFILES += $(REGISTRY_PROTOS)
# Targets for generating protocol buffer code.
%.pb.cc %.pb.h: $(top_srcdir)/include/mesos/%.proto
@@ -153,7 +157,10 @@ $(PYTHON_PROTOS): $(MESOS_PROTO)
# libraries themselves.
noinst_LTLIBRARIES += libmesos_no_third_party.la
-nodist_libmesos_no_third_party_la_SOURCES = $(CXX_PROTOS) $(MESSAGES_PROTOS)
+nodist_libmesos_no_third_party_la_SOURCES = \
+ $(CXX_PROTOS) \
+ $(MESSAGES_PROTOS) \
+ $(REGISTRY_PROTOS)
libmesos_no_third_party_la_SOURCES = \
sched/sched.cpp \
@@ -162,6 +169,8 @@ libmesos_no_third_party_la_SOURCES = \
master/drf_sorter.cpp \
master/http.cpp \
master/master.cpp \
+ master/registry.hpp \
+ master/registry.proto \
slave/constants.cpp \
slave/gc.cpp \
slave/monitor.cpp \
@@ -278,8 +287,13 @@ libmesos_no_third_party_la_LIBADD += liblog.la
# include the leveldb headers.
noinst_LTLIBRARIES += libstate.la
libstate_la_SOURCES = state/leveldb.cpp state/zookeeper.cpp
-libstate_la_SOURCES += state/leveldb.hpp state/serializer.hpp \
- state/state.hpp state/zookeeper.hpp messages/state.hpp \
+libstate_la_SOURCES += \
+ state/leveldb.hpp \
+ state/protobuf.hpp \
+ state/state.hpp \
+ state/storage.hpp \
+ state/zookeeper.hpp \
+ messages/state.hpp \
messages/state.proto
nodist_libstate_la_SOURCES = $(STATE_PROTOS)
libstate_la_CPPFLAGS = -I../$(LEVELDB)/include $(MESOS_CPPFLAGS)
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/java/jni/org_apache_mesos_state_Variable.cpp
----------------------------------------------------------------------
diff --git a/src/java/jni/org_apache_mesos_state_Variable.cpp b/src/java/jni/org_apache_mesos_state_Variable.cpp
index eacb110..4d840ce 100644
--- a/src/java/jni/org_apache_mesos_state_Variable.cpp
+++ b/src/java/jni/org_apache_mesos_state_Variable.cpp
@@ -20,13 +20,13 @@ JNIEXPORT jbyteArray JNICALL Java_org_apache_mesos_state_Variable_value
jfieldID __variable = env->GetFieldID(clazz, "__variable", "J");
- Variable<std::string>* variable =
- (Variable<std::string>*) env->GetLongField(thiz, __variable);
+ Variable* variable = (Variable*) env->GetLongField(thiz, __variable);
+
+ const std::string& value = variable->value();
// byte[] value = ..;
- jbyteArray jvalue = env->NewByteArray((*variable)->size());
- env->SetByteArrayRegion(
- jvalue, 0, (*variable)->size(), (jbyte*) (*variable)->data());
+ jbyteArray jvalue = env->NewByteArray(value.size());
+ env->SetByteArrayRegion(jvalue, 0, value.size(), (jbyte*) value.data());
return jvalue;
}
@@ -44,15 +44,14 @@ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_Variable_mutate
jfieldID __variable = env->GetFieldID(clazz, "__variable", "J");
- // Create a copy of the old variable to support the immutable Java API.
- Variable<std::string>* variable = new Variable<std::string>(
- *((Variable<std::string>*) env->GetLongField(thiz, __variable)));
+ Variable* variable = (Variable*) env->GetLongField(thiz, __variable);
jbyte* value = env->GetByteArrayElements(jvalue, NULL);
jsize length = env->GetArrayLength(jvalue);
- // Update the value of the new copy.
- (*variable)->assign((const char*) value, length);
+ // Mutate the variable and save a copy of the result.
+ variable =
+ new Variable(variable->mutate(std::string((const char*) value, length)));
env->ReleaseByteArrayElements(jvalue, value, 0);
@@ -80,8 +79,7 @@ JNIEXPORT void JNICALL Java_org_apache_mesos_state_Variable_finalize
jfieldID __variable = env->GetFieldID(clazz, "__variable", "J");
- Variable<std::string>* variable =
- (Variable<std::string>*) env->GetLongField(thiz, __variable);
+ Variable* variable = (Variable*) env->GetLongField(thiz, __variable);
delete variable;
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/java/jni/org_apache_mesos_state_ZooKeeperState.cpp
----------------------------------------------------------------------
diff --git a/src/java/jni/org_apache_mesos_state_ZooKeeperState.cpp b/src/java/jni/org_apache_mesos_state_ZooKeeperState.cpp
index 5abf3ef..c3282c0 100644
--- a/src/java/jni/org_apache_mesos_state_ZooKeeperState.cpp
+++ b/src/java/jni/org_apache_mesos_state_ZooKeeperState.cpp
@@ -48,11 +48,16 @@ JNIEXPORT void JNICALL Java_org_apache_mesos_state_ZooKeeperState_initialize__Lj
string znode = construct<string>(env, jznode);
- // Create the C++ State and initialize the __state variable.
- State<>* state = new ZooKeeperState<>(servers, timeout, znode);
+ // Create the C++ Storage and State instances and initialize the
+ // __storage and __state variables.
+ Storage* storage = new ZooKeeperStorage(servers, timeout, znode);
+ State* state = new State(storage);
clazz = env->GetObjectClass(thiz);
+ jfieldID __storage = env->GetFieldID(clazz, "__storage", "J");
+ env->SetLongField(thiz, __storage, (jlong) storage);
+
jfieldID __state = env->GetFieldID(clazz, "__state", "J");
env->SetLongField(thiz, __state, (jlong) state);
}
@@ -87,7 +92,7 @@ JNIEXPORT void JNICALL Java_org_apache_mesos_state_ZooKeeperState_initialize__Lj
string znode = construct<string>(env, jznode);
// Create the C++ State.
- State<>* state = NULL;
+ Storage* storage = NULL;
if (jscheme != NULL && jcredentials != NULL) {
string scheme = construct<string>(env, jscheme);
@@ -100,16 +105,21 @@ JNIEXPORT void JNICALL Java_org_apache_mesos_state_ZooKeeperState_initialize__Lj
zookeeper::Authentication authentication(scheme, credentials);
- state = new ZooKeeperState<>(servers, timeout, znode, authentication);
+ storage = new ZooKeeperStorage(servers, timeout, znode, authentication);
} else {
- state = new ZooKeeperState<>(servers, timeout, znode);
+ storage = new ZooKeeperStorage(servers, timeout, znode);
}
- CHECK(state != NULL);
+ CHECK(storage != NULL);
+
+ State* state = new State(storage);
- // Initialize the __state variable.
+ // Initialize the __storage and __state variables.
clazz = env->GetObjectClass(thiz);
+ jfieldID __storage = env->GetFieldID(clazz, "__storage", "J");
+ env->SetLongField(thiz, __storage, (jlong) storage);
+
jfieldID __state = env->GetFieldID(clazz, "__state", "J");
env->SetLongField(thiz, __state, (jlong) state);
}
@@ -127,18 +137,24 @@ JNIEXPORT void JNICALL Java_org_apache_mesos_state_ZooKeeperState_finalize
jfieldID __state = env->GetFieldID(clazz, "__state", "J");
- State<>* state = (State<>*) env->GetLongField(thiz, __state);
+ State* state = (State*) env->GetLongField(thiz, __state);
delete state;
+
+ jfieldID __storage = env->GetFieldID(clazz, "__storage", "J");
+
+ Storage* storage = (Storage*) env->GetLongField(thiz, __storage);
+
+ delete storage;
}
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __get
+ * Method: __fetch
* Signature: (Ljava/lang/String;)J
*/
-JNIEXPORT jlong JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get
+JNIEXPORT jlong JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1fetch
(JNIEnv* env, jobject thiz, jstring jname)
{
string name = construct<string>(env, jname);
@@ -147,10 +163,9 @@ JNIEXPORT jlong JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get
jfieldID __state = env->GetFieldID(clazz, "__state", "J");
- State<>* state = (State<>*) env->GetLongField(thiz, __state);
+ State* state = (State*) env->GetLongField(thiz, __state);
- Future<Variable<string> >* future =
- new Future<Variable<string> >(state->get<string>(name));
+ Future<Variable>* future = new Future<Variable>(state->fetch(name));
return (jlong) future;
}
@@ -158,13 +173,13 @@ JNIEXPORT jlong JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __get_cancel
+ * Method: __fetch_cancel
* Signature: (J)Z
*/
-JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1cancel
+JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1fetch_1cancel
(JNIEnv* env, jobject thiz, jlong jfuture)
{
- Future<Variable<string> >* future = (Future<Variable<string> >*) jfuture;
+ Future<Variable>* future = (Future<Variable>*) jfuture;
if (!future->isDiscarded()) {
future->discard();
@@ -177,13 +192,13 @@ JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1c
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __get_is_cancelled
+ * Method: __fetch_is_cancelled
* Signature: (J)Z
*/
-JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1is_1cancelled
+JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1fetch_1is_1cancelled
(JNIEnv* env, jobject thiz, jlong jfuture)
{
- Future<Variable<string> >* future = (Future<Variable<string> >*) jfuture;
+ Future<Variable>* future = (Future<Variable>*) jfuture;
return (jboolean) future->isDiscarded();
}
@@ -191,13 +206,13 @@ JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1i
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __get_is_done
+ * Method: __fetch_is_done
* Signature: (J)Z
*/
-JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1is_1done
+JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1fetch_1is_1done
(JNIEnv* env, jobject thiz, jlong jfuture)
{
- Future<Variable<string> >* future = (Future<Variable<string> >*) jfuture;
+ Future<Variable>* future = (Future<Variable>*) jfuture;
return (jboolean) !future->isPending();
}
@@ -205,13 +220,13 @@ JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1i
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __get_get
+ * Method: __fetch_get
* Signature: (J)Lorg/apache/mesos/state/Variable;
*/
-JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1get
+JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1fetch_1get
(JNIEnv* env, jobject thiz, jlong jfuture)
{
- Future<Variable<string> >* future = (Future<Variable<string> >*) jfuture;
+ Future<Variable>* future = (Future<Variable>*) jfuture;
future->await();
@@ -227,7 +242,7 @@ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1ge
CHECK(future->isReady());
- Variable<string>* variable = new Variable<string>(future->get());
+ Variable* variable = new Variable(future->get());
// Variable variable = new Variable();
jclass clazz = env->FindClass("org/apache/mesos/state/Variable");
@@ -244,13 +259,13 @@ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1ge
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __get_get_timeout
+ * Method: __fetch_get_timeout
* Signature: (JJLjava/util/concurrent/TimeUnit;)Lorg/apache/mesos/state/Variable;
*/
-JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1get_1timeout
+JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1fetch_1get_1timeout
(JNIEnv* env, jobject thiz, jlong jfuture, jlong jtimeout, jobject junit)
{
- Future<Variable<string> >* future = (Future<Variable<string> >*) jfuture;
+ Future<Variable>* future = (Future<Variable>*) jfuture;
jclass clazz = env->GetObjectClass(junit);
@@ -273,7 +288,7 @@ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1ge
}
CHECK(future->isReady());
- Variable<string>* variable = new Variable<string>(future->get());
+ Variable* variable = new Variable(future->get());
// Variable variable = new Variable();
clazz = env->FindClass("org/apache/mesos/state/Variable");
@@ -296,13 +311,13 @@ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1ge
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __get_finalize
+ * Method: __fetch_finalize
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1finalize
+JNIEXPORT void JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1fetch_1finalize
(JNIEnv* env, jobject thiz, jlong jfuture)
{
- Future<Variable<string> >* future = (Future<Variable<string> >*) jfuture;
+ Future<Variable>* future = (Future<Variable>*) jfuture;
delete future;
}
@@ -310,27 +325,26 @@ JNIEXPORT void JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1get_1final
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __set
+ * Method: __store
* Signature: (Lorg/apache/mesos/state/Variable;)J
*/
-JNIEXPORT jlong JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set
+JNIEXPORT jlong JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1store
(JNIEnv* env, jobject thiz, jobject jvariable)
{
jclass clazz = env->GetObjectClass(jvariable);
jfieldID __variable = env->GetFieldID(clazz, "__variable", "J");
- Variable<string>* variable = (Variable<string>*)
- env->GetLongField(jvariable, __variable);
+ Variable* variable = (Variable*) env->GetLongField(jvariable, __variable);
clazz = env->GetObjectClass(thiz);
jfieldID __state = env->GetFieldID(clazz, "__state", "J");
- State<>* state = (State<>*) env->GetLongField(thiz, __state);
+ State* state = (State*) env->GetLongField(thiz, __state);
- Future<Option<Variable<string> > >* future =
- new Future<Option<Variable<string> > >(state->set(*variable));
+ Future<Option<Variable> >* future =
+ new Future<Option<Variable> >(state->store(*variable));
return (jlong) future;
}
@@ -338,14 +352,13 @@ JNIEXPORT jlong JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __set_cancel
+ * Method: __store_cancel
* Signature: (J)Z
*/
-JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1cancel
+JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1store_1cancel
(JNIEnv* env, jobject thiz, jlong jfuture)
{
- Future<Option<Variable<string> > >* future =
- (Future<Option<Variable<string> > >*) jfuture;
+ Future<Option<Variable> >* future = (Future<Option<Variable> >*) jfuture;
if (!future->isDiscarded()) {
future->discard();
@@ -358,14 +371,13 @@ JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1c
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __set_is_cancelled
+ * Method: __store_is_cancelled
* Signature: (J)Z
*/
-JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1is_1cancelled
+JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1store_1is_1cancelled
(JNIEnv* env, jobject thiz, jlong jfuture)
{
- Future<Option<Variable<string> > >* future =
- (Future<Option<Variable<string> > >*) jfuture;
+ Future<Option<Variable> >* future = (Future<Option<Variable> >*) jfuture;
return (jboolean) future->isDiscarded();
}
@@ -373,14 +385,13 @@ JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1i
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __set_is_done
+ * Method: __store_is_done
* Signature: (J)Z
*/
-JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1is_1done
+JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1store_1is_1done
(JNIEnv* env, jobject thiz, jlong jfuture)
{
- Future<Option<Variable<string> > >* future =
- (Future<Option<Variable<string> > >*) jfuture;
+ Future<Option<Variable> >* future = (Future<Option<Variable> >*) jfuture;
return (jboolean) !future->isPending();
}
@@ -388,14 +399,13 @@ JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1i
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __set_get
+ * Method: __store_get
* Signature: (J)Lorg/apache/mesos/state/Variable;
*/
-JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1get
+JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1store_1get
(JNIEnv* env, jobject thiz, jlong jfuture)
{
- Future<Option<Variable<string> > >* future =
- (Future<Option<Variable<string> > >*) jfuture;
+ Future<Option<Variable> >* future = (Future<Option<Variable> >*) jfuture;
future->await();
@@ -412,7 +422,7 @@ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1ge
CHECK(future->isReady());
if (future->get().isSome()) {
- Variable<string>* variable = new Variable<string>(future->get().get());
+ Variable* variable = new Variable(future->get().get());
// Variable variable = new Variable();
jclass clazz = env->FindClass("org/apache/mesos/state/Variable");
@@ -432,14 +442,13 @@ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1ge
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __set_get_timeout
+ * Method: __store_get_timeout
* Signature: (JJLjava/util/concurrent/TimeUnit;)Lorg/apache/mesos/state/Variable;
*/
-JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1get_1timeout
+JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1store_1get_1timeout
(JNIEnv* env, jobject thiz, jlong jfuture, jlong jtimeout, jobject junit)
{
- Future<Option<Variable<string> > >* future =
- (Future<Option<Variable<string> > >*) jfuture;
+ Future<Option<Variable> >* future = (Future<Option<Variable> >*) jfuture;
jclass clazz = env->GetObjectClass(junit);
@@ -464,7 +473,7 @@ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1ge
CHECK(future->isReady());
if (future->get().isSome()) {
- Variable<string>* variable = new Variable<string>(future->get().get());
+ Variable* variable = new Variable(future->get().get());
// Variable variable = new Variable();
clazz = env->FindClass("org/apache/mesos/state/Variable");
@@ -490,14 +499,186 @@ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1ge
/*
* Class: org_apache_mesos_state_ZooKeeperState
- * Method: __set_finalize
+ * Method: __store_finalize
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1store_1finalize
+ (JNIEnv* env, jobject thiz, jlong jfuture)
+{
+ Future<Option<Variable> >* future = (Future<Option<Variable> >*) jfuture;
+
+ delete future;
+}
+
+
+/*
+ * Class: org_apache_mesos_state_ZooKeeperState
+ * Method: __expunge
+ * Signature: (Lorg/apache/mesos/state/Variable;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1expunge
+ (JNIEnv* env, jobject thiz, jobject jvariable)
+{
+ jclass clazz = env->GetObjectClass(jvariable);
+
+ jfieldID __variable = env->GetFieldID(clazz, "__variable", "J");
+
+ Variable* variable = (Variable*) env->GetLongField(jvariable, __variable);
+
+ clazz = env->GetObjectClass(thiz);
+
+ jfieldID __state = env->GetFieldID(clazz, "__state", "J");
+
+ State* state = (State*) env->GetLongField(thiz, __state);
+
+ Future<bool>* future = new Future<bool>(state->expunge(*variable));
+
+ return (jlong) future;
+}
+
+
+/*
+ * Class: org_apache_mesos_state_ZooKeeperState
+ * Method: __expunge_cancel
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1expunge_1cancel
+ (JNIEnv* env, jobject thiz, jlong jfuture)
+{
+ Future<bool>* future = (Future<bool>*) jfuture;
+
+ if (!future->isDiscarded()) {
+ future->discard();
+ return (jboolean) future->isDiscarded();
+ }
+
+ return (jboolean) true;
+}
+
+
+/*
+ * Class: org_apache_mesos_state_ZooKeeperState
+ * Method: __expunge_is_cancelled
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1expunge_1is_1cancelled
+ (JNIEnv* env, jobject thiz, jlong jfuture)
+{
+ Future<bool>* future = (Future<bool>*) jfuture;
+
+ return (jboolean) future->isDiscarded();
+}
+
+
+/*
+ * Class: org_apache_mesos_state_ZooKeeperState
+ * Method: __expunge_is_done
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1expunge_1is_1done
+ (JNIEnv* env, jobject thiz, jlong jfuture)
+{
+ Future<bool>* future = (Future<bool>*) jfuture;
+
+ return (jboolean) !future->isPending();
+}
+
+
+/*
+ * Class: org_apache_mesos_state_ZooKeeperState
+ * Method: __expunge_get
+ * Signature: (J)Ljava/lang/Boolean;
+ */
+JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1expunge_1get
+ (JNIEnv* env, jobject thiz, jlong jfuture)
+{
+ Future<bool>* future = (Future<bool>*) jfuture;
+
+ future->await();
+
+ if (future->isFailed()) {
+ jclass clazz = env->FindClass("java/util/concurrent/ExecutionException");
+ env->ThrowNew(clazz, future->failure().c_str());
+ return NULL;
+ } else if (future->isDiscarded()) {
+ jclass clazz = env->FindClass("java/util/concurrent/CancellationException");
+ env->ThrowNew(clazz, "Future was discarded");
+ return NULL;
+ }
+
+ CHECK(future->isReady());
+
+ if (future->get()) {
+ jclass clazz = env->FindClass("java/lang/Boolean");
+ jfieldID TRUE = env->GetStaticFieldID(clazz, "TRUE", "Ljava/lang/Boolean;");
+ return env->GetStaticObjectField(clazz, TRUE);
+ }
+
+ jclass clazz = env->FindClass("java/lang/Boolean");
+ jfieldID FALSE = env->GetStaticFieldID(clazz, "FALSE", "Ljava/lang/Boolean;");
+ return env->GetStaticObjectField(clazz, FALSE);
+}
+
+
+/*
+ * Class: org_apache_mesos_state_ZooKeeperState
+ * Method: __expunge_get_timeout
+ * Signature: (JJLjava/util/concurrent/TimeUnit;)Ljava/lang/Boolean;
+ */
+JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1expunge_1get_1timeout
+ (JNIEnv* env, jobject thiz, jlong jfuture, jlong jtimeout, jobject junit)
+{
+ Future<bool>* future = (Future<bool>*) jfuture;
+
+ jclass clazz = env->GetObjectClass(junit);
+
+ // long seconds = unit.toSeconds(time);
+ jmethodID toSeconds = env->GetMethodID(clazz, "toSeconds", "(J)J");
+
+ jlong jseconds = env->CallLongMethod(junit, toSeconds, jtimeout);
+
+ Seconds seconds(jseconds);
+
+ if (future->await(seconds)) {
+ if (future->isFailed()) {
+ clazz = env->FindClass("java/util/concurrent/ExecutionException");
+ env->ThrowNew(clazz, future->failure().c_str());
+ return NULL;
+ } else if (future->isDiscarded()) {
+ clazz = env->FindClass("java/util/concurrent/CancellationException");
+ env->ThrowNew(clazz, "Future was discarded");
+ return NULL;
+ }
+
+ CHECK(future->isReady());
+
+ if (future->get()) {
+ jclass clazz = env->FindClass("java/lang/Boolean");
+ jfieldID TRUE = env->GetStaticFieldID(clazz, "TRUE", "Ljava/lang/Boolean;");
+ return env->GetStaticObjectField(clazz, TRUE);
+ }
+
+ jclass clazz = env->FindClass("java/lang/Boolean");
+ jfieldID FALSE = env->GetStaticFieldID(clazz, "FALSE", "Ljava/lang/Boolean;");
+ return env->GetStaticObjectField(clazz, FALSE);
+ }
+
+ clazz = env->FindClass("java/util/concurrent/TimeoutException");
+ env->ThrowNew(clazz, "Failed to wait for future within timeout");
+
+ return NULL;
+}
+
+
+/*
+ * Class: org_apache_mesos_state_ZooKeeperState
+ * Method: __expunge_finalize
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1set_1finalize
+JNIEXPORT void JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1expunge_1finalize
(JNIEnv* env, jobject thiz, jlong jfuture)
{
- Future<Option<Variable<string> > >* future =
- (Future<Option<Variable<string> > >*) jfuture;
+ Future<bool>* future = (Future<bool>*) jfuture;
delete future;
}
@@ -515,9 +696,10 @@ JNIEXPORT jlong JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1names
jfieldID __state = env->GetFieldID(clazz, "__state", "J");
- State<>* state = (State<>*) env->GetLongField(thiz, __state);
+ State* state = (State*) env->GetLongField(thiz, __state);
- Future<vector<string> >* future = new Future<vector<string> >(state->names());
+ Future<vector<string> >* future =
+ new Future<vector<string> >(state->names());
return (jlong) future;
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/java/src/org/apache/mesos/state/InMemoryState.java
----------------------------------------------------------------------
diff --git a/src/java/src/org/apache/mesos/state/InMemoryState.java b/src/java/src/org/apache/mesos/state/InMemoryState.java
index 5de921e..7addd2d 100644
--- a/src/java/src/org/apache/mesos/state/InMemoryState.java
+++ b/src/java/src/org/apache/mesos/state/InMemoryState.java
@@ -32,7 +32,7 @@ import java.util.concurrent.FutureTask;
*/
public class InMemoryState implements State {
@Override
- public Future<Variable> get(String name) {
+ public Future<Variable> fetch(String name) {
Entry entry = entries.get(name); // Is null if doesn't exist.
if (entry == null) {
@@ -40,17 +40,21 @@ public class InMemoryState implements State {
entry.name = name;
entry.uuid = UUID.randomUUID();
entry.value = new byte[0];
- entries.put(name, entry);
- entry = entries.putIfAbsent(name, entry);
+
+ // We use 'putIfAbsent' because multiple threads might be
+ // attempting to fetch a "new" variable at the same time.
+ if (entries.putIfAbsent(name, entry) != null) {
+ return fetch(name);
+ }
}
- assert entry != null; // ConcurrentMap.putIfAbsent should not return null.
+ assert entry != null;
return futureFrom((Variable) new InMemoryVariable(entry));
}
@Override
- public Future<Variable> set(Variable v) {
+ public Future<Variable> store(Variable v) {
InMemoryVariable variable = (InMemoryVariable) v;
Entry entry = new Entry();
@@ -66,6 +70,13 @@ public class InMemoryState implements State {
}
@Override
+ public Future<Boolean> expunge(Variable v) {
+ InMemoryVariable variable = (InMemoryVariable) v;
+
+ return futureFrom(entries.remove(variable.entry.name, variable.entry));
+ }
+
+ @Override
public Future<Iterator<String>> names() {
return futureFrom(entries.keySet().iterator());
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/java/src/org/apache/mesos/state/State.java
----------------------------------------------------------------------
diff --git a/src/java/src/org/apache/mesos/state/State.java b/src/java/src/org/apache/mesos/state/State.java
index 81b8685..dccb0ff 100644
--- a/src/java/src/org/apache/mesos/state/State.java
+++ b/src/java/src/org/apache/mesos/state/State.java
@@ -30,18 +30,18 @@ import java.util.concurrent.Future;
* fetched. Varying implementations of state provide varying
* replicated guarantees.
*
- * Note that the semantics of 'get' and 'set' provide atomicity. That
- * is, you can not set a variable that has changed since you did the
- * last get. That is, if a set succeeds then no other writes have been
- * performed on the variable since your get.
+ * Note that the semantics of 'fetch' and 'store' provide
+ * atomicity. That is, you can not store a variable that has changed
+ * since you did the last fetch. That is, if a store succeeds then no
+ * other writes have been performed on the variable since your fetch.
*
* Example:
*
* State state = new ZooKeeperState();
- * Future<Variable> variable = state.get("machines");
+ * Future<Variable> variable = state.fetch("machines");
* Variable machines = variable.get();
* machines = machines.mutate(...);
- * variable = state.set(machines);
+ * variable = state.store(machines);
* machines = variable.get();
*/
public interface State {
@@ -49,14 +49,20 @@ public interface State {
* Returns an immutable "variable" representing the current value
* from the state associated with the specified name.
*/
- Future<Variable> get(String name);
+ Future<Variable> fetch(String name);
/**
* Returns an immutable "variable" representing the current value in
* the state if updating the specified variable in the state was
* successful, otherwise returns null.
*/
- Future<Variable> set(Variable variable);
+ Future<Variable> store(Variable variable);
+
+ /**
+ * Returns true if successfully expunged the variable from the state
+ * or false if the variable did not exist or was no longer valid.
+ */
+ Future<Boolean> expunge(Variable variable);
/**
* Returns an iterator of variable names in the state.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/java/src/org/apache/mesos/state/ZooKeeperState.java
----------------------------------------------------------------------
diff --git a/src/java/src/org/apache/mesos/state/ZooKeeperState.java b/src/java/src/org/apache/mesos/state/ZooKeeperState.java
index 1ef591a..999d593 100644
--- a/src/java/src/org/apache/mesos/state/ZooKeeperState.java
+++ b/src/java/src/org/apache/mesos/state/ZooKeeperState.java
@@ -73,86 +73,125 @@ public class ZooKeeperState implements State {
}
@Override
- public Future<Variable> get(final String name) {
- final long future = __get(name); // Asynchronously start the operation.
+ public Future<Variable> fetch(final String name) {
+ final long future = __fetch(name); // Asynchronously start the operation.
return new Future<Variable>() {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
if (mayInterruptIfRunning) {
- return __get_cancel(future);
+ return __fetch_cancel(future);
}
return false; // Should not interrupt and already running (or finished).
}
@Override
public boolean isCancelled() {
- return __get_is_cancelled(future);
+ return __fetch_is_cancelled(future);
}
@Override
public boolean isDone() {
- return __get_is_done(future);
+ return __fetch_is_done(future);
}
@Override
public Variable get() throws InterruptedException, ExecutionException {
- return __get_get(future);
+ return __fetch_get(future);
}
@Override
public Variable get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
- return __get_get_timeout(future, timeout, unit);
+ return __fetch_get_timeout(future, timeout, unit);
}
@Override
protected void finalize() {
- __get_finalize(future);
+ __fetch_finalize(future);
}
};
}
@Override
- public Future<Variable> set(Variable variable) {
- final long future = __set(variable); // Asynchronously start the operation.
+ public Future<Variable> store(Variable variable) {
+ final long future = __store(variable); // Asynchronously start the operation.
return new Future<Variable>() {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
if (mayInterruptIfRunning) {
- return __set_cancel(future);
+ return __store_cancel(future);
}
return false; // Should not interrupt and already running (or finished).
}
@Override
public boolean isCancelled() {
- return __set_is_cancelled(future);
+ return __store_is_cancelled(future);
}
@Override
public boolean isDone() {
- return __set_is_done(future);
+ return __store_is_done(future);
}
@Override
public Variable get() throws InterruptedException, ExecutionException {
- return __set_get(future);
+ return __store_get(future);
}
@Override
public Variable get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
- return __set_get_timeout(future, timeout, unit);
+ return __store_get_timeout(future, timeout, unit);
}
@Override
protected void finalize() {
- __set_finalize(future);
+ __store_finalize(future);
}
};
}
@Override
+ public Future<Boolean> expunge(Variable variable) {
+ final long future = __expunge(variable); // Asynchronously start the operation.
+ return new Future<Boolean>() {
+ @Override
+ public boolean cancel(boolean mayInterruptIfRunning) {
+ if (mayInterruptIfRunning) {
+ return __expunge_cancel(future);
+ }
+ return false; // Should not interrupt and already running (or finished).
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return __expunge_is_cancelled(future);
+ }
+
+ @Override
+ public boolean isDone() {
+ return __expunge_is_done(future);
+ }
+
+ @Override
+ public Boolean get() throws InterruptedException, ExecutionException {
+ return __expunge_get(future);
+ }
+
+ @Override
+ public Boolean get(long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ return __expunge_get_timeout(future, timeout, unit);
+ }
+
+ @Override
+ protected void finalize() {
+ __expunge_finalize(future);
+ }
+ };
+ }
+
public Future<Iterator<String>> names() {
final long future = __names(); // Asynchronously start the operation.
return new Future<Iterator<String>>() {
@@ -206,24 +245,33 @@ public class ZooKeeperState implements State {
protected native void finalize();
- // Native implementations of get, set, and names.
- private native long __get(String name);
- private native boolean __get_cancel(long future);
- private native boolean __get_is_cancelled(long future);
- private native boolean __get_is_done(long future);
- private native Variable __get_get(long future);
- private native Variable __get_get_timeout(
+ // Native implementations of 'fetch', 'store', 'expunge', and 'names'.
+ private native long __fetch(String name);
+ private native boolean __fetch_cancel(long future);
+ private native boolean __fetch_is_cancelled(long future);
+ private native boolean __fetch_is_done(long future);
+ private native Variable __fetch_get(long future);
+ private native Variable __fetch_get_timeout(
+ long future, long timeout, TimeUnit unit);
+ private native void __fetch_finalize(long future);
+
+ private native long __store(Variable variable);
+ private native boolean __store_cancel(long future);
+ private native boolean __store_is_cancelled(long future);
+ private native boolean __store_is_done(long future);
+ private native Variable __store_get(long future);
+ private native Variable __store_get_timeout(
long future, long timeout, TimeUnit unit);
- private native void __get_finalize(long future);
-
- private native long __set(Variable variable);
- private native boolean __set_cancel(long future);
- private native boolean __set_is_cancelled(long future);
- private native boolean __set_is_done(long future);
- private native Variable __set_get(long future);
- private native Variable __set_get_timeout(
+ private native void __store_finalize(long future);
+
+ private native long __expunge(Variable variable);
+ private native boolean __expunge_cancel(long future);
+ private native boolean __expunge_is_cancelled(long future);
+ private native boolean __expunge_is_done(long future);
+ private native Boolean __expunge_get(long future);
+ private native Boolean __expunge_get_timeout(
long future, long timeout, TimeUnit unit);
- private native void __set_finalize(long future);
+ private native void __expunge_finalize(long future);
private native long __names();
private native boolean __names_cancel(long future);
@@ -234,5 +282,6 @@ public class ZooKeeperState implements State {
long future, long timeout, TimeUnit unit);
private native void __names_finalize(long future);
+ private long __storage;
private long __state;
};
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/master/registry.hpp
----------------------------------------------------------------------
diff --git a/src/master/registry.hpp b/src/master/registry.hpp
new file mode 100644
index 0000000..d3cbe56
--- /dev/null
+++ b/src/master/registry.hpp
@@ -0,0 +1,24 @@
+/**
+ * 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.
+ */
+
+#ifndef __MASTER_REGISTRY_HPP__
+#define __MASTER_REGISTRY_HPP__
+
+#include "master/registry.pb.h"
+
+#endif // __MASTER_REGISTRY_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/master/registry.proto
----------------------------------------------------------------------
diff --git a/src/master/registry.proto b/src/master/registry.proto
new file mode 100644
index 0000000..877bfa1
--- /dev/null
+++ b/src/master/registry.proto
@@ -0,0 +1,32 @@
+/**
+ * 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.
+ */
+
+import "mesos.proto";
+
+package mesos.internal.registry;
+
+message Slave {
+ // TODO(benh): Add other information here that is internal to Mesos
+ // and shouldn't be exposed in SlaveInfo.
+ required SlaveInfo info = 2;
+}
+
+
+message Registry {
+ repeated Slave slaves = 1;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/messages/messages.hpp
----------------------------------------------------------------------
diff --git a/src/messages/messages.hpp b/src/messages/messages.hpp
index 285cc65..98038c0 100644
--- a/src/messages/messages.hpp
+++ b/src/messages/messages.hpp
@@ -19,6 +19,46 @@
#ifndef __MESSAGES_HPP__
#define __MESSAGES_HPP__
+#include <google/protobuf/message.h>
+
+#include <google/protobuf/io/zero_copy_stream_impl.h> // For ArrayInputStream.
+
+#include <string>
+
+#include <stout/try.hpp>
+
#include "messages/messages.pb.h"
+namespace messages {
+
+template <typename T>
+Try<T> deserialize(const std::string& value)
+{
+ T t;
+ (void) static_cast<google::protobuf::Message*>(&t);
+
+ google::protobuf::io::ArrayInputStream stream(value.data(), value.size());
+ if (!t.ParseFromZeroCopyStream(&stream)) {
+ return Try<T>::error(
+ "Failed to deserialize " + t.GetDescriptor()->full_name());
+ }
+ return t;
+}
+
+
+template <typename T>
+Try<std::string> serialize(const T& t)
+{
+ (void) static_cast<const google::protobuf::Message*>(&t);
+
+ std::string value;
+ if (!t.SerializeToString(&value)) {
+ return Try<std::string>::error(
+ "Failed to serialize " + t.GetDescriptor()->full_name());
+ }
+ return value;
+}
+
+} // namespace messages {
+
#endif // __MESSAGES_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/messages/messages.proto
----------------------------------------------------------------------
diff --git a/src/messages/messages.proto b/src/messages/messages.proto
index 3f02474..2c196ee 100644
--- a/src/messages/messages.proto
+++ b/src/messages/messages.proto
@@ -73,12 +73,6 @@ message StatusUpdateRecord {
}
-message Slaves
-{
- repeated SlaveInfo infos = 1;
-}
-
-
message SubmitSchedulerRequest
{
required string name = 1;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/state/leveldb.cpp
----------------------------------------------------------------------
diff --git a/src/state/leveldb.cpp b/src/state/leveldb.cpp
index 5b3fe91..69d5714 100644
--- a/src/state/leveldb.cpp
+++ b/src/state/leveldb.cpp
@@ -2,6 +2,8 @@
#include <google/protobuf/message.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h> // For ArrayInputStream.
+
#include <string>
#include <vector>
@@ -20,7 +22,7 @@
#include "messages/state.hpp"
#include "state/leveldb.hpp"
-#include "state/state.hpp"
+#include "state/storage.hpp"
using namespace process;
@@ -31,17 +33,17 @@ namespace mesos {
namespace internal {
namespace state {
-LevelDBStateProcess::LevelDBStateProcess(const string& _path)
+LevelDBStorageProcess::LevelDBStorageProcess(const string& _path)
: path(_path), db(NULL) {}
-LevelDBStateProcess::~LevelDBStateProcess()
+LevelDBStorageProcess::~LevelDBStorageProcess()
{
- delete db; // Might be null if open failed in LevelDBStateProcess::initialize.
+ delete db; // NULL if open failed in LevelDBStorageProcess::initialize.
}
-void LevelDBStateProcess::initialize()
+void LevelDBStorageProcess::initialize()
{
leveldb::Options options;
options.create_if_missing = true;
@@ -58,7 +60,7 @@ void LevelDBStateProcess::initialize()
}
-Future<vector<string> > LevelDBStateProcess::names()
+Future<vector<string> > LevelDBStorageProcess::names()
{
if (error.isSome()) {
return Future<vector<string> >::failed(error.get());
@@ -81,13 +83,13 @@ Future<vector<string> > LevelDBStateProcess::names()
}
-Future<Option<Entry> > LevelDBStateProcess::fetch(const string& name)
+Future<Option<Entry> > LevelDBStorageProcess::get(const string& name)
{
if (error.isSome()) {
return Future<Option<Entry> >::failed(error.get());
}
- Try<Option<Entry> > option = get(name);
+ Try<Option<Entry> > option = read(name);
if (option.isError()) {
return Future<Option<Entry> >::failed(option.error());
@@ -97,16 +99,16 @@ Future<Option<Entry> > LevelDBStateProcess::fetch(const string& name)
}
-Future<bool> LevelDBStateProcess::swap(const Entry& entry, const UUID& uuid)
+Future<bool> LevelDBStorageProcess::set(const Entry& entry, const UUID& uuid)
{
if (error.isSome()) {
return Future<bool>::failed(error.get());
}
- // We do a fetch first to make sure the version has not changed. This
+ // We do a read first to make sure the version has not changed. This
// could be optimized in the future, for now it will probably hit
// the cache anyway.
- Try<Option<Entry> > option = get(entry.name());
+ Try<Option<Entry> > option = read(entry.name());
if (option.isError()) {
return Future<bool>::failed(option.error());
@@ -118,11 +120,11 @@ Future<bool> LevelDBStateProcess::swap(const Entry& entry, const UUID& uuid)
}
}
- // Note that there is no need to do the DB::Get and DB::Put
- // "atomically" because only one db can be opened at a time, so
- // there can not be any writes that occur concurrently.
+ // Note that the read (i.e., DB::Get) and the write (i.e., DB::Put)
+ // are inherently "atomic" because only one db can be opened at a
+ // time, so there can not be any writes that occur concurrently.
- Try<bool> result = put(entry);
+ Try<bool> result = write(entry);
if (result.isError()) {
return Future<bool>::failed(result.error());
@@ -132,7 +134,48 @@ Future<bool> LevelDBStateProcess::swap(const Entry& entry, const UUID& uuid)
}
-Try<Option<Entry> > LevelDBStateProcess::get(const string& name)
+Future<bool> LevelDBStorageProcess::expunge(const Entry& entry)
+{
+ if (error.isSome()) {
+ return Future<bool>::failed(error.get());
+ }
+
+ // We do a read first to make sure the version has not changed. This
+ // could be optimized in the future, for now it will probably hit
+ // the cache anyway.
+ Try<Option<Entry> > option = read(entry.name());
+
+ if (option.isError()) {
+ return Future<bool>::failed(option.error());
+ }
+
+ if (option.get().isNone()) {
+ return false;
+ }
+
+ if (UUID::fromBytes(option.get().get().uuid()) !=
+ UUID::fromBytes(entry.uuid())) {
+ return false;
+ }
+
+ // Note that the read (i.e., DB::Get) and DB::Delete are inherently
+ // "atomic" because only one db can be opened at a time, so there
+ // can not be any writes that occur concurrently.
+
+ leveldb::WriteOptions options;
+ options.sync = true;
+
+ leveldb::Status status = db->Delete(options, entry.name());
+
+ if (!status.ok()) {
+ return Future<bool>::failed(status.ToString());
+ }
+
+ return true;
+}
+
+
+Try<Option<Entry> > LevelDBStorageProcess::read(const string& name)
{
CHECK(error.isNone());
@@ -160,7 +203,7 @@ Try<Option<Entry> > LevelDBStateProcess::get(const string& name)
}
-Try<bool> LevelDBStateProcess::put(const Entry& entry)
+Try<bool> LevelDBStorageProcess::write(const Entry& entry)
{
CHECK(error.isNone());
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/state/leveldb.hpp
----------------------------------------------------------------------
diff --git a/src/state/leveldb.hpp b/src/state/leveldb.hpp
index 94f306b..14a94cc 100644
--- a/src/state/leveldb.hpp
+++ b/src/state/leveldb.hpp
@@ -14,8 +14,7 @@
#include "messages/state.hpp"
-#include "state/serializer.hpp"
-#include "state/state.hpp"
+#include "state/storage.hpp"
// Forward declarations.
namespace leveldb { class DB; }
@@ -26,46 +25,44 @@ namespace internal {
namespace state {
// More forward declarations.
-class LevelDBStateProcess;
+class LevelDBStorageProcess;
-template <typename Serializer = StringSerializer>
-class LevelDBState : public State<Serializer>
+class LevelDBStorage : public Storage
{
public:
- LevelDBState(const std::string& path);
- virtual ~LevelDBState();
+ LevelDBStorage(const std::string& path);
+ virtual ~LevelDBStorage();
- // State implementation.
+ // Storage implementation.
+ virtual process::Future<Option<Entry> > get(const std::string& name);
+ virtual process::Future<bool> set(const Entry& entry, const UUID& uuid);
+ virtual process::Future<bool> expunge(const Entry& entry);
virtual process::Future<std::vector<std::string> > names();
-protected:
- // More State implementation.
- virtual process::Future<Option<Entry> > fetch(const std::string& name);
- virtual process::Future<bool> swap(const Entry& entry, const UUID& uuid);
-
private:
- LevelDBStateProcess* process;
+ LevelDBStorageProcess* process;
};
-class LevelDBStateProcess : public process::Process<LevelDBStateProcess>
+class LevelDBStorageProcess : public process::Process<LevelDBStorageProcess>
{
public:
- LevelDBStateProcess(const std::string& path);
- virtual ~LevelDBStateProcess();
+ LevelDBStorageProcess(const std::string& path);
+ virtual ~LevelDBStorageProcess();
virtual void initialize();
- // State implementation.
+ // Storage implementation.
+ process::Future<Option<Entry> > get(const std::string& name);
+ process::Future<bool> set(const Entry& entry, const UUID& uuid);
+ process::Future<bool> expunge(const Entry& entry);
process::Future<std::vector<std::string> > names();
- process::Future<Option<Entry> > fetch(const std::string& name);
- process::Future<bool> swap(const Entry& entry, const UUID& uuid);
private:
// Helpers for interacting with leveldb.
- Try<Option<Entry> > get(const std::string& name);
- Try<bool> put(const Entry& entry);
+ Try<Option<Entry> > read(const std::string& name);
+ Try<bool> write(const Entry& entry);
const std::string path;
leveldb::DB* db;
@@ -74,16 +71,14 @@ private:
};
-template <typename Serializer>
-LevelDBState<Serializer>::LevelDBState(const std::string& path)
+inline LevelDBStorage::LevelDBStorage(const std::string& path)
{
- process = new LevelDBStateProcess(path);
+ process = new LevelDBStorageProcess(path);
process::spawn(process);
}
-template <typename Serializer>
-LevelDBState<Serializer>::~LevelDBState()
+inline LevelDBStorage::~LevelDBStorage()
{
process::terminate(process);
process::wait(process);
@@ -91,27 +86,31 @@ LevelDBState<Serializer>::~LevelDBState()
}
-template <typename Serializer>
-process::Future<std::vector<std::string> > LevelDBState<Serializer>::names()
+inline process::Future<Option<Entry> > LevelDBStorage::get(
+ const std::string& name)
{
- return process::dispatch(process, &LevelDBStateProcess::names);
+ return process::dispatch(process, &LevelDBStorageProcess::get, name);
}
-template <typename Serializer>
-process::Future<Option<Entry> > LevelDBState<Serializer>::fetch(
- const std::string& name)
+inline process::Future<bool> LevelDBStorage::set(
+ const Entry& entry,
+ const UUID& uuid)
{
- return process::dispatch(process, &LevelDBStateProcess::fetch, name);
+ return process::dispatch(process, &LevelDBStorageProcess::set, entry, uuid);
}
-template <typename Serializer>
-process::Future<bool> LevelDBState<Serializer>::swap(
- const Entry& entry,
- const UUID& uuid)
+inline process::Future<bool> LevelDBStorage::expunge(
+ const Entry& entry)
+{
+ return process::dispatch(process, &LevelDBStorageProcess::expunge, entry);
+}
+
+
+inline process::Future<std::vector<std::string> > LevelDBStorage::names()
{
- return process::dispatch(process, &LevelDBStateProcess::swap, entry, uuid);
+ return process::dispatch(process, &LevelDBStorageProcess::names);
}
} // namespace state {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/state/protobuf.hpp
----------------------------------------------------------------------
diff --git a/src/state/protobuf.hpp b/src/state/protobuf.hpp
new file mode 100644
index 0000000..75e082b
--- /dev/null
+++ b/src/state/protobuf.hpp
@@ -0,0 +1,166 @@
+/**
+ * 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.
+ */
+
+#ifndef __STATE_PROTOBUF_HPP__
+#define __STATE_PROTOBUF_HPP__
+
+#include <string>
+
+#include <process/future.hpp>
+
+#include <stout/lambda.hpp>
+#include <stout/option.hpp>
+#include <stout/try.hpp>
+#include <stout/uuid.hpp>
+
+#include "messages/messages.hpp"
+#include "messages/state.hpp"
+
+#include "state/state.hpp"
+#include "state/storage.hpp"
+
+namespace mesos {
+namespace internal {
+namespace state {
+namespace protobuf {
+
+template <typename T>
+class Variable
+{
+public:
+ T get() const
+ {
+ return t;
+ }
+
+ Variable mutate(const T& t) const
+ {
+ Variable variable(*this);
+ variable.t = t;
+ return variable;
+ }
+
+private:
+ friend class State; // Creates and manages variables.
+
+ Variable(const state::Variable& _variable, const T& _t)
+ : variable(_variable), t(_t)
+ {}
+
+ state::Variable variable; // Not const to keep Variable assignable.
+ T t;
+};
+
+
+class State : public state::State
+{
+public:
+ State(Storage* storage) : state::State(storage) {}
+ virtual ~State() {}
+
+ // Returns a variable from the state, creating a new one if one
+ // previously did not exist (or an error if one occurs).
+ template <typename T>
+ process::Future<Variable<T> > fetch(const std::string& name);
+
+ // Returns the variable specified if it was successfully stored in
+ // the state, otherwise returns none if the version of the variable
+ // was no longer valid, or an error if one occurs.
+ template <typename T>
+ process::Future<Option<Variable<T> > > store(const Variable<T>& variable);
+
+ // Expunges the variable from the state.
+ template <typename T>
+ process::Future<bool> expunge(const Variable<T>& variable);
+
+private:
+ // Helpers to handle future results from fetch and swap. We make
+ // these static members of State for friend access to Variable's
+ // constructor.
+ template <typename T>
+ static process::Future<Variable<T> > _fetch(
+ const state::Variable& option);
+
+ template <typename T>
+ static process::Future<Option<Variable<T> > > _store(
+ const T& t,
+ const Option<state::Variable>& variable);
+};
+
+
+template <typename T>
+process::Future<Variable<T> > State::fetch(const std::string& name)
+{
+ return state::State::fetch(name)
+ .then(lambda::bind(&State::template _fetch<T>, lambda::_1));
+}
+
+
+template <typename T>
+process::Future<Variable<T> > State::_fetch(
+ const state::Variable& variable)
+{
+ Try<T> t = messages::deserialize<T>(variable.value());
+ if (t.isError()) {
+ return process::Future<Variable<T> >::failed(t.error());
+ }
+
+ return Variable<T>(variable, t.get());
+}
+
+
+template <typename T>
+process::Future<Option<Variable<T> > > State::store(
+ const Variable<T>& variable)
+{
+ Try<std::string> value = messages::serialize(variable.t);
+
+ if (value.isError()) {
+ return process::Future<Option<Variable<T> > >::failed(value.error());
+ }
+
+ return state::State::store(variable.variable.mutate(value.get()))
+ .then(lambda::bind(&State::template _store<T>, variable.t, lambda::_1));
+}
+
+
+template <typename T>
+process::Future<Option<Variable<T> > > State::_store(
+ const T& t,
+ const Option<state::Variable>& variable)
+{
+ if (variable.isSome()) {
+ return Option<Variable<T> >::some(Variable<T>(variable.get(), t));
+ }
+
+ return None();
+}
+
+
+template <typename T>
+process::Future<bool> State::expunge(const Variable<T>& variable)
+{
+ return state::State::expunge(variable.variable);
+}
+
+} // namespace protobuf {
+} // namespace state {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __STATE_PROTOBUF_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/state/serializer.hpp
----------------------------------------------------------------------
diff --git a/src/state/serializer.hpp b/src/state/serializer.hpp
deleted file mode 100644
index bd8c5df..0000000
--- a/src/state/serializer.hpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef __STATE_SERIALIZER_HPP__
-#define __STATE_SERIALIZER_HPP__
-
-#include <google/protobuf/message.h>
-
-#include <google/protobuf/io/zero_copy_stream_impl.h> // For ArrayInputStream.
-
-#include <string>
-
-#include <stout/error.hpp>
-#include <stout/try.hpp>
-
-namespace mesos {
-namespace internal {
-namespace state {
-
-struct StringSerializer
-{
- template <typename T>
- static Try<std::string> deserialize(const std::string& value)
- {
- return value;
- }
-
- template <typename T>
- static Try<std::string> serialize(const std::string& value)
- {
- return value;
- }
-};
-
-
-struct ProtobufSerializer
-{
- template <typename T>
- static Try<T> deserialize(const std::string& value)
- {
- T t;
- (void)static_cast<google::protobuf::Message*>(&t);
-
- google::protobuf::io::ArrayInputStream stream(value.data(), value.size());
- if (!t.ParseFromZeroCopyStream(&stream)) {
- return Error(
- "Failed to deserialize " + t.GetDescriptor()->full_name());
- }
- return t;
- }
-
- template <typename T>
- static Try<std::string> serialize(const T& t)
- {
- // TODO(benh): Actually store the descriptor so that we can verify
- // type information (and compatibility) when we deserialize.
- std::string value;
- if (!t.SerializeToString(&value)) {
- return Error(
- "Failed to serialize " + t.GetDescriptor()->full_name());
- }
- return value;
- }
-};
-
-} // namespace state {
-} // namespace internal {
-} // namespace mesos {
-
-#endif // __STATE_SERIALIZER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/state/state.hpp
----------------------------------------------------------------------
diff --git a/src/state/state.hpp b/src/state/state.hpp
index c616e00..b3abf89 100644
--- a/src/state/state.hpp
+++ b/src/state/state.hpp
@@ -24,16 +24,15 @@
#include <process/future.hpp>
+#include <stout/lambda.hpp>
#include <stout/none.hpp>
#include <stout/option.hpp>
#include <stout/try.hpp>
#include <stout/uuid.hpp>
-#include "logging/logging.hpp"
-
#include "messages/state.hpp"
-#include "state/serializer.hpp"
+#include "state/storage.hpp"
namespace mesos {
namespace internal {
@@ -46,187 +45,153 @@ namespace state {
// fetched. Varying implementations of state provide varying
// replicated guarantees.
//
-// Note that the semantics of 'get' and 'set' provide atomicity. That
-// is, you can not set a variable that has changed since you did the
-// last get. That is, if a set succeeds then no other writes have been
-// performed on the variable since your get.
-
+// Note that the semantics of 'fetch' and 'store' provide
+// atomicity. That is, you can not store a variable that has changed
+// since you did the last fetch. That is, if a store succeeds then no
+// other writes have been performed on the variable since your fetch.
+//
// Example:
-
-// State<ProtobufSerializer>* state = new ZooKeeperState<ProtobufSerializer>();
-// Future<Variable<Slaves> > variable = state->get<Slaves>("slaves");
-// Variable<Slaves> slaves = variable.get();
-// slaves->add_infos()->MergeFrom(info);
-// Future<bool> set = state->set(&slaves);
+//
+// Storage* storage = new ZooKeeperStorage();
+// State* state = new State(storage);
+// Future<Variable> variable = state->fetch("slaves");
+// std::string value = update(variable.value());
+// variable = variable.mutate(value);
+// state->store(variable);
// Forward declarations.
-template <typename Serializer>
class State;
-class ZooKeeperStateProcess;
-template <typename T>
+// Wrapper around a state "entry" to force immutability.
class Variable
{
public:
- T* operator -> ()
+ std::string value() const
{
- return &t;
+ return entry.value();
+ }
+
+ Variable mutate(const std::string& value) const
+ {
+ Variable variable(*this);
+ variable.entry.set_value(value);
+ return variable;
}
private:
- template <typename Serializer>
friend class State; // Creates and manages variables.
- Variable(const Entry& _entry, const T& _t)
- : entry(_entry), t(_t)
+ Variable(const Entry& _entry)
+ : entry(_entry)
{}
- Entry entry; // Not const so Variable is copyable.
- T t;
+ Entry entry; // Not const to keep Variable assignable.
};
-template <typename Serializer = StringSerializer>
class State
{
public:
- State() {}
+ State(Storage* _storage) : storage(_storage) {}
virtual ~State() {}
// Returns a variable from the state, creating a new one if one
// previously did not exist (or an error if one occurs).
- template <typename T>
- process::Future<Variable<T> > get(const std::string& name);
+ process::Future<Variable> fetch(const std::string& name);
- // Returns true if the variable was successfully set in the state,
- // otherwise false if the version of the variable was no longer
- // valid (or an error if one occurs).
- template <typename T>
- process::Future<Option<Variable<T> > > set(const Variable<T>& variable);
+ // Returns the variable specified if it was successfully stored in
+ // the state, otherwise returns none if the version of the variable
+ // was no longer valid, or an error if one occurs.
+ process::Future<Option<Variable> > store(const Variable& variable);
- // Returns the collection of variable names in the state.
- virtual process::Future<std::vector<std::string> > names() = 0;
+ // Returns true if successfully expunged the variable from the state.
+ process::Future<bool> expunge(const Variable& variable);
-protected:
- // Fetch and swap state entries, factored out to allow State
- // implementations to be agnostic of Variable which is templated.
- virtual process::Future<Option<Entry> > fetch(const std::string& name) = 0;
- virtual process::Future<bool> swap(const Entry& entry, const UUID& uuid) = 0;
+ // Returns the collection of variable names in the state.
+ process::Future<std::vector<std::string> > names();
private:
// Helpers to handle future results from fetch and swap. We make
// these static members of State for friend access to Variable's
// constructor.
- template <typename T>
- static process::Future<Variable<T> > _get(
+ static process::Future<Variable> _fetch(
const std::string& name,
const Option<Entry>& option);
- template <typename T>
- static process::Future<Option<Variable<T> > > _set(
+ static process::Future<Option<Variable> > _store(
const Entry& entry,
- const T& t,
const bool& b); // TODO(benh): Remove 'const &' after fixing libprocess.
+
+ Storage* storage;
};
-template <typename Serializer>
-template <typename T>
-process::Future<Variable<T> > State<Serializer>::_get(
+inline process::Future<Variable> State::fetch(const std::string& name)
+{
+ return storage->get(name)
+ .then(lambda::bind(&State::_fetch, name, lambda::_1));
+}
+
+
+inline process::Future<Variable> State::_fetch(
const std::string& name,
const Option<Entry>& option)
{
if (option.isSome()) {
- const Entry& entry = option.get();
-
- Try<T> t = Serializer::template deserialize<T>(entry.value());
-
- if (t.isError()) {
- return process::Future<Variable<T> >::failed(t.error());
- }
-
- return Variable<T>(entry, t.get());
+ return Variable(option.get());
}
- // Otherwise, construct a Variable out of a new Entry with a default
- // value for T (and a random UUID to start).
- T t;
+ // Otherwise, construct a Variable with a new Entry (with a random
+ // UUID and no value to start).
+ Entry entry;
+ entry.set_name(name);
+ entry.set_uuid(UUID::random().toBytes());
+
+ return Variable(entry);
+}
- Try<std::string> value = Serializer::template serialize<T>(t);
- if (value.isError()) {
- return process::Future<Variable<T> >::failed(value.error());
- }
+inline process::Future<Option<Variable> > State::store(const Variable& variable)
+{
+ // Note that we try and swap an entry even if the value didn't change!
+ UUID uuid = UUID::fromBytes(variable.entry.uuid());
+ // Create a new entry to replace the existing entry provided the
+ // UUID matches.
Entry entry;
- entry.set_name(name);
+ entry.set_name(variable.entry.name());
entry.set_uuid(UUID::random().toBytes());
- entry.set_value(value.get());
+ entry.set_value(variable.entry.value());
- return Variable<T>(entry, t);
+ return storage->set(entry, uuid)
+ .then(lambda::bind(&State::_store, entry, lambda::_1));
}
-template <typename Serializer>
-template <typename T>
-process::Future<Option<Variable<T> > > State<Serializer>::_set(
+inline process::Future<Option<Variable > > State::_store(
const Entry& entry,
- const T& t,
const bool& b) // TODO(benh): Remove 'const &' after fixing libprocess.
{
if (b) {
- return Option<Variable<T> >::some(Variable<T>(entry, t));
+ return Option<Variable>::some(Variable(entry));
}
return None();
}
-template <typename Serializer>
-template <typename T>
-process::Future<Variable<T> > State<Serializer>::get(const std::string& name)
+inline process::Future<bool> State::expunge(const Variable& variable)
{
- return fetch(name)
- .then(std::tr1::bind(&State<Serializer>::template _get<T>,
- name,
- std::tr1::placeholders::_1));
+ return storage->expunge(variable.entry);
}
-template <typename Serializer>
-template <typename T>
-process::Future<Option<Variable<T> > > State<Serializer>::set(
- const Variable<T>& variable)
+inline process::Future<std::vector<std::string> > State::names()
{
- Try<std::string> value = Serializer::template serialize<T>(variable.t);
-
- if (value.isError()) {
- return process::Future<Option<Variable<T> > >::failed(value.error());
- }
-
- // Note that we try and swap an entry even if the value didn't change!
- UUID uuid = UUID::fromBytes(variable.entry.uuid());
-
- // Create a new entry that should be replace the existing entry
- // provided the UUID matches.
- Entry entry;
- entry.set_name(variable.entry.name());
- entry.set_uuid(UUID::random().toBytes());
- entry.set_value(value.get());
-
- std::tr1::function<
- process::Future<Option<Variable<T> > >(const bool&)> _set =
- std::tr1::bind(&State<Serializer>::template _set<T>,
- entry,
- variable.t,
- std::tr1::placeholders::_1);
-
- return swap(entry, uuid).then(_set);
+ return storage->names();
}
-
-
} // namespace state {
} // namespace internal {
} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/state/storage.hpp
----------------------------------------------------------------------
diff --git a/src/state/storage.hpp b/src/state/storage.hpp
new file mode 100644
index 0000000..a137075
--- /dev/null
+++ b/src/state/storage.hpp
@@ -0,0 +1,60 @@
+/**
+ * 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.
+ */
+
+#ifndef __STATE_STORAGE_HPP__
+#define __STATE_STORAGE_HPP__
+
+#include <string>
+#include <vector>
+
+#include <process/future.hpp>
+
+#include <stout/option.hpp>
+#include <stout/uuid.hpp>
+
+#include "messages/state.hpp"
+
+namespace mesos {
+namespace internal {
+namespace state {
+
+class Storage
+{
+public:
+ Storage() {}
+ virtual ~Storage() {}
+
+ // Get and set state entries, factored out to allow Storage
+ // implementations to be agnostic of Variable. Note that set acts
+ // like a "test-and-set" by requiring the existing entry to have the
+ // specified UUID.
+ virtual process::Future<Option<Entry> > get(const std::string& name) = 0;
+ virtual process::Future<bool> set(const Entry& entry, const UUID& uuid) = 0;
+
+ // Returns true if successfully expunged the variable from the state.
+ virtual process::Future<bool> expunge(const Entry& entry) = 0;
+
+ // Returns the collection of variable names in the state.
+ virtual process::Future<std::vector<std::string> > names() = 0;
+};
+
+} // namespace state {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __STATE_STORAGE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/state/zookeeper.cpp
----------------------------------------------------------------------
diff --git a/src/state/zookeeper.cpp b/src/state/zookeeper.cpp
index 07339ff..1801fce 100644
--- a/src/state/zookeeper.cpp
+++ b/src/state/zookeeper.cpp
@@ -1,5 +1,7 @@
#include <google/protobuf/message.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h> // For ArrayInputStream.
+
#include <queue>
#include <string>
#include <vector>
@@ -21,7 +23,7 @@
#include "messages/state.hpp"
-#include "state/state.hpp"
+#include "state/storage.hpp"
#include "state/zookeeper.hpp"
#include "zookeeper/authentication.hpp"
@@ -53,7 +55,7 @@ void fail(queue<T*>* queue, const string& message)
}
-ZooKeeperStateProcess::ZooKeeperStateProcess(
+ZooKeeperStorageProcess::ZooKeeperStorageProcess(
const string& _servers,
const Duration& _timeout,
const string& _znode,
@@ -71,27 +73,27 @@ ZooKeeperStateProcess::ZooKeeperStateProcess(
{}
-ZooKeeperStateProcess::~ZooKeeperStateProcess()
+ZooKeeperStorageProcess::~ZooKeeperStorageProcess()
{
- fail(&pending.names, "No longer managing state");
- fail(&pending.fetches, "No longer managing state");
- fail(&pending.swaps, "No longer managing state");
+ fail(&pending.names, "No longer managing storage");
+ fail(&pending.gets, "No longer managing storage");
+ fail(&pending.sets, "No longer managing storage");
delete zk;
delete watcher;
}
-void ZooKeeperStateProcess::initialize()
+void ZooKeeperStorageProcess::initialize()
{
// Doing initialization here allows to avoid the race between
// instantiating the ZooKeeper instance and being spawned ourself.
- watcher = new ProcessWatcher<ZooKeeperStateProcess>(self());
+ watcher = new ProcessWatcher<ZooKeeperStorageProcess>(self());
zk = new ZooKeeper(servers, timeout, watcher);
}
-Future<vector<string> > ZooKeeperStateProcess::names()
+Future<vector<string> > ZooKeeperStorageProcess::names()
{
if (error.isSome()) {
return Future<vector<string> >::failed(error.get());
@@ -115,22 +117,22 @@ Future<vector<string> > ZooKeeperStateProcess::names()
}
-Future<Option<Entry> > ZooKeeperStateProcess::fetch(const string& name)
+Future<Option<Entry> > ZooKeeperStorageProcess::get(const string& name)
{
if (error.isSome()) {
return Future<Option<Entry> >::failed(error.get());
} else if (state != CONNECTED) {
- Fetch* fetch = new Fetch(name);
- pending.fetches.push(fetch);
- return fetch->promise.future();
+ Get* get = new Get(name);
+ pending.gets.push(get);
+ return get->promise.future();
}
- Result<Option<Entry> > result = doFetch(name);
+ Result<Option<Entry> > result = doGet(name);
if (result.isNone()) { // Try again later.
- Fetch* fetch = new Fetch(name);
- pending.fetches.push(fetch);
- return fetch->promise.future();
+ Get* get = new Get(name);
+ pending.gets.push(get);
+ return get->promise.future();
} else if (result.isError()) {
return Future<Option<Entry> >::failed(result.error());
}
@@ -139,22 +141,46 @@ Future<Option<Entry> > ZooKeeperStateProcess::fetch(const string& name)
}
-Future<bool> ZooKeeperStateProcess::swap(const Entry& entry, const UUID& uuid)
+Future<bool> ZooKeeperStorageProcess::set(const Entry& entry, const UUID& uuid)
+{
+ if (error.isSome()) {
+ return Future<bool>::failed(error.get());
+ } else if (state != CONNECTED) {
+ Set* set = new Set(entry, uuid);
+ pending.sets.push(set);
+ return set->promise.future();
+ }
+
+ Result<bool> result = doSet(entry, uuid);
+
+ if (result.isNone()) { // Try again later.
+ Set* set = new Set(entry, uuid);
+ pending.sets.push(set);
+ return set->promise.future();
+ } else if (result.isError()) {
+ return Future<bool>::failed(result.error());
+ }
+
+ return result.get();
+}
+
+
+Future<bool> ZooKeeperStorageProcess::expunge(const Entry& entry)
{
if (error.isSome()) {
return Future<bool>::failed(error.get());
} else if (state != CONNECTED) {
- Swap* swap = new Swap(entry, uuid);
- pending.swaps.push(swap);
- return swap->promise.future();
+ Expunge* expunge = new Expunge(entry);
+ pending.expunges.push(expunge);
+ return expunge->promise.future();
}
- Result<bool> result = doSwap(entry, uuid);
+ Result<bool> result = doExpunge(entry);
if (result.isNone()) { // Try again later.
- Swap* swap = new Swap(entry, uuid);
- pending.swaps.push(swap);
- return swap->promise.future();
+ Expunge* expunge = new Expunge(entry);
+ pending.expunges.push(expunge);
+ return expunge->promise.future();
} else if (result.isError()) {
return Future<bool>::failed(result.error());
}
@@ -163,7 +189,7 @@ Future<bool> ZooKeeperStateProcess::swap(const Entry& entry, const UUID& uuid)
}
-void ZooKeeperStateProcess::connected(bool reconnect)
+void ZooKeeperStorageProcess::connected(bool reconnect)
{
if (!reconnect) {
// Authenticate if necessary (and we are connected for the first
@@ -196,43 +222,43 @@ void ZooKeeperStateProcess::connected(bool reconnect)
delete names;
}
- while (!pending.fetches.empty()) {
- Fetch* fetch = pending.fetches.front();
- Result<Option<Entry> > result = doFetch(fetch->name);
+ while (!pending.gets.empty()) {
+ Get* get = pending.gets.front();
+ Result<Option<Entry> > result = doGet(get->name);
if (result.isNone()) {
return; // Try again later.
} else if (result.isError()) {
- fetch->promise.fail(result.error());
+ get->promise.fail(result.error());
} else {
- fetch->promise.set(result.get());
+ get->promise.set(result.get());
}
- pending.fetches.pop();
- delete fetch;
+ pending.gets.pop();
+ delete get;
}
- while (!pending.swaps.empty()) {
- Swap* swap = pending.swaps.front();
- Result<bool> result = doSwap(swap->entry, swap->uuid);
+ while (!pending.sets.empty()) {
+ Set* set = pending.sets.front();
+ Result<bool> result = doSet(set->entry, set->uuid);
if (result.isNone()) {
return; // Try again later.
} else if (result.isError()) {
- swap->promise.fail(result.error());
+ set->promise.fail(result.error());
} else {
- swap->promise.set(result.get());
+ set->promise.set(result.get());
}
- pending.swaps.pop();
- delete swap;
+ pending.sets.pop();
+ delete set;
}
}
-void ZooKeeperStateProcess::reconnecting()
+void ZooKeeperStorageProcess::reconnecting()
{
state = CONNECTING;
}
-void ZooKeeperStateProcess::expired()
+void ZooKeeperStorageProcess::expired()
{
state = DISCONNECTED;
@@ -243,25 +269,25 @@ void ZooKeeperStateProcess::expired()
}
-void ZooKeeperStateProcess::updated(const string& path)
+void ZooKeeperStorageProcess::updated(const string& path)
{
LOG(FATAL) << "Unexpected ZooKeeper event";
}
-void ZooKeeperStateProcess::created(const string& path)
+void ZooKeeperStorageProcess::created(const string& path)
{
LOG(FATAL) << "Unexpected ZooKeeper event";
}
-void ZooKeeperStateProcess::deleted(const string& path)
+void ZooKeeperStorageProcess::deleted(const string& path)
{
LOG(FATAL) << "Unexpected ZooKeeper event";
}
-Result<vector<string> > ZooKeeperStateProcess::doNames()
+Result<vector<string> > ZooKeeperStorageProcess::doNames()
{
// Get all children to determine current memberships.
vector<string> results;
@@ -284,7 +310,7 @@ Result<vector<string> > ZooKeeperStateProcess::doNames()
}
-Result<Option<Entry> > ZooKeeperStateProcess::doFetch(const string& name)
+Result<Option<Entry> > ZooKeeperStorageProcess::doGet(const string& name)
{
CHECK(error.isNone()) << ": " << error.get();
CHECK(state == CONNECTED);
@@ -317,7 +343,7 @@ Result<Option<Entry> > ZooKeeperStateProcess::doFetch(const string& name)
}
-Result<bool> ZooKeeperStateProcess::doSwap(const Entry& entry, const UUID& uuid)
+Result<bool> ZooKeeperStorageProcess::doSet(const Entry& entry, const UUID& uuid)
{
CHECK(error.isNone()) << ": " << error.get();
CHECK(state == CONNECTED);
@@ -397,7 +423,7 @@ Result<bool> ZooKeeperStateProcess::doSwap(const Entry& entry, const UUID& uuid)
return false;
}
- // Okay, do a set, we get atomic swap by requiring 'stat.version'.
+ // Okay, do the set, we get atomicity by requiring 'stat.version'.
code = zk->set(znode + "/" + entry.name(), data, stat.version);
if (code == ZBADVERSION) {
@@ -414,6 +440,57 @@ Result<bool> ZooKeeperStateProcess::doSwap(const Entry& entry, const UUID& uuid)
return true;
}
+
+Result<bool> ZooKeeperStorageProcess::doExpunge(const Entry& entry)
+{
+ CHECK(error.isNone()) << ": " << error.get();
+ CHECK(state == CONNECTED);
+
+ string result;
+ Stat stat;
+
+ int code = zk->get(znode + "/" + entry.name(), false, &result, &stat);
+
+ if (code == ZNONODE) {
+ return false;
+ } else if (code == ZINVALIDSTATE || (code != ZOK && zk->retryable(code))) {
+ CHECK(zk->getState() != ZOO_AUTH_FAILED_STATE);
+ return None(); // Try again later.
+ } else if (code != ZOK) {
+ return Error(
+ "Failed to get '" + znode + "/" + entry.name() +
+ "' in ZooKeeper: " + zk->message(code));
+ }
+
+ google::protobuf::io::ArrayInputStream stream(result.data(), result.size());
+
+ Entry current;
+
+ if (!current.ParseFromZeroCopyStream(&stream)) {
+ return Error("Failed to deserialize Entry");
+ }
+
+ if (UUID::fromBytes(current.uuid()) != UUID::fromBytes(entry.uuid())) {
+ return false;
+ }
+
+ // Okay, do the remove, we get atomicity by requiring 'stat.version'.
+ code = zk->remove(znode + "/" + entry.name(), stat.version);
+
+ if (code == ZBADVERSION) {
+ return false;
+ } else if (code == ZINVALIDSTATE || (code != ZOK && zk->retryable(code))) {
+ CHECK(zk->getState() != ZOO_AUTH_FAILED_STATE);
+ return None(); // Try again later.
+ } else if (code != ZOK) {
+ return Error(
+ "Failed to remove '" + znode + "/" + entry.name() +
+ "' in ZooKeeper: " + zk->message(code));
+ }
+
+ return true;
+}
+
} // namespace state {
} // namespace internal {
} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/state/zookeeper.hpp
----------------------------------------------------------------------
diff --git a/src/state/zookeeper.hpp b/src/state/zookeeper.hpp
index 1e332ed..90b6607 100644
--- a/src/state/zookeeper.hpp
+++ b/src/state/zookeeper.hpp
@@ -17,8 +17,7 @@
#include "messages/state.hpp"
-#include "state/serializer.hpp"
-#include "state/state.hpp"
+#include "state/storage.hpp"
#include "zookeeper/authentication.hpp"
#include "zookeeper/watcher.hpp"
@@ -29,51 +28,49 @@ namespace internal {
namespace state {
// Forward declarations.
-class ZooKeeperStateProcess;
+class ZooKeeperStorageProcess;
-template <typename Serializer = StringSerializer>
-class ZooKeeperState : public State<Serializer>
+class ZooKeeperStorage : public Storage
{
public:
// TODO(benh): Just take a zookeeper::URL.
- ZooKeeperState(
+ ZooKeeperStorage(
const std::string& servers,
const Duration& timeout,
const std::string& znode,
const Option<zookeeper::Authentication>& auth =
Option<zookeeper::Authentication>());
- virtual ~ZooKeeperState();
+ virtual ~ZooKeeperStorage();
- // State implementation.
+ // Storage implementation.
+ virtual process::Future<Option<Entry> > get(const std::string& name);
+ virtual process::Future<bool> set(const Entry& entry, const UUID& uuid);
+ virtual process::Future<bool> expunge(const Entry& entry);
virtual process::Future<std::vector<std::string> > names();
-protected:
- // More State implementation.
- virtual process::Future<Option<Entry> > fetch(const std::string& name);
- virtual process::Future<bool> swap(const Entry& entry, const UUID& uuid);
-
private:
- ZooKeeperStateProcess* process;
+ ZooKeeperStorageProcess* process;
};
-class ZooKeeperStateProcess : public process::Process<ZooKeeperStateProcess>
+class ZooKeeperStorageProcess : public process::Process<ZooKeeperStorageProcess>
{
public:
- ZooKeeperStateProcess(
+ ZooKeeperStorageProcess(
const std::string& servers,
const Duration& timeout,
const std::string& znode,
const Option<zookeeper::Authentication>& auth);
- virtual ~ZooKeeperStateProcess();
+ virtual ~ZooKeeperStorageProcess();
virtual void initialize();
- // State implementation.
+ // Storage implementation.
+ process::Future<Option<Entry> > get(const std::string& name);
+ process::Future<bool> set(const Entry& entry, const UUID& uuid);
+ virtual process::Future<bool> expunge(const Entry& entry);
process::Future<std::vector<std::string> > names();
- process::Future<Option<Entry> > fetch(const std::string& name);
- process::Future<bool> swap(const Entry& entry, const UUID& uuid);
// ZooKeeper events.
void connected(bool reconnect);
@@ -86,8 +83,9 @@ public:
private:
// Helpers for getting the names, fetching, and swapping.
Result<std::vector<std::string> > doNames();
- Result<Option<Entry> > doFetch(const std::string& name);
- Result<bool> doSwap(const Entry& entry, const UUID& uuid);
+ Result<Option<Entry> > doGet(const std::string& name);
+ Result<bool> doSet(const Entry& entry, const UUID& uuid);
+ Result<bool> doExpunge(const Entry& entry);
const std::string servers;
const Duration timeout;
@@ -111,49 +109,56 @@ private:
process::Promise<std::vector<std::string> > promise;
};
- struct Fetch
+ struct Get
{
- Fetch(const std::string& _name)
+ Get(const std::string& _name)
: name(_name) {}
std::string name;
process::Promise<Option<Entry> > promise;
};
- struct Swap
+ struct Set
{
- Swap(const Entry& _entry, const UUID& _uuid)
+ Set(const Entry& _entry, const UUID& _uuid)
: entry(_entry), uuid(_uuid) {}
Entry entry;
UUID uuid;
process::Promise<bool> promise;
};
+ struct Expunge
+ {
+ Expunge(const Entry& _entry)
+ : entry(_entry) {}
+ Entry entry;
+ process::Promise<bool> promise;
+ };
+
// TODO(benh): Make pending a single queue of "operations" that can
// be "invoked" (C++11 lambdas would help).
struct {
std::queue<Names*> names;
- std::queue<Fetch*> fetches;
- std::queue<Swap*> swaps;
+ std::queue<Get*> gets;
+ std::queue<Set*> sets;
+ std::queue<Expunge*> expunges;
} pending;
Option<std::string> error;
};
-template <typename Serializer>
-ZooKeeperState<Serializer>::ZooKeeperState(
+inline ZooKeeperStorage::ZooKeeperStorage(
const std::string& servers,
const Duration& timeout,
const std::string& znode,
const Option<zookeeper::Authentication>& auth)
{
- process = new ZooKeeperStateProcess(servers, timeout, znode, auth);
+ process = new ZooKeeperStorageProcess(servers, timeout, znode, auth);
process::spawn(process);
}
-template <typename Serializer>
-ZooKeeperState<Serializer>::~ZooKeeperState()
+inline ZooKeeperStorage::~ZooKeeperStorage()
{
process::terminate(process);
process::wait(process);
@@ -161,27 +166,31 @@ ZooKeeperState<Serializer>::~ZooKeeperState()
}
-template <typename Serializer>
-process::Future<std::vector<std::string> > ZooKeeperState<Serializer>::names()
+inline process::Future<Option<Entry> > ZooKeeperStorage::get(
+ const std::string& name)
{
- return process::dispatch(process, &ZooKeeperStateProcess::names);
+ return process::dispatch(process, &ZooKeeperStorageProcess::get, name);
}
-template <typename Serializer>
-process::Future<Option<Entry> > ZooKeeperState<Serializer>::fetch(
- const std::string& name)
+inline process::Future<bool> ZooKeeperStorage::set(
+ const Entry& entry,
+ const UUID& uuid)
{
- return process::dispatch(process, &ZooKeeperStateProcess::fetch, name);
+ return process::dispatch(process, &ZooKeeperStorageProcess::set, entry, uuid);
}
-template <typename Serializer>
-process::Future<bool> ZooKeeperState<Serializer>::swap(
- const Entry& entry,
- const UUID& uuid)
+inline process::Future<bool> ZooKeeperStorage::expunge(
+ const Entry& entry)
+{
+ return process::dispatch(process, &ZooKeeperStorageProcess::expunge, entry);
+}
+
+
+inline process::Future<std::vector<std::string> > ZooKeeperStorage::names()
{
- return process::dispatch(process, &ZooKeeperStateProcess::swap, entry, uuid);
+ return process::dispatch(process, &ZooKeeperStorageProcess::names);
}
} // namespace state {
[13/28] git commit: Cleaned up the output from running and
automagically disabling the CgroupsNoHierarchyTest.
Posted by be...@apache.org.
Cleaned up the output from running and automagically disabling the
CgroupsNoHierarchyTest.
Review: https://reviews.apache.org/r/11274
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/7995751b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/7995751b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/7995751b
Branch: refs/heads/master
Commit: 7995751b66c7c09e31dcdc8b9444777718b4b2c4
Parents: 6b1b820
Author: Benjamin Hindman <be...@twitter.com>
Authored: Thu May 9 23:34:48 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 00:13:40 2013 -0700
----------------------------------------------------------------------
src/tests/cgroups_tests.cpp | 19 ++++++++-----------
src/tests/environment.cpp | 7 ++++---
2 files changed, 12 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/7995751b/src/tests/cgroups_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/cgroups_tests.cpp b/src/tests/cgroups_tests.cpp
index f062fe6..f6b23c4 100644
--- a/src/tests/cgroups_tests.cpp
+++ b/src/tests/cgroups_tests.cpp
@@ -84,17 +84,14 @@ public:
Try<std::set<std::string> > hierarchies = cgroups::hierarchies();
ASSERT_SOME(hierarchies);
- if (!hierarchies.get().empty()) {
- std::cerr
- << "-------------------------------------------------------------\n"
- << "We cannot run any cgroups tests that require mounting\n"
- << "hierarchies because you have the following hierarchies mounted:\n"
- << strings::trim(stringify(hierarchies.get()), " {},") << "\n"
- << "You can either unmount those hierarchies, or disable\n"
- << "this test case (i.e., --gtest_filter=-CgroupsNoHierarchyTest.*).\n"
- << "-------------------------------------------------------------"
- << std::endl;
- }
+ ASSERT_TRUE(hierarchies.get().empty())
+ << "-------------------------------------------------------------\n"
+ << "We cannot run any cgroups tests that require mounting\n"
+ << "hierarchies because you have the following hierarchies mounted:\n"
+ << strings::trim(stringify(hierarchies.get()), " {},") << "\n"
+ << "You can either unmount those hierarchies, or disable\n"
+ << "this test case (i.e., --gtest_filter=-CgroupsNoHierarchyTest.*).\n"
+ << "-------------------------------------------------------------";
}
};
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/7995751b/src/tests/environment.cpp
----------------------------------------------------------------------
diff --git a/src/tests/environment.cpp b/src/tests/environment.cpp
index 2a22acd..d8bb5fd 100644
--- a/src/tests/environment.cpp
+++ b/src/tests/environment.cpp
@@ -35,6 +35,8 @@
#include "linux/cgroups.hpp"
#endif
+#include "logging/logging.hpp"
+
#include "tests/environment.hpp"
#include "tests/flags.hpp"
@@ -83,15 +85,14 @@ static bool enable(const ::testing::TestInfo& test)
#ifdef __linux__
if (strings::contains(name, "NOHIERARCHY_")) {
Try<std::set<std::string> > hierarchies = cgroups::hierarchies();
- CHECK(hierarchies.isSome());
+ CHECK_SOME(hierarchies);
if (!hierarchies.get().empty()) {
std::cerr
<< "-------------------------------------------------------------\n"
<< "We cannot run any cgroups tests that require mounting\n"
<< "hierarchies because you have the following hierarchies mounted:\n"
<< strings::trim(stringify(hierarchies.get()), " {},") << "\n"
- << "You can either unmount those hierarchies, or disable\n"
- << "this test case (i.e., --gtest_filter=-CgroupsNoHierarchyTest.*).\n"
+ << "We'll disable the CgroupsNoHierarchyTest test fixture for now.\n"
<< "-------------------------------------------------------------"
<< std::endl;
[18/28] git commit: More spring cleaning,
this time in the slave recovery tets.
Posted by be...@apache.org.
More spring cleaning, this time in the slave recovery tets.
Review: https://reviews.apache.org/r/11279
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/a1e25cb7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/a1e25cb7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/a1e25cb7
Branch: refs/heads/master
Commit: a1e25cb703d1d6d206292d7aef926254f1377f34
Parents: bfa2255
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sat May 11 19:38:15 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 00:13:41 2013 -0700
----------------------------------------------------------------------
src/tests/slave_recovery_tests.cpp | 166 +++++++++++++++----------------
1 files changed, 82 insertions(+), 84 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/a1e25cb7/src/tests/slave_recovery_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/slave_recovery_tests.cpp b/src/tests/slave_recovery_tests.cpp
index 65f50ed..0315c52 100644
--- a/src/tests/slave_recovery_tests.cpp
+++ b/src/tests/slave_recovery_tests.cpp
@@ -155,12 +155,15 @@ TYPED_TEST(SlaveRecoveryTest, RecoverSlaveState)
Try<PID<Slave> > slave = this->StartSlave(&isolator, flags);
ASSERT_SOME(slave);
- // Message expectations.
- Future<Message> registerFramework =
- FUTURE_MESSAGE(Eq(RegisterFrameworkMessage().GetTypeName()), _, _);
-
- // Scheduler expectations.
MockScheduler sched;
+
+ // Enable checkpointing for the framework.
+ FrameworkInfo frameworkInfo;
+ frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
+ frameworkInfo.set_checkpoint(true);
+
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
+
FrameworkID frameworkId;
EXPECT_CALL(sched, registered(_, _, _))
.WillOnce(SaveArg<1>(&frameworkId));
@@ -170,18 +173,14 @@ TYPED_TEST(SlaveRecoveryTest, RecoverSlaveState)
.WillOnce(FutureArg<1>(&offers))
.WillRepeatedly(Return()); // Ignore subsequent offers.
- // Enable checkpointing for the framework.
- FrameworkInfo frameworkInfo;
- frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
- frameworkInfo.set_checkpoint(true);
-
- MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
+ Future<Message> registerFrameworkMessage =
+ FUTURE_MESSAGE(Eq(RegisterFrameworkMessage().GetTypeName()), _, _);
driver.start();
// Capture the framework pid.
- AWAIT_READY(registerFramework);
- UPID frameworkPid = registerFramework.get().from;
+ AWAIT_READY(registerFrameworkMessage);
+ UPID frameworkPid = registerFrameworkMessage.get().from;
AWAIT_READY(offers);
EXPECT_NE(0u, offers.get().size());
@@ -330,16 +329,8 @@ TYPED_TEST(SlaveRecoveryTest, RecoverStatusUpdateManager)
Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
ASSERT_SOME(slave);
- // Scheduler expectations.
MockScheduler sched;
- EXPECT_CALL(sched, registered(_, _, _));
-
- Future<vector<Offer> > offers;
- EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
-
// Enable checkpointing for the framework.
FrameworkInfo frameworkInfo;
frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
@@ -347,6 +338,13 @@ TYPED_TEST(SlaveRecoveryTest, RecoverStatusUpdateManager)
MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
+ EXPECT_CALL(sched, registered(_, _, _));
+
+ Future<vector<Offer> > offers;
+ EXPECT_CALL(sched, resourceOffers(_, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
driver.start();
AWAIT_READY(offers);
@@ -414,14 +412,7 @@ TYPED_TEST(SlaveRecoveryTest, ReconnectExecutor)
Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
ASSERT_SOME(slave);
- // Scheduler expectations.
MockScheduler sched;
- EXPECT_CALL(sched, registered(_, _, _));
-
- Future<vector<Offer> > offers;
- EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
// Enable checkpointing for the framework.
FrameworkInfo frameworkInfo;
@@ -430,6 +421,13 @@ TYPED_TEST(SlaveRecoveryTest, ReconnectExecutor)
MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
+ EXPECT_CALL(sched, registered(_, _, _));
+
+ Future<vector<Offer> > offers;
+ EXPECT_CALL(sched, resourceOffers(_, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
driver.start();
AWAIT_READY(offers);
@@ -506,14 +504,7 @@ TYPED_TEST(SlaveRecoveryTest, RecoverUnregisteredExecutor)
Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
ASSERT_SOME(slave);
- // Scheduler expectations.
MockScheduler sched;
- EXPECT_CALL(sched, registered(_, _, _));
-
- Future<vector<Offer> > offers;
- EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
// Enable checkpointing for the framework.
FrameworkInfo frameworkInfo;
@@ -522,6 +513,13 @@ TYPED_TEST(SlaveRecoveryTest, RecoverUnregisteredExecutor)
MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
+ EXPECT_CALL(sched, registered(_, _, _));
+
+ Future<vector<Offer> > offers;
+ EXPECT_CALL(sched, resourceOffers(_, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
driver.start();
AWAIT_READY(offers);
@@ -599,14 +597,7 @@ TYPED_TEST(SlaveRecoveryTest, RecoverTerminatedExecutor)
Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
ASSERT_SOME(slave);
- // Scheduler expectations.
MockScheduler sched;
- EXPECT_CALL(sched, registered(_, _, _));
-
- Future<vector<Offer> > offers;
- EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
// Enable checkpointing for the framework.
FrameworkInfo frameworkInfo;
@@ -615,6 +606,13 @@ TYPED_TEST(SlaveRecoveryTest, RecoverTerminatedExecutor)
MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
+ EXPECT_CALL(sched, registered(_, _, _));
+
+ Future<vector<Offer> > offers;
+ EXPECT_CALL(sched, resourceOffers(_, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
driver.start();
AWAIT_READY(offers);
@@ -698,14 +696,7 @@ TYPED_TEST(SlaveRecoveryTest, CleanupExecutor)
Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
ASSERT_SOME(slave);
- // Scheduler expectations.
MockScheduler sched;
- EXPECT_CALL(sched, registered(_, _, _));
-
- Future<vector<Offer> > offers;
- EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
// Enable checkpointing for the framework.
FrameworkInfo frameworkInfo;
@@ -714,6 +705,13 @@ TYPED_TEST(SlaveRecoveryTest, CleanupExecutor)
MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
+ EXPECT_CALL(sched, registered(_, _, _));
+
+ Future<vector<Offer> > offers;
+ EXPECT_CALL(sched, resourceOffers(_, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
driver.start();
AWAIT_READY(offers);
@@ -780,14 +778,7 @@ TYPED_TEST(SlaveRecoveryTest, RemoveNonCheckpointingFramework)
Try<PID<Slave> > slave = this->StartSlave(&isolator);
ASSERT_SOME(slave);
- // Scheduler expectations.
MockScheduler sched;
- EXPECT_CALL(sched, registered(_, _, _));
-
- Future<vector<Offer> > offers;
- EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
// Disable checkpointing for the framework.
FrameworkInfo frameworkInfo;
@@ -796,6 +787,13 @@ TYPED_TEST(SlaveRecoveryTest, RemoveNonCheckpointingFramework)
MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
+ EXPECT_CALL(sched, registered(_, _, _));
+
+ Future<vector<Offer> > offers;
+ EXPECT_CALL(sched, resourceOffers(_, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
driver.start();
AWAIT_READY(offers);
@@ -845,8 +843,15 @@ TYPED_TEST(SlaveRecoveryTest, NonCheckpointingFramework)
Try<PID<Slave> > slave = this->StartSlave(&isolator, flags);
ASSERT_SOME(slave);
- // Scheduler expectations.
MockScheduler sched;
+
+ // Disable checkpointing for the framework.
+ FrameworkInfo frameworkInfo;
+ frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
+ frameworkInfo.set_checkpoint(false);
+
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
+
FrameworkID frameworkId;
EXPECT_CALL(sched, registered(_, _, _))
.WillOnce(SaveArg<1>(&frameworkId));
@@ -856,13 +861,6 @@ TYPED_TEST(SlaveRecoveryTest, NonCheckpointingFramework)
.WillOnce(FutureArg<1>(&offers))
.WillRepeatedly(Return()); // Ignore subsequent offers.
- // Disable checkpointing for the framework.
- FrameworkInfo frameworkInfo;
- frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
- frameworkInfo.set_checkpoint(false);
-
- MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
-
driver.start();
AWAIT_READY(offers);
@@ -928,13 +926,7 @@ TYPED_TEST(SlaveRecoveryTest, KillTask)
Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
ASSERT_SOME(slave);
- // Scheduler expectations.
MockScheduler sched;
- EXPECT_CALL(sched, registered(_, _, _));
-
- Future<vector<Offer> > offers1;
- EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers1));
// Enable checkpointing for the framework.
FrameworkInfo frameworkInfo;
@@ -943,6 +935,12 @@ TYPED_TEST(SlaveRecoveryTest, KillTask)
MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
+ EXPECT_CALL(sched, registered(_, _, _));
+
+ Future<vector<Offer> > offers1;
+ EXPECT_CALL(sched, resourceOffers(_, _))
+ .WillOnce(FutureArg<1>(&offers1));
+
driver.start();
AWAIT_READY(offers1);
@@ -1039,14 +1037,7 @@ TYPED_TEST(SlaveRecoveryTest, GCExecutor)
Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
ASSERT_SOME(slave);
- // Scheduler expectations.
MockScheduler sched;
- EXPECT_CALL(sched, registered(_, _, _));
-
- Future<vector<Offer> > offers;
- EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
// Enable checkpointing for the framework.
FrameworkInfo frameworkInfo;
@@ -1055,6 +1046,13 @@ TYPED_TEST(SlaveRecoveryTest, GCExecutor)
MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
+ EXPECT_CALL(sched, registered(_, _, _));
+
+ Future<vector<Offer> > offers;
+ EXPECT_CALL(sched, resourceOffers(_, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
driver.start();
AWAIT_READY(offers);
@@ -1161,14 +1159,7 @@ TYPED_TEST(SlaveRecoveryTest, ShutdownSlave)
Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
ASSERT_SOME(slave);
- // Scheduler expectations.
MockScheduler sched;
- EXPECT_CALL(sched, registered(_, _, _));
-
- Future<vector<Offer> > offers1;
- EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers1))
- .WillOnce(Return()); // Ignore the offer when slave is shutting down.
// Enable checkpointing for the framework.
FrameworkInfo frameworkInfo;
@@ -1177,6 +1168,13 @@ TYPED_TEST(SlaveRecoveryTest, ShutdownSlave)
MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
+ EXPECT_CALL(sched, registered(_, _, _));
+
+ Future<vector<Offer> > offers1;
+ EXPECT_CALL(sched, resourceOffers(_, _))
+ .WillOnce(FutureArg<1>(&offers1))
+ .WillOnce(Return()); // Ignore the offer when slave is shutting down.
+
driver.start();
AWAIT_READY(offers1);
[26/28] git commit: Fixed bug where we didn't stop all
MesosExecutorDrivers when using the TestingIsolator (potentially causing a
segfault when a driver attempts to use a MockExecutor that had been
deallocated).
Posted by be...@apache.org.
Fixed bug where we didn't stop all MesosExecutorDrivers when using the
TestingIsolator (potentially causing a segfault when a driver attempts
to use a MockExecutor that had been deallocated).
Review: https://reviews.apache.org/r/11352
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/bc9cb875
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/bc9cb875
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/bc9cb875
Branch: refs/heads/master
Commit: bc9cb875536dd2ee349dfc8b917322d77a865a04
Parents: 6958e6d
Author: Benjamin Hindman <be...@twitter.com>
Authored: Tue May 21 23:35:11 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 09:28:38 2013 -0700
----------------------------------------------------------------------
src/tests/allocator_tests.cpp | 38 ++-------
src/tests/allocator_zookeeper_tests.cpp | 116 +++++++++---------------
src/tests/fault_tolerance_tests.cpp | 51 ++++-------
src/tests/gc_tests.cpp | 20 ++---
src/tests/isolator.hpp | 10 ++-
src/tests/master_tests.cpp | 42 ++-------
src/tests/resource_offers_tests.cpp | 5 +-
src/tests/status_update_manager_tests.cpp | 21 +----
8 files changed, 105 insertions(+), 198 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc9cb875/src/tests/allocator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/allocator_tests.cpp b/src/tests/allocator_tests.cpp
index 8b868bc..52e2b03 100644
--- a/src/tests/allocator_tests.cpp
+++ b/src/tests/allocator_tests.cpp
@@ -666,15 +666,12 @@ TYPED_TEST(AllocatorTest, SchedulerFailover)
EXPECT_CALL(this->allocator, frameworkRemoved(_))
.Times(AtMost(1));
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver2.stop();
driver2.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
@@ -796,25 +793,20 @@ TYPED_TEST(AllocatorTest, FrameworkExited)
EXPECT_CALL(sched2, resourceOffers(_, OfferEq(2, 768)))
.WillOnce(FutureSatisfy(&resourceOffers));
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver1.stop();
driver1.join();
AWAIT_READY(resourceOffers);
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver2.stop();
driver2.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
@@ -881,9 +873,8 @@ TYPED_TEST(AllocatorTest, SlaveLost)
.WillOnce(DoAll(InvokeSlaveRemoved(&this->allocator),
FutureSatisfy(&slaveRemoved)));
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
EXPECT_CALL(sched, slaveLost(_, _));
@@ -891,10 +882,6 @@ TYPED_TEST(AllocatorTest, SlaveLost)
AWAIT_READY(slaveRemoved);
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
- MockExecutor exec2(DEFAULT_EXECUTOR_ID);
-
slave::Flags flags2 = this->CreateSlaveFlags();
flags2.resources = Option<string>("cpus:3;mem:256");
@@ -907,7 +894,7 @@ TYPED_TEST(AllocatorTest, SlaveLost)
EXPECT_CALL(sched, resourceOffers(_, OfferEq(3, 256)))
.WillOnce(FutureSatisfy(&resourceOffers));
- Try<PID<Slave> > slave2 = this->StartSlave(&exec2, flags2);
+ Try<PID<Slave> > slave2 = this->StartSlave(flags2);
ASSERT_SOME(slave2);
AWAIT_READY(resourceOffers);
@@ -922,14 +909,9 @@ TYPED_TEST(AllocatorTest, SlaveLost)
EXPECT_CALL(this->allocator, frameworkRemoved(_))
.Times(AtMost(1));
- EXPECT_CALL(exec2, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
-
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
@@ -1025,15 +1007,12 @@ TYPED_TEST(AllocatorTest, SlaveAdded)
EXPECT_CALL(this->allocator, frameworkRemoved(_))
.Times(AtMost(1));
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(2));
@@ -1135,15 +1114,12 @@ TYPED_TEST(AllocatorTest, TaskFinished)
EXPECT_CALL(this->allocator, frameworkRemoved(_))
.Times(AtMost(1));
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc9cb875/src/tests/allocator_zookeeper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/allocator_zookeeper_tests.cpp b/src/tests/allocator_zookeeper_tests.cpp
index 31f4dc6..1034d72 100644
--- a/src/tests/allocator_zookeeper_tests.cpp
+++ b/src/tests/allocator_zookeeper_tests.cpp
@@ -121,47 +121,28 @@ TYPED_TEST(AllocatorZooKeeperTest, FrameworkReregistersFirst)
MesosSchedulerDriver driver(
&sched, DEFAULT_FRAMEWORK_INFO, stringify(this->url.get()));
- Future<Nothing> registered;
- EXPECT_CALL(sched, registered(&driver, _, _))
- .WillOnce(FutureSatisfy(®istered));
+ EXPECT_CALL(sched, registered(&driver, _, _));
- Future<vector<Offer> > resourceOffers1;
- EXPECT_CALL(sched, resourceOffers(&driver, _))
- .WillOnce(DoAll(LaunchTasks(1, 1, 500),
- FutureArg<1>(&resourceOffers1)))
+ // The framework should be offered all of the resources on the slave
+ // since it is the only framework running.
+ EXPECT_CALL(sched, resourceOffers(&driver, OfferEq(2, 1024)))
+ .WillOnce(LaunchTasks(1, 1, 500))
.WillRepeatedly(DeclineOffers());
- Future<TaskStatus> statusUpdate;
- EXPECT_CALL(sched, statusUpdate(&driver, _))
- .WillOnce(FutureArg<1>(&statusUpdate));
-
- EXPECT_CALL(sched, disconnected(_))
- .WillRepeatedly(DoDefault());
-
EXPECT_CALL(exec, registered(_, _, _, _));
EXPECT_CALL(exec, launchTask(_, _))
.WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));
- EXPECT_CALL(exec, disconnected(_))
- .WillRepeatedly(DoDefault());
-
- EXPECT_CALL(exec, shutdown(_))
- .WillRepeatedly(DoDefault());
+ Future<TaskStatus> status;
+ EXPECT_CALL(sched, statusUpdate(&driver, _))
+ .WillOnce(FutureArg<1>(&status));
driver.start();
- AWAIT_READY(registered);
+ AWAIT_READY(status);
- AWAIT_READY(resourceOffers1);
-
- // The framework will be offered all of the resources on the slave,
- // since it is the only framework running.
- EXPECT_THAT(resourceOffers1.get(), OfferEq(2, 1024));
-
- AWAIT_READY(statusUpdate);
-
- EXPECT_EQ(TASK_RUNNING, statusUpdate.get().state());
+ EXPECT_EQ(TASK_RUNNING, status.get().state());
// Stop the failing master from telling the slave to shut down when
// it is killed.
@@ -172,6 +153,16 @@ TYPED_TEST(AllocatorZooKeeperTest, FrameworkReregistersFirst)
// framework has reregistered.
DROP_PROTOBUFS(ReregisterSlaveMessage(), _, _);
+ // Shutting down the masters will cause the scheduler to get
+ // disconnected.
+ EXPECT_CALL(sched, disconnected(_));
+
+ // Shutting down the masters will also cause the slave to shutdown
+ // frameworks that are not checkpointing, thus causing the executor
+ // to get shutdown.
+ EXPECT_CALL(exec, shutdown(_))
+ .Times(AtMost(1));
+
this->ShutdownMasters();
AWAIT_READY(shutdownMessage);
@@ -213,20 +204,15 @@ TYPED_TEST(AllocatorZooKeeperTest, FrameworkReregistersFirst)
EXPECT_CALL(allocator2, resourcesRecovered(_, _, _))
.WillRepeatedly(DoDefault());
- EXPECT_CALL(allocator2, frameworkDeactivated(_));
+ EXPECT_CALL(allocator2, frameworkDeactivated(_))
+ .Times(AtMost(1));
- Future<Nothing> frameworkRemoved;
EXPECT_CALL(allocator2, frameworkRemoved(_))
- .WillOnce(FutureSatisfy(&frameworkRemoved));
-
- EXPECT_CALL(exec, shutdown(_))
.Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(frameworkRemoved);
-
EXPECT_CALL(allocator2, slaveRemoved(_))
.Times(AtMost(1));
@@ -257,47 +243,28 @@ TYPED_TEST(AllocatorZooKeeperTest, SlaveReregistersFirst)
MesosSchedulerDriver driver(
&sched, DEFAULT_FRAMEWORK_INFO, stringify(this->url.get()));
- Future<Nothing> registered;
- EXPECT_CALL(sched, registered(&driver, _, _))
- .WillOnce(FutureSatisfy(®istered));
+ EXPECT_CALL(sched, registered(&driver, _, _));
- Future<vector<Offer> > resourceOffers1;
- EXPECT_CALL(sched, resourceOffers(&driver, _))
- .WillOnce(DoAll(LaunchTasks(1, 1, 500),
- FutureArg<1>(&resourceOffers1)))
+ // The framework should be offered all of the resources on the slave
+ // since it is the only framework running.
+ EXPECT_CALL(sched, resourceOffers(&driver, OfferEq(2, 1024)))
+ .WillOnce(LaunchTasks(1, 1, 500))
.WillRepeatedly(DeclineOffers());
- Future<TaskStatus> statusUpdate;
- EXPECT_CALL(sched, statusUpdate(&driver, _))
- .WillOnce(FutureArg<1>(&statusUpdate));
-
- EXPECT_CALL(sched, disconnected(_))
- .WillRepeatedly(DoDefault());
-
EXPECT_CALL(exec, registered(_, _, _, _));
EXPECT_CALL(exec, launchTask(_, _))
.WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));
- EXPECT_CALL(exec, disconnected(_))
- .WillRepeatedly(DoDefault());
-
- EXPECT_CALL(exec, shutdown(_))
- .WillRepeatedly(DoDefault());
+ Future<TaskStatus> status;
+ EXPECT_CALL(sched, statusUpdate(&driver, _))
+ .WillOnce(FutureArg<1>(&status));
driver.start();
- AWAIT_READY(registered);
+ AWAIT_READY(status);
- AWAIT_READY(resourceOffers1);
-
- // The framework will be offered all of the resources on the slave,
- // since it is the only framework running.
- EXPECT_THAT(resourceOffers1.get(), OfferEq(2, 1024));
-
- AWAIT_READY(statusUpdate);
-
- EXPECT_EQ(TASK_RUNNING, statusUpdate.get().state());
+ EXPECT_EQ(TASK_RUNNING, status.get().state());
// Stop the failing master from telling the slave to shut down when
// it is killed.
@@ -308,6 +275,16 @@ TYPED_TEST(AllocatorZooKeeperTest, SlaveReregistersFirst)
// slave has reregistered.
DROP_PROTOBUFS(ReregisterFrameworkMessage(), _, _);
+ // Shutting down the masters will cause the scheduler to get
+ // disconnected.
+ EXPECT_CALL(sched, disconnected(_));
+
+ // Shutting down the masters will also cause the slave to shutdown
+ // frameworks that are not checkpointing, thus causing the executor
+ // to get shutdown.
+ EXPECT_CALL(exec, shutdown(_))
+ .Times(AtMost(1));
+
this->ShutdownMasters();
AWAIT_READY(shutdownMessage);
@@ -349,20 +326,15 @@ TYPED_TEST(AllocatorZooKeeperTest, SlaveReregistersFirst)
EXPECT_CALL(allocator2, resourcesRecovered(_, _, _))
.WillRepeatedly(DoDefault());
- EXPECT_CALL(allocator2, frameworkDeactivated(_));
+ EXPECT_CALL(allocator2, frameworkDeactivated(_))
+ .Times(AtMost(1));
- Future<Nothing> frameworkRemoved;
EXPECT_CALL(allocator2, frameworkRemoved(_))
- .WillOnce(FutureSatisfy(&frameworkRemoved));
-
- EXPECT_CALL(exec, shutdown(_))
.Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(frameworkRemoved);
-
EXPECT_CALL(allocator2, slaveRemoved(_))
.Times(AtMost(1));
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc9cb875/src/tests/fault_tolerance_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/fault_tolerance_tests.cpp b/src/tests/fault_tolerance_tests.cpp
index 287453d..c8fad7c 100644
--- a/src/tests/fault_tolerance_tests.cpp
+++ b/src/tests/fault_tolerance_tests.cpp
@@ -274,7 +274,7 @@ TEST_F(FaultToleranceTest, PartitionedSlaveReregistration)
// Drop the first shutdown message from the master (simulated
// partition), allow the second shutdown message to pass when
// the slave re-registers.
- Future<ShutdownMessage> shutdownSlave =
+ Future<ShutdownMessage> shutdownMessage =
DROP_PROTOBUF(ShutdownMessage(), _, slave.get());
Future<TaskStatus> lostStatus;
@@ -309,7 +309,7 @@ TEST_F(FaultToleranceTest, PartitionedSlaveReregistration)
EXPECT_EQ(TASK_LOST, lostStatus.get().state());
// Wait for the master to attempt to shut down the slave.
- AWAIT_READY(shutdownSlave);
+ AWAIT_READY(shutdownMessage);
// The master will notify the framework that the slave was lost.
AWAIT_READY(slaveLost);
@@ -319,11 +319,11 @@ TEST_F(FaultToleranceTest, PartitionedSlaveReregistration)
// normally occur during a network partition.
process::post(slave.get(), NoMasterDetectedMessage());
- Future<Nothing> shutdownExecutor;
+ Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdownExecutor));
+ .WillOnce(FutureSatisfy(&shutdown));
- shutdownSlave = FUTURE_PROTOBUF(ShutdownMessage(), _, slave.get());
+ shutdownMessage = FUTURE_PROTOBUF(ShutdownMessage(), _, slave.get());
// Have the slave re-register with the master.
NewMasterDetectedMessage newMasterDetectedMessage;
@@ -332,8 +332,8 @@ TEST_F(FaultToleranceTest, PartitionedSlaveReregistration)
// Upon re-registration, the master will shutdown the slave.
// The slave will then shut down the executor.
- AWAIT_READY(shutdownSlave);
- AWAIT_READY(shutdownExecutor);
+ AWAIT_READY(shutdownMessage);
+ AWAIT_READY(shutdown);
Clock::resume();
@@ -392,7 +392,7 @@ TEST_F(FaultToleranceTest, PartitionedSlaveStatusUpdates)
// Drop the first shutdown message from the master (simulated
// partition), allow the second shutdown message to pass when
// the slave sends an update.
- Future<ShutdownMessage> shutdownSlave =
+ Future<ShutdownMessage> shutdownMessage =
DROP_PROTOBUF(ShutdownMessage(), _, slave.get());
EXPECT_CALL(sched, offerRescinded(&driver, _))
@@ -422,12 +422,12 @@ TEST_F(FaultToleranceTest, PartitionedSlaveStatusUpdates)
Clock::settle();
// Wait for the master to attempt to shut down the slave.
- AWAIT_READY(shutdownSlave);
+ AWAIT_READY(shutdownMessage);
// The master will notify the framework that the slave was lost.
AWAIT_READY(slaveLost);
- shutdownSlave = FUTURE_PROTOBUF(ShutdownMessage(), _, slave.get());
+ shutdownMessage = FUTURE_PROTOBUF(ShutdownMessage(), _, slave.get());
// At this point, the slave still thinks it's registered, so we
// simulate a status update coming from the slave.
@@ -445,7 +445,7 @@ TEST_F(FaultToleranceTest, PartitionedSlaveStatusUpdates)
process::post(master.get(), statusUpdate);
// The master should shutdown the slave upon receiving the update.
- AWAIT_READY(shutdownSlave);
+ AWAIT_READY(shutdownMessage);
Clock::resume();
@@ -519,6 +519,7 @@ TEST_F(FaultToleranceTest, PartitionedSlaveExitedExecutor)
// Set up the expectations for launching the task.
EXPECT_CALL(exec, registered(_, _, _, _));
+
EXPECT_CALL(exec, launchTask(_, _))
.WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));
@@ -532,7 +533,7 @@ TEST_F(FaultToleranceTest, PartitionedSlaveExitedExecutor)
// Drop the first shutdown message from the master (simulated
// partition) and allow the second shutdown message to pass when
// triggered by the ExitedExecutorMessage.
- Future<ShutdownMessage> shutdownSlave =
+ Future<ShutdownMessage> shutdownMessage =
DROP_PROTOBUF(ShutdownMessage(), _, slave.get());
Future<TaskStatus> lostStatus;
@@ -567,12 +568,12 @@ TEST_F(FaultToleranceTest, PartitionedSlaveExitedExecutor)
EXPECT_EQ(TASK_LOST, lostStatus.get().state());
// Wait for the master to attempt to shut down the slave.
- AWAIT_READY(shutdownSlave);
+ AWAIT_READY(shutdownMessage);
// The master will notify the framework that the slave was lost.
AWAIT_READY(slaveLost);
- shutdownSlave = FUTURE_PROTOBUF(ShutdownMessage(), _, slave.get());
+ shutdownMessage = FUTURE_PROTOBUF(ShutdownMessage(), _, slave.get());
// Induce an ExitedExecutorMessage from the slave.
dispatch(isolator,
@@ -581,7 +582,7 @@ TEST_F(FaultToleranceTest, PartitionedSlaveExitedExecutor)
DEFAULT_EXECUTOR_INFO.executor_id());
// Upon receiving the message, the master will shutdown the slave.
- AWAIT_READY(shutdownSlave);
+ AWAIT_READY(shutdownMessage);
Clock::resume();
@@ -964,9 +965,8 @@ TEST_F(FaultToleranceTest, SchedulerFailoverStatusUpdate)
AWAIT_READY(statusUpdate);
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver1.stop();
driver2.stop();
@@ -974,8 +974,6 @@ TEST_F(FaultToleranceTest, SchedulerFailoverStatusUpdate)
driver1.join();
driver2.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
Shutdown();
Clock::resume();
@@ -1052,15 +1050,12 @@ TEST_F(FaultToleranceTest, ForwardStatusUpdateUnknownExecutor)
EXPECT_EQ(taskId, status.get().task_id());
EXPECT_EQ(TASK_RUNNING, status.get().state());
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
Shutdown();
}
@@ -1144,9 +1139,8 @@ TEST_F(FaultToleranceTest, SchedulerFailoverFrameworkMessage)
AWAIT_READY(frameworkMessage);
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver1.stop();
driver2.stop();
@@ -1154,8 +1148,6 @@ TEST_F(FaultToleranceTest, SchedulerFailoverFrameworkMessage)
driver1.join();
driver2.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
Shutdown();
}
@@ -1212,15 +1204,12 @@ TEST_F(FaultToleranceTest, SchedulerExit)
AWAIT_READY(status);
EXPECT_EQ(TASK_RUNNING, status.get().state());
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown);
-
Shutdown();
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc9cb875/src/tests/gc_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/gc_tests.cpp b/src/tests/gc_tests.cpp
index 43c3e5d..1745800 100644
--- a/src/tests/gc_tests.cpp
+++ b/src/tests/gc_tests.cpp
@@ -313,9 +313,8 @@ TEST_F(GarbageCollectorIntegrationTest, Restart)
Clock::pause();
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
EXPECT_CALL(sched, statusUpdate(_, _))
.Times(AtMost(1)); // Ignore TASK_LOST from killed executor.
@@ -326,8 +325,6 @@ TEST_F(GarbageCollectorIntegrationTest, Restart)
Stop(slave.get());
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
AWAIT_READY(slaveLost);
Future<Nothing> schedule =
@@ -727,21 +724,22 @@ TEST_F(GarbageCollectorIntegrationTest, Unschedule)
Future<Nothing> unscheduleFrameworkWork =
FUTURE_DISPATCH(_, &GarbageCollectorProcess::unschedule);
- // Launch the next run of the executor on the receipt of next offer.
- EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(LaunchTasks(1, cpus, mem));
+ // We ask the isolator to kill the exector below.
+ EXPECT_CALL(exec, shutdown(_))
+ .Times(AtMost(1));
EXPECT_CALL(sched, statusUpdate(_, _))
- .WillRepeatedly(Return()); // Ignore subsequent updates.
+ .Times(AtMost(2)); // Once for a TASK_LOST then once for TASK_RUNNING.
+
+ // We use the killed executor/tasks resources to run another task.
+ EXPECT_CALL(sched, resourceOffers(_, _))
+ .WillOnce(LaunchTasks(1, cpus, mem));
EXPECT_CALL(exec, registered(_, _, _, _));
EXPECT_CALL(exec, launchTask(_, _))
.WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));
- EXPECT_CALL(exec, shutdown(_))
- .WillRepeatedly(Return());
-
Clock::pause();
// Kill the first executor.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc9cb875/src/tests/isolator.hpp
----------------------------------------------------------------------
diff --git a/src/tests/isolator.hpp b/src/tests/isolator.hpp
index ebfc485..fe6b38d 100644
--- a/src/tests/isolator.hpp
+++ b/src/tests/isolator.hpp
@@ -67,7 +67,15 @@ public:
setup();
}
- virtual ~TestingIsolator() {}
+ virtual ~TestingIsolator()
+ {
+ foreachvalue (MesosExecutorDriver* driver, drivers) {
+ driver->stop();
+ driver->join();
+ delete driver;
+ }
+ drivers.clear();
+ }
virtual void initialize(
const slave::Flags& flags,
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc9cb875/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index 1d26eeb..5ac4d5f 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -134,15 +134,12 @@ TEST_F(MasterTest, TaskRunning)
AWAIT_READY(resourcesChanged);
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
@@ -209,15 +206,12 @@ TEST_F(MasterTest, ShutdownFrameworkWhileTaskRunning)
AWAIT_READY(resourcesChanged);
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
@@ -287,15 +281,12 @@ TEST_F(MasterTest, KillTask)
AWAIT_READY(status);
EXPECT_EQ(TASK_KILLED, status.get().state());
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // To ensure can deallocate MockExecutor.
-
Shutdown();
}
@@ -357,15 +348,12 @@ TEST_F(MasterTest, StatusUpdateAck)
// Ensure the slave gets a status update ACK.
AWAIT_READY(acknowledgement);
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
Shutdown();
}
@@ -465,6 +453,9 @@ TEST_F(MasterTest, RecoverResources)
EXPECT_CALL(sched, resourceOffers(&driver, _))
.WillOnce(FutureArg<1>(&offers));
+ EXPECT_CALL(exec, shutdown(_))
+ .Times(AtMost(1));
+
// Now kill the executor, scheduler should get an offer it's resources.
// TODO(benh): WTF? Why aren't we dispatching?
isolator.killExecutor(offer.framework_id(), executorInfo.executor_id());
@@ -482,11 +473,6 @@ TEST_F(MasterTest, RecoverResources)
driver.stop();
driver.join();
- // Terminating the slave might cause the mock executor to get a
- // shutdown since the executor driver "links" the slave.
- EXPECT_CALL(exec, shutdown(_))
- .Times(AtMost(1));
-
Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
@@ -562,15 +548,12 @@ TEST_F(MasterTest, FrameworkMessage)
AWAIT_READY(schedData);
EXPECT_EQ("world", schedData.get());
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
schedDriver.stop();
schedDriver.join();
- AWAIT_READY(shutdown); // To ensure can deallocate MockExecutor.
-
Shutdown();
}
@@ -673,20 +656,15 @@ TEST_F(MasterTest, MultipleExecutors)
AWAIT_READY(status2);
EXPECT_EQ(TASK_RUNNING, status2.get().state());
- Future<Nothing> shutdown1;
EXPECT_CALL(exec1, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown1));
+ .Times(AtMost(1));
- Future<Nothing> shutdown2;
EXPECT_CALL(exec2, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown2));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown1); // To ensure can deallocate MockExecutor.
- AWAIT_READY(shutdown2); // To ensure can deallocate MockExecutor.
-
Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc9cb875/src/tests/resource_offers_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/resource_offers_tests.cpp b/src/tests/resource_offers_tests.cpp
index e030d3d..b066403 100644
--- a/src/tests/resource_offers_tests.cpp
+++ b/src/tests/resource_offers_tests.cpp
@@ -573,14 +573,11 @@ TEST_F(MultipleExecutorsTest, TasksExecutorInfoDiffers)
" with same ExecutorID is not compatible)",
status.get().message());
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // To ensure can deallocate MockExecutor.
-
Shutdown();
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc9cb875/src/tests/status_update_manager_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/status_update_manager_tests.cpp b/src/tests/status_update_manager_tests.cpp
index 892a3f1..61ccfcc 100644
--- a/src/tests/status_update_manager_tests.cpp
+++ b/src/tests/status_update_manager_tests.cpp
@@ -64,6 +64,7 @@ using std::string;
using std::vector;
using testing::_;
+using testing::AtMost;
using testing::Return;
using testing::SaveArg;
@@ -176,15 +177,12 @@ TEST_F(StatusUpdateManagerTest, CheckpointStatusUpdate)
close(fd.get());
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillRepeatedly(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
Shutdown();
}
@@ -249,15 +247,12 @@ TEST_F(StatusUpdateManagerTest, RetryStatusUpdate)
Clock::resume();
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillRepeatedly(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
Shutdown();
}
@@ -369,15 +364,12 @@ TEST_F(StatusUpdateManagerTest, IgnoreDuplicateStatusUpdateAck)
Clock::resume();
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillRepeatedly(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
Shutdown();
}
@@ -464,14 +456,11 @@ TEST_F(StatusUpdateManagerTest, IgnoreUnexpectedStatusUpdateAck)
// it is 'false'.
AWAIT_READY(unexpectedAck);
- Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillRepeatedly(FutureSatisfy(&shutdown));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
-
Shutdown();
}
[06/28] git commit: Made tests flags inherit from logging.
Posted by be...@apache.org.
Made tests flags inherit from logging.
Review: https://reviews.apache.org/r/11267
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/6f6ca876
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/6f6ca876
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/6f6ca876
Branch: refs/heads/master
Commit: 6f6ca8767fe054fda167135711aeb0801ae50218
Parents: 0ebf393
Author: Benjamin Hindman <be...@twitter.com>
Authored: Fri Apr 26 17:17:42 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Fri May 24 22:05:05 2013 -0700
----------------------------------------------------------------------
src/Makefile.am | 1 +
src/tests/flags.cpp | 30 ++++++++++++++++++++++++++++++
src/tests/flags.hpp | 5 ++++-
src/tests/utils.cpp | 4 ----
src/tests/utils.hpp | 4 ----
5 files changed, 35 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6f6ca876/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 22346f3..5ed3423 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -769,6 +769,7 @@ check_PROGRAMS += mesos-tests
mesos_tests_SOURCES = tests/main.cpp tests/utils.cpp \
tests/environment.cpp \
+ tests/flags.cpp \
tests/master_tests.cpp tests/state_tests.cpp \
tests/paths_tests.cpp \
tests/reaper_tests.cpp \
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6f6ca876/src/tests/flags.cpp
----------------------------------------------------------------------
diff --git a/src/tests/flags.cpp b/src/tests/flags.cpp
new file mode 100644
index 0000000..98b780f
--- /dev/null
+++ b/src/tests/flags.cpp
@@ -0,0 +1,30 @@
+/**
+ * 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 "tests/flags.hpp"
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+// Storage for the flags.
+Flags flags;
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6f6ca876/src/tests/flags.hpp
----------------------------------------------------------------------
diff --git a/src/tests/flags.hpp b/src/tests/flags.hpp
index 9a4ebd6..6ba5eca 100644
--- a/src/tests/flags.hpp
+++ b/src/tests/flags.hpp
@@ -31,7 +31,7 @@ namespace mesos {
namespace internal {
namespace tests {
-class Flags : public virtual flags::FlagsBase
+class Flags : public logging::Flags
{
public:
Flags()
@@ -67,6 +67,9 @@ public:
std::string build_dir;
};
+// Global flags for running the tests.
+extern Flags flags;
+
} // namespace tests {
} // namespace internal {
} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6f6ca876/src/tests/utils.cpp
----------------------------------------------------------------------
diff --git a/src/tests/utils.cpp b/src/tests/utils.cpp
index 9d1d5ad..0bb1536 100644
--- a/src/tests/utils.cpp
+++ b/src/tests/utils.cpp
@@ -35,10 +35,6 @@ namespace mesos {
namespace internal {
namespace tests {
-// Storage for our flags.
-flags::Flags<logging::Flags, Flags> flags;
-
-
Try<string> mkdtemp()
{
const ::testing::TestInfo* const testInfo =
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6f6ca876/src/tests/utils.hpp
----------------------------------------------------------------------
diff --git a/src/tests/utils.hpp b/src/tests/utils.hpp
index ca3ecd7..2e47734 100644
--- a/src/tests/utils.hpp
+++ b/src/tests/utils.hpp
@@ -79,10 +79,6 @@ namespace mesos {
namespace internal {
namespace tests {
-// Flags used to run the tests.
-extern flags::Flags<logging::Flags, Flags> flags;
-
-
#ifdef __linux__
// Cgroups hierarchy used by the cgroups related tests.
const static std::string TEST_CGROUPS_HIERARCHY = "/tmp/mesos_test_cgroup";
[02/28] git commit: Removed unnecessary use of Option.
Posted by be...@apache.org.
Removed unnecessary use of Option.
Review: https://reviews.apache.org/r/11265
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/39ce99ef
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/39ce99ef
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/39ce99ef
Branch: refs/heads/master
Commit: 39ce99efa04f94b3cc514f445d69a53922bf1186
Parents: f5be413
Author: Benjamin Hindman <be...@twitter.com>
Authored: Thu Apr 25 18:32:37 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Fri May 24 22:05:05 2013 -0700
----------------------------------------------------------------------
src/tests/allocator_zookeeper_tests.cpp | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/39ce99ef/src/tests/allocator_zookeeper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/allocator_zookeeper_tests.cpp b/src/tests/allocator_zookeeper_tests.cpp
index 39b4627..bb7f84d 100644
--- a/src/tests/allocator_zookeeper_tests.cpp
+++ b/src/tests/allocator_zookeeper_tests.cpp
@@ -100,7 +100,7 @@ TYPED_TEST(AllocatorZooKeeperTest, FrameworkReregistersFirst)
Try<zookeeper::URL> url = zookeeper::URL::parse(zk);
ASSERT_SOME(url);
- Cluster cluster(Option<zookeeper::URL>(url.get()));
+ Cluster cluster(url.get());
Try<PID<Master> > master = cluster.masters.start(&this->allocator1);
ASSERT_SOME(master);
@@ -237,7 +237,7 @@ TYPED_TEST(AllocatorZooKeeperTest, SlaveReregistersFirst)
Try<zookeeper::URL> url = zookeeper::URL::parse(zk);
ASSERT_SOME(url);
- Cluster cluster(Option<zookeeper::URL>(url.get()));
+ Cluster cluster(url.get());
Try<PID<Master> > master = cluster.masters.start(&this->allocator1);
ASSERT_SOME(master);
[12/28] git commit: Refactored MesosTest/MesosClusterTest into a
generic fixture for launching in-memory Mesos clusters and updated all tests
appropriately.
Posted by be...@apache.org.
Refactored MesosTest/MesosClusterTest into a generic fixture for
launching in-memory Mesos clusters and updated all tests
appropriately.
Review: https://reviews.apache.org/r/11273
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/6b1b8208
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/6b1b8208
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/6b1b8208
Branch: refs/heads/master
Commit: 6b1b82085a6049944cb3342a415829fe3d0e9320
Parents: b553a07
Author: Benjamin Hindman <be...@twitter.com>
Authored: Wed Apr 24 22:06:48 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 00:13:35 2013 -0700
----------------------------------------------------------------------
src/Makefile.am | 2 +
src/master/hierarchical_allocator_process.hpp | 2 +-
src/tests/allocator_tests.cpp | 166 +++---
src/tests/allocator_zookeeper_tests.cpp | 151 +++--
src/tests/cgroups_tests.cpp | 5 +-
src/tests/cluster.hpp | 247 ++------
src/tests/configurator_tests.cpp | 12 +-
src/tests/exception_tests.cpp | 16 +-
src/tests/fault_tolerance_tests.cpp | 301 +++------
src/tests/files_tests.cpp | 2 +
src/tests/flags_tests.cpp | 3 +-
src/tests/gc_tests.cpp | 88 ++-
src/tests/group_tests.cpp | 3 +-
src/tests/isolator.hpp | 9 +
src/tests/isolator_tests.cpp | 62 +-
src/tests/log_tests.cpp | 5 +-
src/tests/logging_tests.cpp | 5 +-
src/tests/main.cpp | 3 +-
src/tests/master_detector_tests.cpp | 17 +-
src/tests/master_tests.cpp | 120 ++--
src/tests/mesos.cpp | 240 +++++++
src/tests/mesos.hpp | 676 ++++++++++++++++++
src/tests/monitor_tests.cpp | 7 +-
src/tests/paths_tests.cpp | 2 -
src/tests/protobuf_io_tests.cpp | 3 +-
src/tests/reaper_tests.cpp | 15 +-
src/tests/resource_offers_tests.cpp | 24 +-
src/tests/script.cpp | 4 +-
src/tests/slave_recovery_tests.cpp | 335 ++++++----
src/tests/state_tests.cpp | 3 +-
src/tests/status_update_manager_tests.cpp | 52 +-
src/tests/utils.cpp | 1 +
src/tests/utils.hpp | 727 +-------------------
src/tests/zookeeper.cpp | 2 +-
src/tests/zookeeper.hpp | 10 +-
src/tests/zookeeper_tests.cpp | 3 +-
src/zookeeper/authentication.hpp | 19 +-
src/zookeeper/url.hpp | 9 +
38 files changed, 1719 insertions(+), 1632 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index bc0c5c6..0f7794e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -233,6 +233,7 @@ libmesos_no_third_party_la_SOURCES += common/attributes.hpp \
tests/zookeeper.hpp tests/flags.hpp tests/utils.hpp \
tests/cluster.hpp \
tests/isolator.hpp \
+ tests/mesos.hpp \
tests/zookeeper_test_server.hpp zookeeper/authentication.hpp \
zookeeper/group.hpp zookeeper/watcher.hpp \
zookeeper/zookeeper.hpp zookeeper/url.hpp
@@ -780,6 +781,7 @@ check_PROGRAMS += mesos-tests
mesos_tests_SOURCES = tests/main.cpp tests/utils.cpp \
tests/environment.cpp \
tests/flags.cpp \
+ tests/mesos.cpp \
tests/master_tests.cpp tests/state_tests.cpp \
tests/paths_tests.cpp \
tests/reaper_tests.cpp \
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/master/hierarchical_allocator_process.hpp
----------------------------------------------------------------------
diff --git a/src/master/hierarchical_allocator_process.hpp b/src/master/hierarchical_allocator_process.hpp
index f4afb71..ebd97e4 100644
--- a/src/master/hierarchical_allocator_process.hpp
+++ b/src/master/hierarchical_allocator_process.hpp
@@ -30,6 +30,7 @@
#include "common/resources.hpp"
#include "master/allocator.hpp"
+#include "master/drf_sorter.hpp"
#include "master/master.hpp"
#include "master/sorter.hpp"
@@ -38,7 +39,6 @@ namespace internal {
namespace master {
// Forward declarations.
-class DRFSorter;
class Filter;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/allocator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/allocator_tests.cpp b/src/tests/allocator_tests.cpp
index 540c05a..5a0de33 100644
--- a/src/tests/allocator_tests.cpp
+++ b/src/tests/allocator_tests.cpp
@@ -34,8 +34,8 @@
#include "master/hierarchical_allocator_process.hpp"
#include "master/master.hpp"
-#include "tests/cluster.hpp"
-#include "tests/utils.hpp"
+#include "tests/isolator.hpp"
+#include "tests/mesos.hpp"
using namespace mesos;
using namespace mesos::internal;
@@ -66,7 +66,7 @@ using testing::Return;
using testing::SaveArg;
-class DRFAllocatorTest : public MesosClusterTest {};
+class DRFAllocatorTest : public MesosTest {};
// Checks that the DRF allocator implements the DRF algorithm
@@ -82,16 +82,15 @@ TEST_F(DRFAllocatorTest, DRFAllocatorProcess)
EXPECT_CALL(allocator, initialize(_, _));
- Try<PID<Master> > master = cluster.masters.start(&allocator);
+ Try<PID<Master> > master = StartMaster(&allocator);
ASSERT_SOME(master);
- TestingIsolator isolator1;
- slave::Flags flags1 = cluster.slaves.flags;
+ slave::Flags flags1 = CreateSlaveFlags();
flags1.resources = Option<string>("cpus:2;mem:1024;disk:0");
EXPECT_CALL(allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave1 = cluster.slaves.start(flags1, &isolator1);
+ Try<PID<Slave> > slave1 = StartSlave(flags1);
ASSERT_SOME(slave1);
// Total cluster resources now cpus=2, mem=1024.
@@ -135,8 +134,7 @@ TEST_F(DRFAllocatorTest, DRFAllocatorProcess)
AWAIT_READY(frameworkAdded2);
- TestingIsolator isolator2;
- slave::Flags flags2 = cluster.slaves.flags;
+ slave::Flags flags2 = CreateSlaveFlags();
flags2.resources = Option<string>("cpus:1;mem:512;disk:0");
EXPECT_CALL(allocator, slaveAdded(_, _, _));
@@ -145,7 +143,7 @@ TEST_F(DRFAllocatorTest, DRFAllocatorProcess)
EXPECT_CALL(sched2, resourceOffers(_, _))
.WillOnce(FutureArg<1>(&offers2));
- Try<PID<Slave> > slave2 = cluster.slaves.start(flags2, &isolator2);
+ Try<PID<Slave> > slave2 = StartSlave(flags2);
ASSERT_SOME(slave2);
// Total cluster resources now cpus=3, mem=1536.
// framework1 share = 0.66
@@ -159,8 +157,7 @@ TEST_F(DRFAllocatorTest, DRFAllocatorProcess)
// framework1 share = 0.66
// framework2 share = 0.33
- TestingIsolator isolator3;
- slave::Flags flags3 = cluster.slaves.flags;
+ slave::Flags flags3 = CreateSlaveFlags();
flags3.resources = Option<string>("cpus:3;mem:2048;disk:0");
EXPECT_CALL(allocator, slaveAdded(_, _, _));
@@ -169,7 +166,7 @@ TEST_F(DRFAllocatorTest, DRFAllocatorProcess)
EXPECT_CALL(sched2, resourceOffers(_, _))
.WillOnce(FutureArg<1>(&offers3));
- Try<PID<Slave> > slave3 = cluster.slaves.start(flags3, &isolator3);
+ Try<PID<Slave> > slave3 = StartSlave(flags3);
ASSERT_SOME(slave3);
// Total cluster resources now cpus=6, mem=3584.
// framework1 share = 0.33
@@ -200,8 +197,7 @@ TEST_F(DRFAllocatorTest, DRFAllocatorProcess)
AWAIT_READY(frameworkAdded3);
- TestingIsolator isolator4;
- slave::Flags flags4 = cluster.slaves.flags;
+ slave::Flags flags4 = CreateSlaveFlags();
flags4.resources = Option<string>("cpus:4;mem:4096;disk:0");
EXPECT_CALL(allocator, slaveAdded(_, _, _));
@@ -210,7 +206,7 @@ TEST_F(DRFAllocatorTest, DRFAllocatorProcess)
EXPECT_CALL(sched3, resourceOffers(_, _))
.WillOnce(FutureArg<1>(&offers4));
- Try<PID<Slave> > slave4 = cluster.slaves.start(flags4, &isolator4);
+ Try<PID<Slave> > slave4 = StartSlave(flags4);
ASSERT_SOME(slave4);
// Total cluster resources now cpus=10, mem=7680.
// framework1 share = 0.2
@@ -240,17 +236,17 @@ TEST_F(DRFAllocatorTest, DRFAllocatorProcess)
driver2.stop();
driver3.stop();
- cluster.shutdown();
+ Shutdown();
}
template <typename T>
-class AllocatorTest : public MesosClusterTest
+class AllocatorTest : public MesosTest
{
protected:
virtual void SetUp()
{
- MesosClusterTest::SetUp();
+ MesosTest::SetUp();
a = new Allocator(&allocator);
}
@@ -258,7 +254,7 @@ protected:
virtual void TearDown()
{
delete a;
- MesosClusterTest::TearDown();
+ MesosTest::TearDown();
}
MockAllocatorProcess<T> allocator;
@@ -277,17 +273,15 @@ TYPED_TEST(AllocatorTest, MockAllocator)
{
EXPECT_CALL(this->allocator, initialize(_, _));
- Try<PID<Master> > master = this->cluster.masters.start(&this->allocator);
+ Try<PID<Master> > master = this->StartMaster(&this->allocator);
ASSERT_SOME(master);
- MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- slave::Flags flags = this->cluster.slaves.flags;
+ slave::Flags flags = this->CreateSlaveFlags();
flags.resources = Option<string>("cpus:2;mem:1024;disk:0");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave = this->cluster.slaves.start(flags, &isolator);
+ Try<PID<Slave> > slave = this->StartSlave(flags);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -327,11 +321,11 @@ TYPED_TEST(AllocatorTest, MockAllocator)
EXPECT_CALL(this->allocator, slaveRemoved(_))
.WillOnce(FutureSatisfy(&slaveRemoved));
- this->cluster.slaves.shutdown();
+ this->ShutdownSlaves();
AWAIT_READY(slaveRemoved);
- this->cluster.masters.shutdown();
+ this->ShutdownMasters();
}
@@ -342,17 +336,17 @@ TYPED_TEST(AllocatorTest, ResourcesUnused)
{
EXPECT_CALL(this->allocator, initialize(_, _));
- Try<PID<Master> > master = this->cluster.masters.start(&this->allocator);
+ Try<PID<Master> > master = this->StartMaster(&this->allocator);
ASSERT_SOME(master);
- MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- slave::Flags flags1 = this->cluster.slaves.flags;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+
+ slave::Flags flags1 = this->CreateSlaveFlags();
flags1.resources = Option<string>("cpus:2;mem:1024");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave1 = this->cluster.slaves.start(flags1, &isolator);
+ Try<PID<Slave> > slave1 = this->StartSlave(&exec, flags1);
ASSERT_SOME(slave1);
MockScheduler sched1;
@@ -431,7 +425,7 @@ TYPED_TEST(AllocatorTest, ResourcesUnused)
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
- this->cluster.shutdown();
+ this->Shutdown();
}
@@ -442,16 +436,15 @@ TYPED_TEST(AllocatorTest, OutOfOrderDispatch)
{
EXPECT_CALL(this->allocator, initialize(_, _));
- Try<PID<Master> > master = this->cluster.masters.start(&this->allocator);
+ Try<PID<Master> > master = this->StartMaster(&this->allocator);
ASSERT_SOME(master);
- TestingIsolator isolator;
- slave::Flags flags1 = this->cluster.slaves.flags;
+ slave::Flags flags1 = this->CreateSlaveFlags();
flags1.resources = Option<string>("cpus:2;mem:1024");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave1 = this->cluster.slaves.start(flags1, &isolator);
+ Try<PID<Slave> > slave1 = this->StartSlave(flags1);
ASSERT_SOME(slave1);
FrameworkInfo frameworkInfo1;
@@ -553,7 +546,7 @@ TYPED_TEST(AllocatorTest, OutOfOrderDispatch)
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
- this->cluster.shutdown();
+ this->Shutdown();
}
@@ -564,17 +557,18 @@ TYPED_TEST(AllocatorTest, SchedulerFailover)
{
EXPECT_CALL(this->allocator, initialize(_, _));
- Try<PID<Master> > master = this->cluster.masters.start(&this->allocator);
+ Try<PID<Master> > master = this->StartMaster(&this->allocator);
ASSERT_SOME(master);
- MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- slave::Flags flags = this->cluster.slaves.flags;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+ TestingIsolator isolator(&exec);
+
+ slave::Flags flags = this->CreateSlaveFlags();
flags.resources = Option<string>("cpus:3;mem:1024");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave = this->cluster.slaves.start(flags, &isolator);
+ Try<PID<Slave> > slave = this->StartSlave(&isolator, flags);
ASSERT_SOME(slave);
FrameworkInfo frameworkInfo1;
@@ -680,7 +674,7 @@ TYPED_TEST(AllocatorTest, SchedulerFailover)
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
- this->cluster.shutdown();
+ this->Shutdown();
}
@@ -690,12 +684,12 @@ TYPED_TEST(AllocatorTest, FrameworkExited)
{
EXPECT_CALL(this->allocator, initialize(_, _));
- master::Flags masterFlags = this->cluster.masters.flags;
+ master::Flags masterFlags = this->CreateMasterFlags();
masterFlags.allocation_interval = Duration::parse("50ms").get();
- Try<PID<Master> > master = this->cluster.masters.start(&this->allocator, masterFlags);
+ Try<PID<Master> > master = this->StartMaster(&this->allocator, masterFlags);
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
EXPECT_CALL(exec, registered(_, _, _, _))
.Times(2);
@@ -707,8 +701,9 @@ TYPED_TEST(AllocatorTest, FrameworkExited)
EXPECT_CALL(exec, shutdown(_))
.Times(AtMost(2));
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- slave::Flags flags = this->cluster.slaves.flags;
+ TestingIsolator isolator(&exec);
+
+ slave::Flags flags = this->CreateSlaveFlags();
flags.resources = Option<string>("cpus:3;mem:1024");
EXPECT_CALL(isolator, resourcesChanged(_, _, _))
@@ -716,7 +711,7 @@ TYPED_TEST(AllocatorTest, FrameworkExited)
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave = this->cluster.slaves.start(flags, &isolator);
+ Try<PID<Slave> > slave = this->StartSlave(&isolator, flags);
ASSERT_SOME(slave);
MockScheduler sched1;
@@ -809,7 +804,7 @@ TYPED_TEST(AllocatorTest, FrameworkExited)
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
- this->cluster.shutdown();
+ this->Shutdown();
}
@@ -821,17 +816,18 @@ TYPED_TEST(AllocatorTest, SlaveLost)
{
EXPECT_CALL(this->allocator, initialize(_, _));
- Try<PID<Master> > master = this->cluster.masters.start(&this->allocator);
+ Try<PID<Master> > master = this->StartMaster(&this->allocator);
ASSERT_SOME(master);
- MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- slave::Flags flags1 = this->cluster.slaves.flags;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+ TestingIsolator isolator(&exec);
+
+ slave::Flags flags1 = this->CreateSlaveFlags();
flags1.resources = Option<string>("cpus:2;mem:1024");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave1 = this->cluster.slaves.start(flags1, &isolator);
+ Try<PID<Slave> > slave1 = this->StartSlave(&isolator, flags1);
ASSERT_SOME(slave1);
MockScheduler sched1;
@@ -887,15 +883,15 @@ TYPED_TEST(AllocatorTest, SlaveLost)
EXPECT_CALL(sched1, slaveLost(_, _));
- this->cluster.slaves.shutdown();
+ this->ShutdownSlaves();
AWAIT_READY(slaveRemoved1);
AWAIT_READY(shutdownCall);
- MockExecutor exec2;
- TestingIsolator isolator2(DEFAULT_EXECUTOR_ID, &exec2);
- slave::Flags flags2 = this->cluster.slaves.flags;
+ MockExecutor exec2(DEFAULT_EXECUTOR_ID);
+
+ slave::Flags flags2 = this->CreateSlaveFlags();
flags2.resources = Option<string>("cpus:3;mem:256");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
@@ -907,7 +903,7 @@ TYPED_TEST(AllocatorTest, SlaveLost)
EXPECT_CALL(sched1, resourceOffers(_, OfferEq(3, 256)))
.WillOnce(FutureArg<1>(&resourceOffers2));
- Try<PID<Slave> > slave2 = this->cluster.slaves.start(flags2, &isolator2);
+ Try<PID<Slave> > slave2 = this->StartSlave(&exec2, flags2);
ASSERT_SOME(slave2);
AWAIT_READY(resourceOffers2);
@@ -935,7 +931,7 @@ TYPED_TEST(AllocatorTest, SlaveLost)
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
- this->cluster.shutdown();
+ this->Shutdown();
}
@@ -946,19 +942,20 @@ TYPED_TEST(AllocatorTest, SlaveAdded)
{
EXPECT_CALL(this->allocator, initialize(_, _));
- master::Flags masterFlags = this->cluster.masters.flags;
+ master::Flags masterFlags = this->CreateMasterFlags();
masterFlags.allocation_interval = Duration::parse("50ms").get();
- Try<PID<Master> > master = this->cluster.masters.start(&this->allocator, masterFlags);
+ Try<PID<Master> > master = this->StartMaster(&this->allocator, masterFlags);
ASSERT_SOME(master);
- MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- slave::Flags flags1 = this->cluster.slaves.flags;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+ TestingIsolator isolator(&exec);
+
+ slave::Flags flags1 = this->CreateSlaveFlags();
flags1.resources = Option<string>("cpus:3;mem:1024");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave1 = this->cluster.slaves.start(flags1, &isolator);
+ Try<PID<Slave> > slave1 = this->StartSlave(&isolator, flags1);
ASSERT_SOME(slave1);
MockScheduler sched1;
@@ -1004,7 +1001,7 @@ TYPED_TEST(AllocatorTest, SlaveAdded)
AWAIT_READY(launchTask);
- slave::Flags flags2 = this->cluster.slaves.flags;
+ slave::Flags flags2 = this->CreateSlaveFlags();
flags2.resources = Option<string>("cpus:4;mem:2048");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
@@ -1016,7 +1013,7 @@ TYPED_TEST(AllocatorTest, SlaveAdded)
EXPECT_CALL(sched1, resourceOffers(_, OfferEq(5, 2560)))
.WillOnce(FutureSatisfy(&resourceOffers2));
- Try<PID<Slave> > slave2 = this->cluster.slaves.start(flags2, &isolator);
+ Try<PID<Slave> > slave2 = this->StartSlave(flags2);
ASSERT_SOME(slave2);
AWAIT_READY(resourceOffers2);
@@ -1042,7 +1039,7 @@ TYPED_TEST(AllocatorTest, SlaveAdded)
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(2));
- this->cluster.shutdown();
+ this->Shutdown();
}
@@ -1052,19 +1049,20 @@ TYPED_TEST(AllocatorTest, TaskFinished)
{
EXPECT_CALL(this->allocator, initialize(_, _));
- master::Flags masterFlags = this->cluster.masters.flags;
+ master::Flags masterFlags = this->CreateMasterFlags();
masterFlags.allocation_interval = Duration::parse("50ms").get();
- Try<PID<Master> > master = this->cluster.masters.start(&this->allocator, masterFlags);
+ Try<PID<Master> > master = this->StartMaster(&this->allocator, masterFlags);
ASSERT_SOME(master);
- MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- slave::Flags flags = this->cluster.slaves.flags;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+ TestingIsolator isolator(&exec);
+
+ slave::Flags flags = this->CreateSlaveFlags();
flags.resources = Option<string>("cpus:3;mem:1024");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave = this->cluster.slaves.start(flags, &isolator);
+ Try<PID<Slave> > slave = this->StartSlave(&isolator, flags);
ASSERT_SOME(slave);
MockScheduler sched1;
@@ -1156,7 +1154,7 @@ TYPED_TEST(AllocatorTest, TaskFinished)
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
- this->cluster.shutdown();
+ this->Shutdown();
}
@@ -1170,7 +1168,7 @@ TYPED_TEST(AllocatorTest, WhitelistSlave)
string path = "whitelist.txt";
ASSERT_SOME(os::write(path, hosts)) << "Error writing whitelist";
- master::Flags masterFlags = this->cluster.masters.flags;
+ master::Flags masterFlags = this->CreateMasterFlags();
masterFlags.whitelist = "file://" + path; // TODO(benh): Put in /tmp.
EXPECT_CALL(this->allocator, initialize(_, _));
@@ -1180,17 +1178,15 @@ TYPED_TEST(AllocatorTest, WhitelistSlave)
.WillOnce(DoAll(InvokeUpdateWhitelist(&this->allocator),
FutureSatisfy(&updateWhitelist1)));
- Try<PID<Master> > master = this->cluster.masters.start(&this->allocator, masterFlags);
+ Try<PID<Master> > master = this->StartMaster(&this->allocator, masterFlags);
ASSERT_SOME(master);
- MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- slave::Flags flags = this->cluster.slaves.flags;
+ slave::Flags flags = this->CreateSlaveFlags();
flags.resources = Option<string>("cpus:2;mem:1024");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave = this->cluster.slaves.start(flags, &isolator);
+ Try<PID<Slave> > slave = this->StartSlave(flags);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -1256,7 +1252,7 @@ TYPED_TEST(AllocatorTest, WhitelistSlave)
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
- this->cluster.shutdown();
+ this->Shutdown();
os::rm(path);
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/allocator_zookeeper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/allocator_zookeeper_tests.cpp b/src/tests/allocator_zookeeper_tests.cpp
index d03a564..31f4dc6 100644
--- a/src/tests/allocator_zookeeper_tests.cpp
+++ b/src/tests/allocator_zookeeper_tests.cpp
@@ -22,16 +22,15 @@
#include <process/gmock.hpp>
#include <process/message.hpp>
-#include "detector/detector.hpp"
+#include <stout/option.hpp>
+#include <stout/try.hpp>
#include "master/allocator.hpp"
#include "master/master.hpp"
-#include "tests/utils.hpp"
+#include "tests/mesos.hpp"
#include "tests/zookeeper.hpp"
-#include "zookeeper/url.hpp"
-
using namespace mesos;
using namespace mesos::internal;
using namespace mesos::internal::tests;
@@ -45,7 +44,6 @@ using mesos::internal::slave::Slave;
using process::Future;
using process::PID;
-using std::map;
using std::string;
using std::vector;
@@ -53,20 +51,49 @@ using testing::_;
using testing::AtMost;
using testing::DoAll;
using testing::DoDefault;
-using testing::Eq;
-using testing::Return;
-using testing::SaveArg;
template <typename T = AllocatorProcess>
-class AllocatorZooKeeperTest : public ZooKeeperTest
+class AllocatorZooKeeperTest : public MesosTest
{
+public:
+ static void SetUpTestCase()
+ {
+ // Make sure the JVM is created.
+ ZooKeeperTest::SetUpTestCase();
+
+ // Launch the ZooKeeper test server.
+ server = new ZooKeeperTestServer();
+ server->startNetwork();
+
+ Try<zookeeper::URL> parse = zookeeper::URL::parse(
+ "zk://" + server->connectString() + "/znode");
+ ASSERT_SOME(parse);
+
+ url = parse.get();
+ }
+
+ static void TearDownTestCase()
+ {
+ delete server;
+ server = NULL;
+ }
+
protected:
- T allocator1;
- MockAllocatorProcess<T> allocator2;
+ AllocatorZooKeeperTest() : MesosTest(url) {}
+
+ static ZooKeeperTestServer* server;
+ static Option<zookeeper::URL> url;
};
+template <typename T>
+ZooKeeperTestServer* AllocatorZooKeeperTest<T>::server = NULL;
+
+template <typename T>
+Option<zookeeper::URL> AllocatorZooKeeperTest<T>::url;
+
+
// Runs TYPED_TEST(AllocatorZooKeeperTest, ...) on all AllocatorTypes.
TYPED_TEST_CASE(AllocatorZooKeeperTest, AllocatorTypes);
@@ -77,25 +104,22 @@ TYPED_TEST_CASE(AllocatorZooKeeperTest, AllocatorTypes);
// accounted for correctly.
TYPED_TEST(AllocatorZooKeeperTest, FrameworkReregistersFirst)
{
- string zk = "zk://" + this->server->connectString() + "/znode";
- Try<zookeeper::URL> url = zookeeper::URL::parse(zk);
- ASSERT_SOME(url);
+ TypeParam allocator1;
- Cluster cluster(url.get());
-
- Try<PID<Master> > master = cluster.masters.start(&this->allocator1);
+ Try<PID<Master> > master = this->StartMaster(&allocator1);
ASSERT_SOME(master);
- MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- slave::Flags flags = cluster.slaves.flags;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+
+ slave::Flags flags = this->CreateSlaveFlags();
flags.resources = Option<string>("cpus:2;mem:1024");
- Try<PID<Slave> > slave = cluster.slaves.start(flags, &isolator);
+ Try<PID<Slave> > slave = this->StartSlave(&exec, flags);
ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, zk);
+ MesosSchedulerDriver driver(
+ &sched, DEFAULT_FRAMEWORK_INFO, stringify(this->url.get()));
Future<Nothing> registered;
EXPECT_CALL(sched, registered(&driver, _, _))
@@ -141,32 +165,34 @@ TYPED_TEST(AllocatorZooKeeperTest, FrameworkReregistersFirst)
// Stop the failing master from telling the slave to shut down when
// it is killed.
- Future<process::Message> shutdownMsg =
- DROP_MESSAGE(Eq(ShutdownMessage().GetTypeName()), _, _);
+ Future<ShutdownMessage> shutdownMessage =
+ DROP_PROTOBUF(ShutdownMessage(), _, _);
// Stop the slave from reregistering with the new master until the
// framework has reregistered.
- DROP_MESSAGES(Eq(ReregisterSlaveMessage().GetTypeName()), _, _);
+ DROP_PROTOBUFS(ReregisterSlaveMessage(), _, _);
- cluster.masters.shutdown();
+ this->ShutdownMasters();
- AWAIT_READY(shutdownMsg);
+ AWAIT_READY(shutdownMessage);
- EXPECT_CALL(this->allocator2, initialize(_, _));
+ MockAllocatorProcess<TypeParam> allocator2;
- Try<PID<Master> > master2 = cluster.masters.start(&this->allocator2);
+ EXPECT_CALL(allocator2, initialize(_, _));
+
+ Try<PID<Master> > master2 = this->StartMaster(&allocator2);
ASSERT_SOME(master2);
Future<Nothing> frameworkAdded;
- EXPECT_CALL(this->allocator2, frameworkAdded(_, _, _))
- .WillOnce(DoAll(InvokeFrameworkAdded(&this->allocator2),
+ EXPECT_CALL(allocator2, frameworkAdded(_, _, _))
+ .WillOnce(DoAll(InvokeFrameworkAdded(&allocator2),
FutureSatisfy(&frameworkAdded)));
EXPECT_CALL(sched, reregistered(&driver, _));
AWAIT_READY(frameworkAdded);
- EXPECT_CALL(this->allocator2, slaveAdded(_, _, _));
+ EXPECT_CALL(allocator2, slaveAdded(_, _, _));
Future<vector<Offer> > resourceOffers2;
EXPECT_CALL(sched, resourceOffers(&driver, _))
@@ -184,13 +210,13 @@ TYPED_TEST(AllocatorZooKeeperTest, FrameworkReregistersFirst)
EXPECT_THAT(resourceOffers2.get(), OfferEq(1, 524));
// Shut everything down.
- EXPECT_CALL(this->allocator2, resourcesRecovered(_, _, _))
+ EXPECT_CALL(allocator2, resourcesRecovered(_, _, _))
.WillRepeatedly(DoDefault());
- EXPECT_CALL(this->allocator2, frameworkDeactivated(_));
+ EXPECT_CALL(allocator2, frameworkDeactivated(_));
Future<Nothing> frameworkRemoved;
- EXPECT_CALL(this->allocator2, frameworkRemoved(_))
+ EXPECT_CALL(allocator2, frameworkRemoved(_))
.WillOnce(FutureSatisfy(&frameworkRemoved));
EXPECT_CALL(exec, shutdown(_))
@@ -201,10 +227,10 @@ TYPED_TEST(AllocatorZooKeeperTest, FrameworkReregistersFirst)
AWAIT_READY(frameworkRemoved);
- EXPECT_CALL(this->allocator2, slaveRemoved(_))
+ EXPECT_CALL(allocator2, slaveRemoved(_))
.Times(AtMost(1));
- cluster.shutdown();
+ this->Shutdown();
}
@@ -214,25 +240,22 @@ TYPED_TEST(AllocatorZooKeeperTest, FrameworkReregistersFirst)
// accounted for correctly.
TYPED_TEST(AllocatorZooKeeperTest, SlaveReregistersFirst)
{
- string zk = "zk://" + this->server->connectString() + "/znode";
- Try<zookeeper::URL> url = zookeeper::URL::parse(zk);
- ASSERT_SOME(url);
-
- Cluster cluster(url.get());
+ TypeParam allocator1;
- Try<PID<Master> > master = cluster.masters.start(&this->allocator1);
+ Try<PID<Master> > master = this->StartMaster(&allocator1);
ASSERT_SOME(master);
- MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- slave::Flags flags = cluster.slaves.flags;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+
+ slave::Flags flags = this->CreateSlaveFlags();
flags.resources = Option<string>("cpus:2;mem:1024");
- Try<PID<Slave> > slave = cluster.slaves.start(flags, &isolator);
+ Try<PID<Slave> > slave = this->StartSlave(&exec, flags);
ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO,zk);
+ MesosSchedulerDriver driver(
+ &sched, DEFAULT_FRAMEWORK_INFO, stringify(this->url.get()));
Future<Nothing> registered;
EXPECT_CALL(sched, registered(&driver, _, _))
@@ -278,32 +301,34 @@ TYPED_TEST(AllocatorZooKeeperTest, SlaveReregistersFirst)
// Stop the failing master from telling the slave to shut down when
// it is killed.
- Future<process::Message> shutdownMsg =
- DROP_MESSAGE(Eq(ShutdownMessage().GetTypeName()), _, _);
+ Future<ShutdownMessage> shutdownMessage =
+ DROP_PROTOBUF(ShutdownMessage(), _, _);
// Stop the framework from reregistering with the new master until the
// slave has reregistered.
- DROP_MESSAGES(Eq(ReregisterFrameworkMessage().GetTypeName()), _, _);
+ DROP_PROTOBUFS(ReregisterFrameworkMessage(), _, _);
+
+ this->ShutdownMasters();
- cluster.masters.shutdown();
+ AWAIT_READY(shutdownMessage);
- AWAIT_READY(shutdownMsg);
+ MockAllocatorProcess<TypeParam> allocator2;
- EXPECT_CALL(this->allocator2, initialize(_, _));
+ EXPECT_CALL(allocator2, initialize(_, _));
- Try<PID<Master> > master2 = cluster.masters.start(&this->allocator2);
+ Try<PID<Master> > master2 = this->StartMaster(&allocator2);
ASSERT_SOME(master2);
Future<Nothing> slaveAdded;
- EXPECT_CALL(this->allocator2, slaveAdded(_, _, _))
- .WillOnce(DoAll(InvokeSlaveAdded(&this->allocator2),
+ EXPECT_CALL(allocator2, slaveAdded(_, _, _))
+ .WillOnce(DoAll(InvokeSlaveAdded(&allocator2),
FutureSatisfy(&slaveAdded)));
EXPECT_CALL(sched, reregistered(&driver, _));
AWAIT_READY(slaveAdded);
- EXPECT_CALL(this->allocator2, frameworkAdded(_, _, _));
+ EXPECT_CALL(allocator2, frameworkAdded(_, _, _));
Future<vector<Offer> > resourceOffers2;
EXPECT_CALL(sched, resourceOffers(&driver, _))
@@ -321,13 +346,13 @@ TYPED_TEST(AllocatorZooKeeperTest, SlaveReregistersFirst)
EXPECT_THAT(resourceOffers2.get(), OfferEq(1, 524));
// Shut everything down.
- EXPECT_CALL(this->allocator2, resourcesRecovered(_, _, _))
+ EXPECT_CALL(allocator2, resourcesRecovered(_, _, _))
.WillRepeatedly(DoDefault());
- EXPECT_CALL(this->allocator2, frameworkDeactivated(_));
+ EXPECT_CALL(allocator2, frameworkDeactivated(_));
Future<Nothing> frameworkRemoved;
- EXPECT_CALL(this->allocator2, frameworkRemoved(_))
+ EXPECT_CALL(allocator2, frameworkRemoved(_))
.WillOnce(FutureSatisfy(&frameworkRemoved));
EXPECT_CALL(exec, shutdown(_))
@@ -338,8 +363,8 @@ TYPED_TEST(AllocatorZooKeeperTest, SlaveReregistersFirst)
AWAIT_READY(frameworkRemoved);
- EXPECT_CALL(this->allocator2, slaveRemoved(_))
+ EXPECT_CALL(allocator2, slaveRemoved(_))
.Times(AtMost(1));
- cluster.shutdown();
+ this->Shutdown();
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/cgroups_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/cgroups_tests.cpp b/src/tests/cgroups_tests.cpp
index db33738..f062fe6 100644
--- a/src/tests/cgroups_tests.cpp
+++ b/src/tests/cgroups_tests.cpp
@@ -35,6 +35,9 @@
#include <gmock/gmock.h>
+#include <process/gtest.hpp>
+
+#include <stout/gtest.hpp>
#include <stout/hashmap.hpp>
#include <stout/option.hpp>
#include <stout/os.hpp>
@@ -44,7 +47,7 @@
#include "linux/cgroups.hpp"
-#include "tests/utils.hpp"
+#include "tests/mesos.hpp" // For TEST_CGROUPS_(HIERARCHY|ROOT).
using namespace mesos::internal::tests;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/cluster.hpp
----------------------------------------------------------------------
diff --git a/src/tests/cluster.hpp b/src/tests/cluster.hpp
index 682b7d6..25cd554 100644
--- a/src/tests/cluster.hpp
+++ b/src/tests/cluster.hpp
@@ -43,10 +43,9 @@
#include "slave/flags.hpp"
#include "slave/isolator.hpp"
+#include "slave/process_isolator.hpp"
#include "slave/slave.hpp"
-#include "tests/isolator.hpp" // For TestingIsolator.
-
#include "zookeeper/url.hpp"
namespace mesos {
@@ -56,7 +55,6 @@ namespace tests {
class Cluster
{
public:
- // TODO(benh): Take flags and make const in Masters and Slaves.
Cluster(const Option<zookeeper::URL>& url = None())
: masters(this, url),
slaves(this, &masters) {}
@@ -70,23 +68,17 @@ public:
void shutdown();
- // Start and manage a new master.
- Try<process::PID<master::Master> > start();
-
// Start and manage a new master using the specified flags.
- Try<process::PID<master::Master> > start(const master::Flags& flags);
-
- // Start and manage a new master injecting the specified allocator
- // process. The allocator process is expected to outlive the
- // launched master (i.e., until it is stopped via Masters::stop).
Try<process::PID<master::Master> > start(
- master::AllocatorProcess* allocatorProcess);
+ const master::Flags& flags = master::Flags());
- // Start and manage a new master using the specified flags
- // and injecting the allocator process as above.
+ // Start and manage a new master injecting the specified allocator
+ // process and using the specified flags. The allocator process is
+ // expected to outlive the launched master (i.e., until it is
+ // stopped via Masters::stop).
Try<process::PID<master::Master> > start(
master::AllocatorProcess* allocatorProcess,
- const master::Flags& flags);
+ const master::Flags& flags = master::Flags());
// Stops and cleans up a master at the specified PID.
Try<Nothing> stop(const process::PID<master::Master>& pid);
@@ -94,10 +86,7 @@ public:
// Returns a new master detector for this instance of masters.
Owned<MasterDetector> detector(
const process::PID<slave::Slave>& pid,
- bool quiet);
-
- // "Default" flags used for creating masters.
- master::Flags flags;
+ const slave::Flags& flags);
private:
// Not copyable, not assignable.
@@ -107,6 +96,7 @@ public:
Cluster* cluster; // Enclosing class.
Option<zookeeper::URL> url;
+ // Encapsulates a single master's dependencies.
struct Master
{
Master()
@@ -134,42 +124,24 @@ public:
// Stop and clean up all slaves.
void shutdown();
- // Start and manage a new slave.
- Try<process::PID<slave::Slave> > start();
-
- // Start and manage a new slave using the specified flags.
- Try<process::PID<slave::Slave> > start(const slave::Flags& flags);
-
- // Start and manage a new slave with a testing isolator that uses
- // the specified executor for the specified ID. The executor is
- // expected to outlive the launched slave (i.e., until it is
- // stopped via Slaves::stop).
+ // Start and manage a new slave with a process isolator using the
+ // specified flags.
Try<process::PID<slave::Slave> > start(
- const ExecutorID& executorId,
- Executor* executor);
-
- // Start and manage a new slave using the specified flags with a
- // testing isolator that uses the specified executor for the
- // specified ID. The executor is expected to outlive the launched
- // slave (i.e., until it is stopped via Slaves::stop).
- Try<process::PID<slave::Slave> > start(
- const slave::Flags& flags,
- const ExecutorID& executorId,
- Executor* executor);
+ const slave::Flags& flags = slave::Flags());
// Start and manage a new slave injecting the specified isolator.
// The isolator is expected to outlive the launched slave (i.e.,
// until it is stopped via Slaves::stop).
- Try<process::PID<slave::Slave> > start(slave::Isolator* isolator);
Try<process::PID<slave::Slave> > start(
- const slave::Flags& flags,
- slave::Isolator* isolator);
+ slave::Isolator* isolator,
+ const slave::Flags& flags = slave::Flags());
- // Stops and cleans up a slave at the specified PID.
- Try<Nothing> stop(const process::PID<slave::Slave>& pid);
-
- // "Default" flags used for creating slaves.
- slave::Flags flags;
+ // Stops and cleans up a slave at the specified PID. If 'shutdown'
+ // is true than the slave is sent a shutdown message instead of
+ // being terminated.
+ Try<Nothing> stop(
+ const process::PID<slave::Slave>& pid,
+ bool shutdown = false);
private:
// Not copyable, not assignable.
@@ -179,15 +151,16 @@ public:
Cluster* cluster; // Enclosing class.
Masters* masters; // Used to create MasterDetector instances.
+ // Encapsulates a single slave's dependencies.
struct Slave
{
Slave()
- : slave(NULL),
- isolator(NULL),
+ : isolator(NULL),
+ slave(NULL),
detector(NULL) {}
- slave::Slave* slave;
slave::Isolator* isolator;
+ slave::Slave* slave;
Owned<MasterDetector> detector;
};
@@ -238,32 +211,6 @@ inline void Cluster::Masters::shutdown()
}
-inline Try<process::PID<master::Master> > Cluster::Masters::start()
-{
- // Disallow multiple masters when not using ZooKeeper.
- if (!masters.empty() && url.isNone()) {
- return Error("Can not start multiple masters when not using ZooKeeper");
- }
-
- Master master;
- master.allocatorProcess = new master::HierarchicalDRFAllocatorProcess();
- master.allocator = new master::Allocator(master.allocatorProcess);
- master.master = new master::Master(master.allocator, &cluster->files, flags);
-
- process::PID<master::Master> pid = process::spawn(master.master);
-
- if (url.isSome()) {
- master.detector = new ZooKeeperMasterDetector(url.get(), pid, true, true);
- } else {
- master.detector = new BasicMasterDetector(pid);
- }
-
- masters[pid] = master;
-
- return pid;
-}
-
-
inline Try<process::PID<master::Master> > Cluster::Masters::start(
const master::Flags& flags)
{
@@ -273,6 +220,7 @@ inline Try<process::PID<master::Master> > Cluster::Masters::start(
}
Master master;
+
master.allocatorProcess = new master::HierarchicalDRFAllocatorProcess();
master.allocator = new master::Allocator(master.allocatorProcess);
master.master = new master::Master(master.allocator, &cluster->files, flags);
@@ -292,13 +240,6 @@ inline Try<process::PID<master::Master> > Cluster::Masters::start(
inline Try<process::PID<master::Master> > Cluster::Masters::start(
- master::AllocatorProcess* allocatorProcess)
-{
- return Cluster::Masters::start(allocatorProcess, flags);
-}
-
-
-inline Try<process::PID<master::Master> > Cluster::Masters::start(
master::AllocatorProcess* allocatorProcess,
const master::Flags& flags)
{
@@ -339,11 +280,8 @@ inline Try<Nothing> Cluster::Masters::stop(
process::wait(master.master);
delete master.master;
- delete master.allocator; // Terminates and waits for the allocator process.
-
- if (master.allocatorProcess != NULL) {
- delete master.allocatorProcess;
- }
+ delete master.allocator; // Terminates and waits for allocator process.
+ delete master.allocatorProcess; // May be NULL.
delete master.detector;
@@ -355,10 +293,10 @@ inline Try<Nothing> Cluster::Masters::stop(
inline Owned<MasterDetector> Cluster::Masters::detector(
const process::PID<slave::Slave>& pid,
- bool quiet)
+ const slave::Flags& flags)
{
if (url.isSome()) {
- return new ZooKeeperMasterDetector(url.get(), pid, false, quiet);
+ return new ZooKeeperMasterDetector(url.get(), pid, false, flags.quiet);
}
CHECK(masters.size() == 1);
@@ -387,52 +325,22 @@ inline void Cluster::Slaves::shutdown()
}
-inline Try<process::PID<slave::Slave> > Cluster::Slaves::start()
-{
- // TODO(benh): Check that we dont have another slave already running
- // with flags that conflict (e.g., work_dir).
-
- Slave slave;
-
- slave.isolator = new TestingIsolator();
-
- process::spawn(slave.isolator);
-
- // TODO(benh): Create a work directory for each slave.
-
- slave.slave = new slave::Slave(flags, true, slave.isolator, &cluster->files);
-
- process::PID<slave::Slave> pid = process::spawn(slave.slave);
-
- // Get a detector for the master(s).
- slave.detector = masters->detector(pid, flags.quiet);
-
- slaves[pid] = slave;
-
- return pid;
-}
-
-
inline Try<process::PID<slave::Slave> > Cluster::Slaves::start(
const slave::Flags& flags)
{
- // TODO(benh): Check that we dont have another slave already running
- // with flags that conflict (e.g., work_dir).
+ // TODO(benh): Create a work directory if using the default.
Slave slave;
- slave.isolator = new TestingIsolator();
-
+ // Create a new process isolator for this slave.
+ slave.isolator = new slave::ProcessIsolator();
process::spawn(slave.isolator);
- // TODO(benh): Create a work directory for each slave.
-
slave.slave = new slave::Slave(flags, true, slave.isolator, &cluster->files);
-
process::PID<slave::Slave> pid = process::spawn(slave.slave);
// Get a detector for the master(s).
- slave.detector = masters->detector(pid, flags.quiet);
+ slave.detector = masters->detector(pid, flags);
slaves[pid] = slave;
@@ -441,82 +349,18 @@ inline Try<process::PID<slave::Slave> > Cluster::Slaves::start(
inline Try<process::PID<slave::Slave> > Cluster::Slaves::start(
- const ExecutorID& executorId,
- Executor* executor)
-{
- return start(flags, executorId, executor);
-}
-
-
-inline Try<process::PID<slave::Slave> > Cluster::Slaves::start(
- const slave::Flags& flags,
- const ExecutorID& executorId,
- Executor* executor)
-{
- // TODO(benh): Check that we dont have another slave already running
- // with flags that conflict (e.g., work_dir).
-
- Slave slave;
-
- slave.isolator = new TestingIsolator(executorId, executor);
-
- process::spawn(slave.isolator);
-
- // TODO(benh): Create a work directory for each slave.
-
- slave.slave = new slave::Slave(flags, true, slave.isolator, &cluster->files);
-
- process::PID<slave::Slave> pid = process::spawn(slave.slave);
-
- // Get a detector for the master(s).
- slave.detector = masters->detector(pid, flags.quiet);
-
- slaves[pid] = slave;
-
- return pid;
-}
-
-
-inline Try<process::PID<slave::Slave> > Cluster::Slaves::start(
- slave::Isolator* isolator)
-{
- // TODO(benh): Check that we dont have another slave already running
- // with flags that conflict (e.g., work_dir).
-
- Slave slave;
-
- // TODO(benh): Create a work directory for each slave.
-
- slave.slave = new slave::Slave(flags, true, isolator, &cluster->files);
-
- process::PID<slave::Slave> pid = process::spawn(slave.slave);
-
- // Get a detector for the master(s).
- slave.detector = masters->detector(pid, flags.quiet);
-
- slaves[pid] = slave;
-
- return pid;
-}
-
-
-inline Try<process::PID<slave::Slave> > Cluster::Slaves::start(
- const slave::Flags& flags,
- slave::Isolator* isolator)
+ slave::Isolator* isolator,
+ const slave::Flags& flags)
{
- // TODO(benh): Check that we dont have another slave already running
- // with flags that conflict (e.g., work_dir).
+ // TODO(benh): Create a work directory if using the default.
Slave slave;
- // TODO(benh): Create a work directory for each slave.
-
slave.slave = new slave::Slave(flags, true, isolator, &cluster->files);
-
process::PID<slave::Slave> pid = process::spawn(slave.slave);
// Get a detector for the master(s).
- slave.detector = masters->detector(pid, flags.quiet);
+ slave.detector = masters->detector(pid, flags);
slaves[pid] = slave;
@@ -525,7 +369,8 @@ inline Try<process::PID<slave::Slave> > Cluster::Slaves::start(
inline Try<Nothing> Cluster::Slaves::stop(
- const process::PID<slave::Slave>& pid)
+ const process::PID<slave::Slave>& pid,
+ bool shutdown)
{
if (slaves.count(pid) == 0) {
return Error("No slave found to stop");
@@ -533,17 +378,15 @@ inline Try<Nothing> Cluster::Slaves::stop(
Slave slave = slaves[pid];
- process::terminate(slave.slave);
+ if (shutdown) {
+ process::dispatch(slave.slave, &slave::Slave::shutdown);
+ } else {
+ process::terminate(slave.slave);
+ }
process::wait(slave.slave);
delete slave.slave;
- if (slave.isolator != NULL) {
- // TODO(benh): Terminate and wait for the isolator once the slave
- // is no longer doing so.
- // process::terminate(slave.isolator);
- // process::wait(slave.isolator);
- delete slave.isolator;
- }
+ delete slave.isolator; // May be NULL.
slaves.erase(pid);
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/configurator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/configurator_tests.cpp b/src/tests/configurator_tests.cpp
index e8ba936..b82f5c2 100644
--- a/src/tests/configurator_tests.cpp
+++ b/src/tests/configurator_tests.cpp
@@ -18,17 +18,13 @@
#include <gtest/gtest.h>
-#include <fstream>
-
-#include <boost/lexical_cast.hpp>
+#include <stout/gtest.hpp>
+#include <stout/os.hpp>
#include "configurator/configurator.hpp"
#include "tests/utils.hpp"
-using boost::lexical_cast;
-
-using std::ofstream;
using std::string;
using namespace mesos;
@@ -36,9 +32,7 @@ using namespace mesos::internal;
using namespace mesos::internal::tests;
-class ConfiguratorTest : public TemporaryDirectoryTest
-{
-};
+class ConfiguratorTest : public TemporaryDirectoryTest {};
TEST_F(ConfiguratorTest, Environment)
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/exception_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/exception_tests.cpp b/src/tests/exception_tests.cpp
index 911e786..60bb690 100644
--- a/src/tests/exception_tests.cpp
+++ b/src/tests/exception_tests.cpp
@@ -22,17 +22,14 @@
#include <mesos/scheduler.hpp>
#include <process/gmock.hpp>
-
-#include "detector/detector.hpp"
+#include <process/pid.hpp>
+#include <process/process.hpp>
#include "local/local.hpp"
#include "master/master.hpp"
-#include "slave/process_isolator.hpp"
-#include "slave/slave.hpp"
-
-#include "tests/utils.hpp"
+#include "tests/mesos.hpp"
using namespace mesos;
using namespace mesos::internal;
@@ -40,8 +37,6 @@ using namespace mesos::internal::tests;
using mesos::internal::master::Master;
-using mesos::internal::slave::Slave;
-
using process::Future;
using process::PID;
@@ -50,14 +45,9 @@ using std::map;
using std::vector;
using testing::_;
-using testing::AnyOf;
using testing::AtMost;
-using testing::DoAll;
-using testing::ElementsAre;
using testing::Eq;
-using testing::Not;
using testing::Return;
-using testing::SaveArg;
TEST(ExceptionTest, DeactivateFrameworkOnAbort)
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/fault_tolerance_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/fault_tolerance_tests.cpp b/src/tests/fault_tolerance_tests.cpp
index bcfe5db..e41a044 100644
--- a/src/tests/fault_tolerance_tests.cpp
+++ b/src/tests/fault_tolerance_tests.cpp
@@ -38,26 +38,21 @@
#include "common/protobuf_utils.hpp"
-#include "detector/detector.hpp"
-
#include "local/local.hpp"
-#include "master/allocator.hpp"
-#include "master/hierarchical_allocator_process.hpp"
#include "master/master.hpp"
#include "slave/isolator.hpp"
#include "slave/slave.hpp"
-#include "tests/utils.hpp"
+#include "tests/isolator.hpp"
+#include "tests/mesos.hpp"
using namespace mesos;
using namespace mesos::internal;
using namespace mesos::internal::protobuf;
using namespace mesos::internal::tests;
-using mesos::internal::master::Allocator;
-using mesos::internal::master::HierarchicalDRFAllocatorProcess;
using mesos::internal::master::Master;
using mesos::internal::slave::Isolator;
@@ -92,21 +87,14 @@ class FaultToleranceTest : public MesosTest {};
// its offer(s) is rescinded.
TEST_F(FaultToleranceTest, SlaveLost)
{
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
-
- TestingIsolator isolator;
-
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&driver, _, _));
@@ -128,7 +116,7 @@ TEST_F(FaultToleranceTest, SlaveLost)
EXPECT_CALL(sched, slaveLost(&driver, offers.get()[0].slave_id()))
.WillOnce(FutureSatisfy(&slaveLost));
- process::terminate(slave);
+ ShutdownSlaves();
AWAIT_READY(offerRescinded);
AWAIT_READY(slaveLost);
@@ -136,10 +124,7 @@ TEST_F(FaultToleranceTest, SlaveLost)
driver.stop();
driver.join();
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ Shutdown();
}
@@ -206,9 +191,6 @@ TEST_F(FaultToleranceTest, PartitionedSlave)
}
-// TODO(bmahler): Remove this when all the tests are refactored.
-class FaultToleranceClusterTest : public MesosClusterTest {};
-
// The purpose of this test is to ensure that when slaves are removed
// from the master, and then attempt to re-register, we deny the
// re-registration by sending a ShutdownMessage to the slave.
@@ -218,9 +200,9 @@ class FaultToleranceClusterTest : public MesosClusterTest {};
// re-register with its running tasks. We've already notified
// frameworks that these tasks were LOST, so we have to have the slave
// slave shut down.
-TEST_F(FaultToleranceClusterTest, PartitionedSlaveReregistration)
+TEST_F(FaultToleranceTest, PartitionedSlaveReregistration)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
// Allow the master to PING the slave, but drop all PONG messages
@@ -230,8 +212,9 @@ TEST_F(FaultToleranceClusterTest, PartitionedSlaveReregistration)
Future<Message> ping = FUTURE_MESSAGE(Eq("PING"), _, _);
DROP_MESSAGES(Eq("PONG"), _, _);
- MockExecutor exec;
- Try<PID<Slave> > slave = cluster.slaves.start(DEFAULT_EXECUTOR_ID, &exec);
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+
+ Try<PID<Slave> > slave = StartSlave(&exec);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -355,7 +338,7 @@ TEST_F(FaultToleranceClusterTest, PartitionedSlaveReregistration)
driver.stop();
driver.join();
- cluster.shutdown();
+ Shutdown();
}
@@ -367,9 +350,9 @@ TEST_F(FaultToleranceClusterTest, PartitionedSlaveReregistration)
// the slave may attempt to send updates if it was unaware that the
// master deactivated it. We've already notified frameworks that these
// tasks were LOST, so we have to have the slave shut down.
-TEST_F(FaultToleranceClusterTest, PartitionedSlaveStatusUpdates)
+TEST_F(FaultToleranceTest, PartitionedSlaveStatusUpdates)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
// Allow the master to PING the slave, but drop all PONG messages
@@ -382,8 +365,9 @@ TEST_F(FaultToleranceClusterTest, PartitionedSlaveStatusUpdates)
Future<SlaveRegisteredMessage> slaveRegisteredMessage =
FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _);
- MockExecutor exec;
- Try<PID<Slave> > slave = cluster.slaves.start(DEFAULT_EXECUTOR_ID, &exec);
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+
+ Try<PID<Slave> > slave = StartSlave(&exec);
ASSERT_SOME(slave);
AWAIT_READY(slaveRegisteredMessage);
@@ -466,7 +450,7 @@ TEST_F(FaultToleranceClusterTest, PartitionedSlaveStatusUpdates)
driver.stop();
driver.join();
- cluster.shutdown();
+ Shutdown();
}
@@ -479,9 +463,9 @@ TEST_F(FaultToleranceClusterTest, PartitionedSlaveStatusUpdates)
// it was unaware that the master deactivated it. We've already
// notified frameworks that the tasks under the executors were LOST,
// so we have to have the slave shut down.
-TEST_F(FaultToleranceClusterTest, PartitionedSlaveExitedExecutor)
+TEST_F(FaultToleranceTest, PartitionedSlaveExitedExecutor)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
// Allow the master to PING the slave, but drop all PONG messages
@@ -491,10 +475,10 @@ TEST_F(FaultToleranceClusterTest, PartitionedSlaveExitedExecutor)
Future<Message> ping = FUTURE_MESSAGE(Eq("PING"), _, _);
DROP_MESSAGES(Eq("PONG"), _, _);
- MockExecutor exec;
- TestingIsolator* isolator = new TestingIsolator(DEFAULT_EXECUTOR_ID, &exec);
- process::spawn(isolator);
- Try<PID<Slave> > slave = cluster.slaves.start(isolator);
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+ TestingIsolator isolator(&exec);
+
+ Try<PID<Slave> > slave = StartSlave(&isolator);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -602,21 +586,15 @@ TEST_F(FaultToleranceClusterTest, PartitionedSlaveExitedExecutor)
driver.stop();
driver.join();
- cluster.shutdown();
-
- // TODO(benh): Terminate and wait for the isolator once the slave
- // is no longer doing so.
- // process::terminate(isolator);
- // process::wait(isolator);
- delete isolator;
+ Shutdown();
}
// This test ensures that a framework connecting with a
// failed over master gets a re-registered callback.
-TEST_F(FaultToleranceClusterTest, MasterFailover)
+TEST_F(FaultToleranceTest, MasterFailover)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
MockScheduler sched;
@@ -632,10 +610,12 @@ TEST_F(FaultToleranceClusterTest, MasterFailover)
AWAIT_READY(frameworkRegisteredMessage);
// Simulate failed over master by restarting the master.
- ASSERT_SOME(cluster.masters.stop(master.get()));
- master = cluster.masters.start();
+ Stop(master.get());
+ master = StartMaster();
ASSERT_SOME(master);
+ EXPECT_CALL(sched, disconnected(&driver));
+
Future<Nothing> reregistered;
EXPECT_CALL(sched, reregistered(&driver, _))
.WillOnce(FutureSatisfy(&reregistered));
@@ -652,7 +632,7 @@ TEST_F(FaultToleranceClusterTest, MasterFailover)
driver.stop();
driver.join();
- cluster.shutdown();
+ Shutdown();
}
@@ -818,21 +798,14 @@ TEST_F(FaultToleranceTest, FrameworkReregister)
TEST_F(FaultToleranceTest, TaskLost)
{
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
-
- TestingIsolator isolator;
-
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&driver, _, _));
@@ -882,11 +855,7 @@ TEST_F(FaultToleranceTest, TaskLost)
driver.stop();
driver.join();
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ Shutdown();
}
@@ -896,23 +865,17 @@ TEST_F(FaultToleranceTest, SchedulerFailoverStatusUpdate)
{
Clock::pause();
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
-
- MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = StartSlave(&exec);
+ ASSERT_SOME(slave);
// Launch the first (i.e., failing) scheduler.
MockScheduler sched1;
- MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master.get());
FrameworkID frameworkId;
EXPECT_CALL(sched1, registered(&driver1, _, _))
@@ -948,7 +911,7 @@ TEST_F(FaultToleranceTest, SchedulerFailoverStatusUpdate)
// Drop the first status update message
// between master and the scheduler.
Future<StatusUpdateMessage> statusUpdateMessage =
- DROP_PROTOBUF(StatusUpdateMessage(), _, Not(AnyOf(Eq(master), Eq(slave))));
+ DROP_PROTOBUF(StatusUpdateMessage(), _, Not(AnyOf(Eq(master.get()), Eq(slave.get()))));
driver1.launchTasks(offers.get()[0].id(), tasks);
@@ -964,7 +927,7 @@ TEST_F(FaultToleranceTest, SchedulerFailoverStatusUpdate)
framework2 = DEFAULT_FRAMEWORK_INFO;
framework2.mutable_id()->MergeFrom(frameworkId);
- MesosSchedulerDriver driver2(&sched2, framework2, master);
+ MesosSchedulerDriver driver2(&sched2, framework2, master.get());
Future<Nothing> registered2;
EXPECT_CALL(sched2, registered(&driver2, frameworkId, _))
@@ -999,11 +962,7 @@ TEST_F(FaultToleranceTest, SchedulerFailoverStatusUpdate)
AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ Shutdown();
Clock::resume();
}
@@ -1011,22 +970,16 @@ TEST_F(FaultToleranceTest, SchedulerFailoverStatusUpdate)
TEST_F(FaultToleranceTest, ForwardStatusUpdateUnknownExecutor)
{
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
-
- MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = StartSlave(&exec);
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
FrameworkID frameworkId;
EXPECT_CALL(sched, registered(&driver, _, _))
@@ -1078,7 +1031,7 @@ TEST_F(FaultToleranceTest, ForwardStatusUpdateUnknownExecutor)
StatusUpdate statusUpdate2 = createStatusUpdate(
frameworkId, offer.slave_id(), taskId, TASK_RUNNING, "Dummy update");
- process::dispatch(slave, &Slave::statusUpdate, statusUpdate2);
+ process::dispatch(slave.get(), &Slave::statusUpdate, statusUpdate2);
// Ensure that the scheduler receives task2's update.
AWAIT_READY(status);
@@ -1094,32 +1047,22 @@ TEST_F(FaultToleranceTest, ForwardStatusUpdateUnknownExecutor)
AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ Shutdown();
}
TEST_F(FaultToleranceTest, SchedulerFailoverFrameworkMessage)
{
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
-
- MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = StartSlave(&exec);
+ ASSERT_SOME(slave);
MockScheduler sched1;
- MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master.get());
FrameworkID frameworkId;
EXPECT_CALL(sched1, registered(&driver1, _, _))
@@ -1167,7 +1110,7 @@ TEST_F(FaultToleranceTest, SchedulerFailoverFrameworkMessage)
framework2 = DEFAULT_FRAMEWORK_INFO;
framework2.mutable_id()->MergeFrom(frameworkId);
- MesosSchedulerDriver driver2(&sched2, framework2, master);
+ MesosSchedulerDriver driver2(&sched2, framework2, master.get());
Future<Nothing> registered;
EXPECT_CALL(sched2, registered(&driver2, frameworkId, _))
@@ -1199,34 +1142,23 @@ TEST_F(FaultToleranceTest, SchedulerFailoverFrameworkMessage)
AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ Shutdown();
}
// This test checks that a scheduler exit shuts down the executor.
TEST_F(FaultToleranceTest, SchedulerExit)
{
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
-
- MockExecutor exec;
-
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = StartSlave(&exec);
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&driver, _, _));
@@ -1275,11 +1207,7 @@ TEST_F(FaultToleranceTest, SchedulerExit)
AWAIT_READY(shutdown);
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ Shutdown();
}
@@ -1287,25 +1215,18 @@ TEST_F(FaultToleranceTest, SlaveReliableRegistration)
{
Clock::pause();
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
-
- TestingIsolator isolator;
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
// Drop the first slave registered message, allow subsequent messages.
Future<SlaveRegisteredMessage> slaveRegisteredMessage =
DROP_PROTOBUF(SlaveRegisteredMessage(), _, _);
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
-
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&driver, _, _));
@@ -1325,11 +1246,7 @@ TEST_F(FaultToleranceTest, SlaveReliableRegistration)
driver.stop();
driver.join();
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ Shutdown();
Clock::resume();
}
@@ -1337,21 +1254,14 @@ TEST_F(FaultToleranceTest, SlaveReliableRegistration)
TEST_F(FaultToleranceTest, SlaveReregisterOnZKExpiration)
{
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
-
- TestingIsolator isolator;
-
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&driver, _, _));
@@ -1371,44 +1281,32 @@ TEST_F(FaultToleranceTest, SlaveReregisterOnZKExpiration)
// expiration) at the slave.
NewMasterDetectedMessage message;
- message.set_pid(master);
+ message.set_pid(master.get());
- process::post(slave, message);
+ process::post(slave.get(), message);
AWAIT_READY(slaveReregisteredMessage);
driver.stop();
driver.join();
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ Shutdown();
}
// This test verifies that the master sends TASK_LOST updates
// for tasks in the master absent from the re-registered slave.
// We do this by dropping RunTaskMessage from master to the slave.
-// TODO(vinod): Use 'Cluster' abstraction.
TEST_F(FaultToleranceTest, ConsolidateTasksOnSlaveReregistration)
{
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
-
- TestingIsolator isolator;
-
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&driver, _, _));
@@ -1435,14 +1333,15 @@ TEST_F(FaultToleranceTest, ConsolidateTasksOnSlaveReregistration)
// We now launch a task and drop the corresponding RunTaskMessage on
// the slave, to ensure that only the master knows about this task.
- Future<RunTaskMessage> runTaskMessage = DROP_PROTOBUF(RunTaskMessage(), _, _);
+ Future<RunTaskMessage> runTaskMessage =
+ DROP_PROTOBUF(RunTaskMessage(), _, _);
driver.launchTasks(offers.get()[0].id(), tasks);
AWAIT_READY(runTaskMessage);
Future<SlaveReregisteredMessage> slaveReregisteredMessage =
- FUTURE_PROTOBUF(SlaveReregisteredMessage(), _, _);
+ FUTURE_PROTOBUF(SlaveReregisteredMessage(), _, _);
Future<TaskStatus> status;
EXPECT_CALL(sched, statusUpdate(&driver, _))
@@ -1452,9 +1351,9 @@ TEST_F(FaultToleranceTest, ConsolidateTasksOnSlaveReregistration)
// expiration) at the slave to force re-registration.
NewMasterDetectedMessage message;
- message.set_pid(master);
+ message.set_pid(master.get());
- process::post(slave, message);
+ process::post(slave.get(), message);
AWAIT_READY(slaveReregisteredMessage);
@@ -1466,9 +1365,5 @@ TEST_F(FaultToleranceTest, ConsolidateTasksOnSlaveReregistration)
driver.stop();
driver.join();
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ Shutdown();
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/files_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/files_tests.cpp b/src/tests/files_tests.cpp
index 5679ecd..a696aa2 100644
--- a/src/tests/files_tests.cpp
+++ b/src/tests/files_tests.cpp
@@ -21,10 +21,12 @@
#include <gmock/gmock.h>
#include <process/future.hpp>
+#include <process/gtest.hpp>
#include <process/http.hpp>
#include <process/pid.hpp>
#include <process/process.hpp>
+#include <stout/gtest.hpp>
#include <stout/json.hpp>
#include <stout/os.hpp>
#include <stout/stringify.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/flags_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/flags_tests.cpp b/src/tests/flags_tests.cpp
index e07dbcc..d52d4db 100644
--- a/src/tests/flags_tests.cpp
+++ b/src/tests/flags_tests.cpp
@@ -23,6 +23,7 @@
#include <string>
#include <stout/duration.hpp>
+#include <stout/gtest.hpp>
#include <stout/none.hpp>
#include <stout/option.hpp>
@@ -31,8 +32,6 @@
#include "flags/flags.hpp"
-#include "tests/utils.hpp"
-
using namespace flags;
class TestFlags : public virtual FlagsBase
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/gc_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/gc_tests.cpp b/src/tests/gc_tests.cpp
index 949678c..43c3e5d 100644
--- a/src/tests/gc_tests.cpp
+++ b/src/tests/gc_tests.cpp
@@ -55,6 +55,8 @@
#include "slave/paths.hpp"
#include "slave/slave.hpp"
+#include "tests/isolator.hpp"
+#include "tests/mesos.hpp"
#include "tests/utils.hpp"
using namespace mesos;
@@ -248,20 +250,24 @@ TEST_F(GarbageCollectorTest, Prune)
}
-class GarbageCollectorIntegrationTest : public MesosClusterTest {};
+class GarbageCollectorIntegrationTest : public MesosTest {};
TEST_F(GarbageCollectorIntegrationTest, Restart)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
Future<SlaveRegisteredMessage> slaveRegisteredMessage =
FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- Try<PID<Slave> > slave = cluster.slaves.start(DEFAULT_EXECUTOR_ID, &exec);
+ // Need to create our own flags because we want to reuse them when
+ // we (re)start the slave below.
+ slave::Flags flags = CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = StartSlave(&exec, flags);
ASSERT_SOME(slave);
AWAIT_READY(slaveRegisteredMessage);
@@ -272,7 +278,7 @@ TEST_F(GarbageCollectorIntegrationTest, Restart)
EXPECT_CALL(sched, registered(_, _, _))
.Times(1);
- Resources resources = Resources::parse(cluster.slaves.flags.resources.get());
+ Resources resources = Resources::parse(flags.resources.get());
double cpus = resources.get("cpus", Value::Scalar()).value();
double mem = resources.get("mem", Value::Scalar()).value();
@@ -300,7 +306,7 @@ TEST_F(GarbageCollectorIntegrationTest, Restart)
// until the task is launched. We get the slave ID from the
// SlaveRegisteredMessage.
const std::string& slaveDir = slave::paths::getSlavePath(
- cluster.slaves.flags.work_dir,
+ flags.work_dir,
slaveRegisteredMessage.get().slave_id());
ASSERT_TRUE(os::exists(slaveDir));
@@ -318,7 +324,7 @@ TEST_F(GarbageCollectorIntegrationTest, Restart)
EXPECT_CALL(sched, slaveLost(_, _))
.WillOnce(FutureSatisfy(&slaveLost));
- cluster.slaves.stop(slave.get());
+ Stop(slave.get());
AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
@@ -327,14 +333,14 @@ TEST_F(GarbageCollectorIntegrationTest, Restart)
Future<Nothing> schedule =
FUTURE_DISPATCH(_, &GarbageCollectorProcess::schedule);
- slave = cluster.slaves.start();
+ slave = StartSlave(flags);
ASSERT_SOME(slave);
AWAIT_READY(schedule);
Clock::settle(); // Wait for GarbageCollectorProcess::schedule to complete.
- Clock::advance(cluster.slaves.flags.gc_delay);
+ Clock::advance(flags.gc_delay);
Clock::settle();
@@ -346,21 +352,23 @@ TEST_F(GarbageCollectorIntegrationTest, Restart)
driver.stop();
driver.join();
- cluster.shutdown();
+ Shutdown();
}
TEST_F(GarbageCollectorIntegrationTest, ExitedFramework)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
Future<SlaveRegisteredMessage> slaveRegisteredMessage =
FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+
+ slave::Flags flags = CreateSlaveFlags();
- Try<PID<Slave> > slave = cluster.slaves.start(DEFAULT_EXECUTOR_ID, &exec);
+ Try<PID<Slave> > slave = StartSlave(&exec, flags);
ASSERT_SOME(slave);
AWAIT_READY(slaveRegisteredMessage);
@@ -374,7 +382,7 @@ TEST_F(GarbageCollectorIntegrationTest, ExitedFramework)
EXPECT_CALL(sched, registered(_, _, _))
.WillOnce(SaveArg<1>(&frameworkId));
- Resources resources = Resources::parse(cluster.slaves.flags.resources.get());
+ Resources resources = Resources::parse(flags.resources.get());
double cpus = resources.get("cpus", Value::Scalar()).value();
double mem = resources.get("mem", Value::Scalar()).value();
@@ -418,7 +426,7 @@ TEST_F(GarbageCollectorIntegrationTest, ExitedFramework)
FUTURE_DISPATCH(_, &GarbageCollectorProcess::schedule);
// Advance clock to kill executor via isolator.
- Clock::advance(cluster.slaves.flags.executor_shutdown_grace_period);
+ Clock::advance(flags.executor_shutdown_grace_period);
Clock::settle();
@@ -426,13 +434,13 @@ TEST_F(GarbageCollectorIntegrationTest, ExitedFramework)
Clock::settle(); // Wait for GarbageCollectorProcess::schedule to complete.
- Clock::advance(cluster.slaves.flags.gc_delay);
+ Clock::advance(flags.gc_delay);
Clock::settle();
// Framework's directory should be gc'ed by now.
const string& frameworkDir = slave::paths::getFrameworkPath(
- cluster.slaves.flags.work_dir, slaveId, frameworkId);
+ flags.work_dir, slaveId, frameworkId);
ASSERT_FALSE(os::exists(frameworkDir));
@@ -443,20 +451,22 @@ TEST_F(GarbageCollectorIntegrationTest, ExitedFramework)
Clock::resume();
- cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
+ Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
TEST_F(GarbageCollectorIntegrationTest, ExitedExecutor)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+
+ TestingIsolator isolator(&exec);
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
+ slave::Flags flags = CreateSlaveFlags();
- Try<PID<Slave> > slave = cluster.slaves.start(&isolator);
+ Try<PID<Slave> > slave = StartSlave(&isolator);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -466,7 +476,7 @@ TEST_F(GarbageCollectorIntegrationTest, ExitedExecutor)
EXPECT_CALL(sched, registered(_, _, _))
.WillOnce(FutureArg<1>(&frameworkId));
- Resources resources = Resources::parse(cluster.slaves.flags.resources.get());
+ Resources resources = Resources::parse(flags.resources.get());
double cpus = resources.get("cpus", Value::Scalar()).value();
double mem = resources.get("mem", Value::Scalar()).value();
@@ -518,7 +528,7 @@ TEST_F(GarbageCollectorIntegrationTest, ExitedExecutor)
Clock::settle(); // Wait for GarbageCollectorProcess::schedule to complete.
- Clock::advance(cluster.slaves.flags.gc_delay);
+ Clock::advance(flags.gc_delay);
Clock::settle();
@@ -533,20 +543,22 @@ TEST_F(GarbageCollectorIntegrationTest, ExitedExecutor)
driver.stop();
driver.join();
- cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
+ Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
TEST_F(GarbageCollectorIntegrationTest, DiskUsage)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
+ TestingIsolator isolator(&exec);
- Try<PID<Slave> > slave = cluster.slaves.start(&isolator);
+ slave::Flags flags = CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = StartSlave(&isolator, flags);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -556,7 +568,7 @@ TEST_F(GarbageCollectorIntegrationTest, DiskUsage)
EXPECT_CALL(sched, registered(_, _, _))
.WillOnce(FutureArg<1>(&frameworkId));
- Resources resources = Resources::parse(cluster.slaves.flags.resources.get());
+ Resources resources = Resources::parse(flags.resources.get());
double cpus = resources.get("cpus", Value::Scalar()).value();
double mem = resources.get("mem", Value::Scalar()).value();
@@ -632,7 +644,7 @@ TEST_F(GarbageCollectorIntegrationTest, DiskUsage)
driver.stop();
driver.join();
- cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
+ Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
@@ -641,17 +653,19 @@ TEST_F(GarbageCollectorIntegrationTest, DiskUsage)
// created by an old executor (with the same id).
TEST_F(GarbageCollectorIntegrationTest, Unschedule)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
Future<SlaveRegisteredMessage> slaveRegistered =
FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+
+ TestingIsolator isolator(&exec);
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
+ slave::Flags flags = CreateSlaveFlags();
- Try<PID<Slave> > slave = cluster.slaves.start(&isolator);
+ Try<PID<Slave> > slave = StartSlave(&isolator, flags);
ASSERT_SOME(slave);
AWAIT_READY(slaveRegistered);
@@ -663,7 +677,7 @@ TEST_F(GarbageCollectorIntegrationTest, Unschedule)
EXPECT_CALL(sched, registered(_, _, _))
.WillOnce(FutureArg<1>(&frameworkId));
- Resources resources = Resources::parse(cluster.slaves.flags.resources.get());
+ Resources resources = Resources::parse(flags.resources.get());
double cpus = resources.get("cpus", Value::Scalar()).value();
double mem = resources.get("mem", Value::Scalar()).value();
@@ -755,5 +769,5 @@ TEST_F(GarbageCollectorIntegrationTest, Unschedule)
driver.stop();
driver.join();
- cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
+ Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/group_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/group_tests.cpp b/src/tests/group_tests.cpp
index d32b74f..c7f789c 100644
--- a/src/tests/group_tests.cpp
+++ b/src/tests/group_tests.cpp
@@ -23,10 +23,11 @@
#include <string>
#include <process/future.hpp>
+#include <process/gtest.hpp>
+#include <stout/gtest.hpp>
#include <stout/option.hpp>
-#include "tests/utils.hpp"
#include "tests/zookeeper.hpp"
#include "zookeeper/authentication.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/isolator.hpp
----------------------------------------------------------------------
diff --git a/src/tests/isolator.hpp b/src/tests/isolator.hpp
index 17dc7b3..ebfc485 100644
--- a/src/tests/isolator.hpp
+++ b/src/tests/isolator.hpp
@@ -26,6 +26,7 @@
#include <process/future.hpp>
#include <process/pid.hpp>
+#include <stout/os.hpp>
#include <stout/try.hpp>
#include <stout/uuid.hpp>
@@ -34,6 +35,8 @@
#include "slave/isolator.hpp"
+#include "tests/mesos.hpp" // For MockExecutor.
+
namespace mesos {
namespace internal {
namespace tests {
@@ -58,6 +61,12 @@ public:
setup();
}
+ TestingIsolator(MockExecutor* executor)
+ {
+ executors[executor->id] = executor;
+ setup();
+ }
+
virtual ~TestingIsolator() {}
virtual void initialize(
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/isolator_tests.cpp b/src/tests/isolator_tests.cpp
index 4715fb7..aae8b2f 100644
--- a/src/tests/isolator_tests.cpp
+++ b/src/tests/isolator_tests.cpp
@@ -32,9 +32,6 @@
#include "detector/detector.hpp"
-#include "master/allocator.hpp"
-#include "master/flags.hpp"
-#include "master/hierarchical_allocator_process.hpp"
#include "master/master.hpp"
#include "slave/flags.hpp"
@@ -44,7 +41,7 @@
#include "slave/process_isolator.hpp"
#include "slave/slave.hpp"
-#include "tests/utils.hpp"
+#include "tests/mesos.hpp"
using namespace mesos;
using namespace mesos::internal;
@@ -52,8 +49,6 @@ using namespace mesos::internal::tests;
using namespace process;
-using mesos::internal::master::Allocator;
-using mesos::internal::master::HierarchicalDRFAllocatorProcess;
using mesos::internal::master::Master;
#ifdef __linux__
@@ -80,6 +75,7 @@ typedef ::testing::Types<ProcessIsolator> IsolatorTypes;
TYPED_TEST_CASE(IsolatorTest, IsolatorTypes);
+
// TODO(bmahler): This test is disabled on OSX, until proc::children
// is implemented for OSX.
#ifdef __APPLE__
@@ -88,20 +84,18 @@ TYPED_TEST(IsolatorTest, DISABLED_Usage)
TYPED_TEST(IsolatorTest, Usage)
#endif
{
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
+ Try<PID<Master> > master = this->StartMaster();
+ ASSERT_SOME(master);
TypeParam isolator;
- Slave s(this->slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
- BasicMasterDetector detector(master, slave, true);
+ slave::Flags flags = this->CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = this->StartSlave(&isolator, flags);
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
Future<FrameworkID> frameworkId;
EXPECT_CALL(sched, registered(&driver, _, _))
@@ -112,11 +106,6 @@ TYPED_TEST(IsolatorTest, Usage)
.WillOnce(FutureArg<1>(&offers))
.WillRepeatedly(Return()); // Ignore subsequent offers.
- Future<TaskStatus> status1, status2;
- EXPECT_CALL(sched, statusUpdate(&driver, _))
- .WillOnce(FutureArg<1>(&status1))
- .WillOnce(FutureArg<1>(&status2));
-
driver.start();
AWAIT_READY(frameworkId);
@@ -130,7 +119,7 @@ TYPED_TEST(IsolatorTest, Usage)
task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id());
task.mutable_resources()->MergeFrom(offers.get()[0].resources());
- const std::string& file = path::join(this->slaveFlags.work_dir, "ready");
+ const std::string& file = path::join(flags.work_dir, "ready");
// This task induces user/system load in a child process by
// running top in a child process for ten seconds.
@@ -148,11 +137,15 @@ TYPED_TEST(IsolatorTest, Usage)
vector<TaskInfo> tasks;
tasks.push_back(task);
+ Future<TaskStatus> status;
+ EXPECT_CALL(sched, statusUpdate(&driver, _))
+ .WillOnce(FutureArg<1>(&status));
+
driver.launchTasks(offers.get()[0].id(), tasks);
- AWAIT_READY(status1);
+ AWAIT_READY(status);
- EXPECT_EQ(TASK_RUNNING, status1.get().state());
+ EXPECT_EQ(TASK_RUNNING, status.get().state());
// Wait for the task to begin inducing cpu time.
while (!os::exists(file));
@@ -167,8 +160,12 @@ TYPED_TEST(IsolatorTest, Usage)
ResourceStatistics statistics;
Duration waited = Duration::zero();
do {
- const Future<ResourceStatistics>& usage =
- isolator.usage(frameworkId.get(), executorId);
+ Future<ResourceStatistics> usage =
+ process::dispatch(
+ (Isolator*) &isolator, // TODO(benh): Fix after reaper changes.
+ &Isolator::usage,
+ frameworkId.get(),
+ executorId);
AWAIT_READY(usage);
@@ -182,27 +179,26 @@ TYPED_TEST(IsolatorTest, Usage)
}
os::sleep(Milliseconds(100));
- waited = waited + Milliseconds(100);
+ waited += Milliseconds(100);
} while (waited < Seconds(10));
EXPECT_GE(statistics.memory_rss(), 1024u);
EXPECT_GE(statistics.cpu_user_time(), 0.125);
EXPECT_GE(statistics.cpu_system_time(), 0.125);
+ EXPECT_CALL(sched, statusUpdate(&driver, _))
+ .WillOnce(FutureArg<1>(&status));
+
driver.killTask(task.task_id());
- AWAIT_READY(status2);
+ AWAIT_READY(status);
// TODO(bmahler): The command executor is buggy in that it does not
// send TASK_KILLED for a non-zero exit code due to a kill.
- EXPECT_EQ(TASK_FAILED, status2.get().state());
+ EXPECT_EQ(TASK_FAILED, status.get().state());
driver.stop();
driver.join();
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ this->Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/log_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/log_tests.cpp b/src/tests/log_tests.cpp
index 208e83e..dbd12b8 100644
--- a/src/tests/log_tests.cpp
+++ b/src/tests/log_tests.cpp
@@ -24,10 +24,12 @@
#include <process/clock.hpp>
#include <process/future.hpp>
#include <process/gmock.hpp>
+#include <process/gtest.hpp>
#include <process/pid.hpp>
#include <process/protobuf.hpp>
#include <process/timeout.hpp>
+#include <stout/gtest.hpp>
#include <stout/option.hpp>
#include <stout/os.hpp>
@@ -39,12 +41,9 @@
#include "messages/messages.hpp"
-#include "tests/utils.hpp"
-
using namespace mesos;
using namespace mesos::internal;
using namespace mesos::internal::log;
-using namespace mesos::internal::tests;
using process::Clock;
using process::Future;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/logging_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/logging_tests.cpp b/src/tests/logging_tests.cpp
index 57eae79..58e9b33 100644
--- a/src/tests/logging_tests.cpp
+++ b/src/tests/logging_tests.cpp
@@ -19,15 +19,14 @@
#include <gmock/gmock.h>
#include <process/future.hpp>
+#include <process/gtest.hpp>
#include <process/http.hpp>
#include <process/pid.hpp>
+#include <process/process.hpp>
#include "logging/logging.hpp"
-#include "tests/utils.hpp"
-
using namespace mesos::internal;
-using namespace mesos::internal::tests;
using process::http::BadRequest;
using process::http::OK;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/main.cpp
----------------------------------------------------------------------
diff --git a/src/tests/main.cpp b/src/tests/main.cpp
index b06c0d1..868bdd5 100644
--- a/src/tests/main.cpp
+++ b/src/tests/main.cpp
@@ -29,9 +29,10 @@
#include "logging/logging.hpp"
+#include "messages/messages.hpp" // For GOOGLE_PROTOBUF_VERIFY_VERSION.
+
#include "tests/environment.hpp"
#include "tests/flags.hpp"
-#include "tests/utils.hpp"
using namespace mesos::internal;
using namespace mesos::internal::tests;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/master_detector_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_detector_tests.cpp b/src/tests/master_detector_tests.cpp
index c9d6d20..57f4e3e 100644
--- a/src/tests/master_detector_tests.cpp
+++ b/src/tests/master_detector_tests.cpp
@@ -48,7 +48,8 @@
#include "slave/slave.hpp"
-#include "tests/utils.hpp"
+#include "tests/isolator.hpp"
+#include "tests/mesos.hpp"
#ifdef MESOS_HAS_JAVA
#include "tests/zookeeper.hpp"
#endif
@@ -75,16 +76,20 @@ using testing::AtMost;
using testing::Return;
-class MasterDetectorTest : public MesosClusterTest {};
+class MasterDetectorTest : public MesosTest {};
TEST_F(MasterDetectorTest, File)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
+ Files files;
TestingIsolator isolator;
- Slave s(cluster.slaves.flags, true, &isolator, &cluster.files);
+
+ slave::Flags flags = CreateSlaveFlags();
+
+ Slave s(flags, true, &isolator, &files);
PID<Slave> slave = process::spawn(&s);
// Write "master" to a file and use the "file://" mechanism to
@@ -92,7 +97,7 @@ TEST_F(MasterDetectorTest, File)
// detector for the master first.
BasicMasterDetector detector1(master.get(), vector<UPID>(), true);
- const string& path = path::join(cluster.slaves.flags.work_dir, "master");
+ const string& path = path::join(flags.work_dir, "master");
ASSERT_SOME(os::write(path, stringify(master.get())));
Try<MasterDetector*> detector =
@@ -119,7 +124,7 @@ TEST_F(MasterDetectorTest, File)
driver.stop();
driver.join();
- cluster.shutdown();
+ Shutdown();
process::terminate(slave);
process::wait(slave);
[17/28] git commit: Removed unnecessary TestingIsolators.
Posted by be...@apache.org.
Removed unnecessary TestingIsolators.
Review: https://reviews.apache.org/r/11276
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/fd981ce6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/fd981ce6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/fd981ce6
Branch: refs/heads/master
Commit: fd981ce6eb5a3fc86a263b9b38a8b7280a4b89b5
Parents: bb18d3b
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sat May 11 10:18:30 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 00:13:41 2013 -0700
----------------------------------------------------------------------
src/tests/allocator_tests.cpp | 32 +++++---------------------------
1 files changed, 5 insertions(+), 27 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/fd981ce6/src/tests/allocator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/allocator_tests.cpp b/src/tests/allocator_tests.cpp
index 7ee71de..e8f833d 100644
--- a/src/tests/allocator_tests.cpp
+++ b/src/tests/allocator_tests.cpp
@@ -34,7 +34,6 @@
#include "master/hierarchical_allocator_process.hpp"
#include "master/master.hpp"
-#include "tests/isolator.hpp"
#include "tests/mesos.hpp"
using namespace mesos;
@@ -561,14 +560,13 @@ TYPED_TEST(AllocatorTest, SchedulerFailover)
ASSERT_SOME(master);
MockExecutor exec(DEFAULT_EXECUTOR_ID);
- TestingIsolator isolator(&exec);
slave::Flags flags = this->CreateSlaveFlags();
flags.resources = Option<string>("cpus:3;mem:1024");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave = this->StartSlave(&isolator, flags);
+ Try<PID<Slave> > slave = this->StartSlave(&exec, flags);
ASSERT_SOME(slave);
FrameworkInfo frameworkInfo1;
@@ -596,9 +594,6 @@ TYPED_TEST(AllocatorTest, SchedulerFailover)
FutureArg<1>(&offers1)))
.WillRepeatedly(DeclineOffers());
- EXPECT_CALL(isolator, resourcesChanged(_, _, _))
- .WillRepeatedly(DoDefault());
-
EXPECT_CALL(exec, registered(_, _, _, _));
Future<Nothing> launchTask;
@@ -701,17 +696,12 @@ TYPED_TEST(AllocatorTest, FrameworkExited)
EXPECT_CALL(exec, shutdown(_))
.Times(AtMost(2));
- TestingIsolator isolator(&exec);
-
slave::Flags flags = this->CreateSlaveFlags();
flags.resources = Option<string>("cpus:3;mem:1024");
- EXPECT_CALL(isolator, resourcesChanged(_, _, _))
- .WillRepeatedly(DoDefault());
-
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave = this->StartSlave(&isolator, flags);
+ Try<PID<Slave> > slave = this->StartSlave(&exec, flags);
ASSERT_SOME(slave);
MockScheduler sched1;
@@ -820,14 +810,13 @@ TYPED_TEST(AllocatorTest, SlaveLost)
ASSERT_SOME(master);
MockExecutor exec(DEFAULT_EXECUTOR_ID);
- TestingIsolator isolator(&exec);
slave::Flags flags1 = this->CreateSlaveFlags();
flags1.resources = Option<string>("cpus:2;mem:1024");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave1 = this->StartSlave(&isolator, flags1);
+ Try<PID<Slave> > slave1 = this->StartSlave(&exec, flags1);
ASSERT_SOME(slave1);
MockScheduler sched1;
@@ -855,9 +844,6 @@ TYPED_TEST(AllocatorTest, SlaveLost)
.WillOnce(DoAll(SendStatusUpdateFromTask(TASK_RUNNING),
FutureSatisfy(&launchTask)));
- EXPECT_CALL(isolator, resourcesChanged(_, _, _))
- .WillRepeatedly(DoDefault());
-
driver1.start();
AWAIT_READY(resourceOffers1);
@@ -948,14 +934,13 @@ TYPED_TEST(AllocatorTest, SlaveAdded)
ASSERT_SOME(master);
MockExecutor exec(DEFAULT_EXECUTOR_ID);
- TestingIsolator isolator(&exec);
slave::Flags flags1 = this->CreateSlaveFlags();
flags1.resources = Option<string>("cpus:3;mem:1024");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave1 = this->StartSlave(&isolator, flags1);
+ Try<PID<Slave> > slave1 = this->StartSlave(&exec, flags1);
ASSERT_SOME(slave1);
MockScheduler sched1;
@@ -992,9 +977,6 @@ TYPED_TEST(AllocatorTest, SlaveAdded)
.WillOnce(DoAll(SendStatusUpdateFromTask(TASK_RUNNING),
FutureSatisfy(&launchTask)));
- EXPECT_CALL(isolator, resourcesChanged(_, _, _))
- .WillRepeatedly(DoDefault());
-
driver1.start();
AWAIT_READY(resourceOffers1);
@@ -1055,14 +1037,13 @@ TYPED_TEST(AllocatorTest, TaskFinished)
ASSERT_SOME(master);
MockExecutor exec(DEFAULT_EXECUTOR_ID);
- TestingIsolator isolator(&exec);
slave::Flags flags = this->CreateSlaveFlags();
flags.resources = Option<string>("cpus:3;mem:1024");
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- Try<PID<Slave> > slave = this->StartSlave(&isolator, flags);
+ Try<PID<Slave> > slave = this->StartSlave(&exec, flags);
ASSERT_SOME(slave);
MockScheduler sched1;
@@ -1107,9 +1088,6 @@ TYPED_TEST(AllocatorTest, TaskFinished)
FutureSatisfy(&launchTask)))
.WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));
- EXPECT_CALL(isolator, resourcesChanged(_, _, _))
- .WillRepeatedly(DoDefault());
-
driver1.start();
AWAIT_READY(resourceOffers1);
[07/28] git commit: Refactored zookeeper_tests.cpp into
master_detector_tests.cpp and group_tests.cpp.
Posted by be...@apache.org.
Refactored zookeeper_tests.cpp into master_detector_tests.cpp and
group_tests.cpp.
Review: https://reviews.apache.org/r/11266
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/0ebf3933
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/0ebf3933
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/0ebf3933
Branch: refs/heads/master
Commit: 0ebf3933b597c1a4cb65cca505cd01fb415517da
Parents: 39ce99e
Author: Benjamin Hindman <be...@twitter.com>
Authored: Thu Apr 25 19:22:22 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Fri May 24 22:05:05 2013 -0700
----------------------------------------------------------------------
src/Makefile.am | 1 +
src/tests/group_tests.cpp | 295 +++++++++++
src/tests/master_detector_tests.cpp | 510 +++++++++++++++++++
src/tests/zookeeper_test.hpp | 31 ++
src/tests/zookeeper_tests.cpp | 796 ------------------------------
5 files changed, 837 insertions(+), 796 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/0ebf3933/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 343a7c5..22346f3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -775,6 +775,7 @@ mesos_tests_SOURCES = tests/main.cpp tests/utils.cpp \
tests/slave_recovery_tests.cpp \
tests/status_update_manager_tests.cpp \
tests/gc_tests.cpp \
+ tests/group_tests.cpp \
tests/resource_offers_tests.cpp \
tests/fault_tolerance_tests.cpp \
tests/files_tests.cpp tests/flags_tests.cpp \
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/0ebf3933/src/tests/group_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/group_tests.cpp b/src/tests/group_tests.cpp
new file mode 100644
index 0000000..3e442cd
--- /dev/null
+++ b/src/tests/group_tests.cpp
@@ -0,0 +1,295 @@
+/**
+ * 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 <zookeeper.h>
+
+#include <gmock/gmock.h>
+
+#include <string>
+
+#include <process/future.hpp>
+
+#include <stout/option.hpp>
+
+#include "tests/utils.hpp"
+#include "tests/zookeeper_test.hpp"
+
+#include "zookeeper/authentication.hpp"
+#include "zookeeper/group.hpp"
+
+using namespace mesos::internal;
+using namespace mesos::internal::tests;
+
+using zookeeper::Group;
+
+using process::Future;
+
+
+class GroupTest : public ZooKeeperTest {};
+
+
+TEST_F(GroupTest, Group)
+{
+ Group group(server->connectString(), NO_TIMEOUT, "/test/");
+
+ Future<Group::Membership> membership = group.join("hello world");
+
+ AWAIT_READY(membership);
+
+ Future<std::set<Group::Membership> > memberships = group.watch();
+
+ AWAIT_READY(memberships);
+ EXPECT_EQ(1u, memberships.get().size());
+ EXPECT_EQ(1u, memberships.get().count(membership.get()));
+
+ Future<std::string> data = group.data(membership.get());
+
+ AWAIT_EXPECT_EQ("hello world", data);
+
+ Future<bool> cancellation = group.cancel(membership.get());
+
+ AWAIT_EXPECT_EQ(true, cancellation);
+
+ memberships = group.watch(memberships.get());
+
+ AWAIT_READY(memberships);
+ EXPECT_EQ(0u, memberships.get().size());
+
+ ASSERT_TRUE(membership.get().cancelled().isReady());
+ ASSERT_TRUE(membership.get().cancelled().get());
+}
+
+
+TEST_F(GroupTest, GroupJoinWithDisconnect)
+{
+ Group group(server->connectString(), NO_TIMEOUT, "/test/");
+
+ server->shutdownNetwork();
+
+ Future<Group::Membership> membership = group.join("hello world");
+
+ EXPECT_TRUE(membership.isPending());
+
+ server->startNetwork();
+
+ AWAIT_READY(membership);
+
+ Future<std::set<Group::Membership> > memberships = group.watch();
+
+ AWAIT_READY(memberships);
+ EXPECT_EQ(1u, memberships.get().size());
+ EXPECT_EQ(1u, memberships.get().count(membership.get()));
+}
+
+
+TEST_F(GroupTest, GroupDataWithDisconnect)
+{
+ Group group(server->connectString(), NO_TIMEOUT, "/test/");
+
+ Future<Group::Membership> membership = group.join("hello world");
+
+ AWAIT_READY(membership);
+
+ Future<std::set<Group::Membership> > memberships = group.watch();
+
+ AWAIT_READY(memberships);
+ EXPECT_EQ(1u, memberships.get().size());
+ EXPECT_EQ(1u, memberships.get().count(membership.get()));
+
+ server->shutdownNetwork();
+
+ Future<std::string> data = group.data(membership.get());
+
+ EXPECT_TRUE(data.isPending());
+
+ server->startNetwork();
+
+ AWAIT_EXPECT_EQ("hello world", data);
+}
+
+
+TEST_F(GroupTest, GroupCancelWithDisconnect)
+{
+ Group group(server->connectString(), NO_TIMEOUT, "/test/");
+
+ Future<Group::Membership> membership = group.join("hello world");
+
+ AWAIT_READY(membership);
+
+ Future<std::set<Group::Membership> > memberships = group.watch();
+
+ AWAIT_READY(memberships);
+ EXPECT_EQ(1u, memberships.get().size());
+ EXPECT_EQ(1u, memberships.get().count(membership.get()));
+
+ Future<std::string> data = group.data(membership.get());
+
+ AWAIT_EXPECT_EQ("hello world", data);
+
+ server->shutdownNetwork();
+
+ Future<bool> cancellation = group.cancel(membership.get());
+
+ EXPECT_TRUE(cancellation.isPending());
+
+ server->startNetwork();
+
+ AWAIT_EXPECT_EQ(true, cancellation);
+
+ memberships = group.watch(memberships.get());
+
+ AWAIT_READY(memberships);
+ EXPECT_EQ(0u, memberships.get().size());
+
+ ASSERT_TRUE(membership.get().cancelled().isReady());
+ ASSERT_TRUE(membership.get().cancelled().get());
+}
+
+
+TEST_F(GroupTest, GroupWatchWithSessionExpiration)
+{
+ Group group(server->connectString(), NO_TIMEOUT, "/test/");
+
+ Future<Group::Membership> membership = group.join("hello world");
+
+ AWAIT_READY(membership);
+
+ Future<std::set<Group::Membership> > memberships = group.watch();
+
+ AWAIT_READY(memberships);
+ EXPECT_EQ(1u, memberships.get().size());
+ EXPECT_EQ(1u, memberships.get().count(membership.get()));
+
+ Future<Option<int64_t> > session = group.session();
+
+ AWAIT_READY(session);
+ ASSERT_SOME(session.get());
+
+ memberships = group.watch(memberships.get());
+
+ server->expireSession(session.get().get());
+
+ AWAIT_READY(memberships);
+ EXPECT_EQ(0u, memberships.get().size());
+
+ ASSERT_TRUE(membership.get().cancelled().isReady());
+ ASSERT_FALSE(membership.get().cancelled().get());
+}
+
+
+TEST_F(GroupTest, MultipleGroups)
+{
+ Group group1(server->connectString(), NO_TIMEOUT, "/test/");
+ Group group2(server->connectString(), NO_TIMEOUT, "/test/");
+
+ Future<Group::Membership> membership1 = group1.join("group 1");
+
+ AWAIT_READY(membership1);
+
+ Future<Group::Membership> membership2 = group2.join("group 2");
+
+ AWAIT_READY(membership2);
+
+ Future<std::set<Group::Membership> > memberships1 = group1.watch();
+
+ AWAIT_READY(memberships1);
+ EXPECT_EQ(2u, memberships1.get().size());
+ EXPECT_EQ(1u, memberships1.get().count(membership1.get()));
+ EXPECT_EQ(1u, memberships1.get().count(membership2.get()));
+
+ Future<std::set<Group::Membership> > memberships2 = group2.watch();
+
+ AWAIT_READY(memberships2);
+ EXPECT_EQ(2u, memberships2.get().size());
+ EXPECT_EQ(1u, memberships2.get().count(membership1.get()));
+ EXPECT_EQ(1u, memberships2.get().count(membership2.get()));
+
+ Future<bool> cancelled;
+
+ // Now watch the membership owned by group1 from group2.
+ foreach (const Group::Membership& membership, memberships2.get()) {
+ if (membership == membership1.get()) {
+ cancelled = membership.cancelled();
+ break;
+ }
+ }
+
+ Future<Option<int64_t> > session1 = group1.session();
+
+ AWAIT_READY(session1);
+ ASSERT_SOME(session1.get());
+
+ server->expireSession(session1.get().get());
+
+ AWAIT_ASSERT_EQ(false, cancelled);
+}
+
+
+TEST_F(GroupTest, GroupPathWithRestrictivePerms)
+{
+ ZooKeeperTest::TestWatcher watcher;
+
+ ZooKeeper authenticatedZk(server->connectString(), NO_TIMEOUT, &watcher);
+ watcher.awaitSessionEvent(ZOO_CONNECTED_STATE);
+
+ authenticatedZk.authenticate("digest", "creator:creator");
+
+ authenticatedZk.create(
+ "/read-only",
+ "42",
+ zookeeper::EVERYONE_READ_CREATOR_ALL,
+ 0,
+ NULL);
+
+ ASSERT_ZK_GET("42", &authenticatedZk, "/read-only");
+
+ authenticatedZk.create(
+ "/read-only/writable",
+ "37",
+ ZOO_OPEN_ACL_UNSAFE,
+ 0,
+ NULL);
+
+ ASSERT_ZK_GET("37", &authenticatedZk, "/read-only/writable");
+
+ zookeeper::Authentication auth("digest", "non-creator:non-creator");
+
+ Group failedGroup1(
+ server->connectString(),
+ NO_TIMEOUT,
+ "/read-only/",
+ auth);
+
+ AWAIT_FAILED(failedGroup1.join("fail"));
+
+ Group failedGroup2(
+ server->connectString(),
+ NO_TIMEOUT,
+ "/read-only/new",
+ auth);
+
+ AWAIT_FAILED(failedGroup2.join("fail"));
+
+ Group successGroup(
+ server->connectString(),
+ NO_TIMEOUT,
+ "/read-only/writable/",
+ auth);
+
+ AWAIT_READY(successGroup.join("succeed"));
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/0ebf3933/src/tests/master_detector_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_detector_tests.cpp b/src/tests/master_detector_tests.cpp
index 3a7b3b4..1739823 100644
--- a/src/tests/master_detector_tests.cpp
+++ b/src/tests/master_detector_tests.cpp
@@ -16,6 +16,8 @@
* limitations under the License.
*/
+#include <zookeeper.h>
+
#include <gmock/gmock.h>
#include <fstream>
@@ -26,9 +28,14 @@
#include <mesos/executor.hpp>
#include <mesos/scheduler.hpp>
+#include <process/clock.hpp>
+#include <process/future.hpp>
#include <process/pid.hpp>
+#include <process/protobuf.hpp>
+#include <stout/duration.hpp>
#include <stout/gtest.hpp>
+#include <stout/nothing.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/try.hpp>
@@ -37,9 +44,14 @@
#include "master/master.hpp"
+#include "messages/messages.hpp"
+
#include "slave/slave.hpp"
#include "tests/utils.hpp"
+#ifdef MESOS_HAS_JAVA
+#include "tests/zookeeper_test.hpp"
+#endif
using namespace mesos;
using namespace mesos::internal;
@@ -49,6 +61,7 @@ using mesos::internal::master::Master;
using mesos::internal::slave::Slave;
+using process::Clock;
using process::Future;
using process::PID;
using process::UPID;
@@ -58,6 +71,8 @@ using std::string;
using std::vector;
using testing::_;
+using testing::AtMost;
+using testing::Return;
class MasterDetectorTest : public MesosClusterTest {};
@@ -109,3 +124,498 @@ TEST_F(MasterDetectorTest, File)
process::terminate(slave);
process::wait(slave);
}
+
+
+class MockMasterDetectorListenerProcess
+ : public ProtobufProcess<MockMasterDetectorListenerProcess>
+{
+public:
+ MockMasterDetectorListenerProcess() {}
+ virtual ~MockMasterDetectorListenerProcess() {}
+
+ MOCK_METHOD1(newMasterDetected, void(const process::UPID&));
+ MOCK_METHOD0(noMasterDetected, void(void));
+
+protected:
+ virtual void initialize()
+ {
+ install<NewMasterDetectedMessage>(
+ &MockMasterDetectorListenerProcess::newMasterDetected,
+ &NewMasterDetectedMessage::pid);
+
+ install<NoMasterDetectedMessage>(
+ &MockMasterDetectorListenerProcess::noMasterDetected);
+ }
+};
+
+
+#ifdef MESOS_HAS_JAVA
+class ZooKeeperMasterDetectorTest : public ZooKeeperTest {};
+
+
+TEST_F(ZooKeeperMasterDetectorTest, MasterDetector)
+{
+ MockMasterDetectorListenerProcess mock;
+ process::spawn(mock);
+
+ Future<Nothing> newMasterDetected;
+ EXPECT_CALL(mock, newMasterDetected(mock.self()))
+ .WillOnce(FutureSatisfy(&newMasterDetected));
+
+ std::string master = "zk://" + server->connectString() + "/mesos";
+
+ Try<MasterDetector*> detector =
+ MasterDetector::create(master, mock.self(), true, true);
+
+ ASSERT_SOME(detector);
+
+ AWAIT_READY(newMasterDetected);
+
+ MasterDetector::destroy(detector.get());
+
+ process::terminate(mock);
+ process::wait(mock);
+}
+
+
+TEST_F(ZooKeeperMasterDetectorTest, MasterDetectors)
+{
+ MockMasterDetectorListenerProcess mock1;
+ process::spawn(mock1);
+
+ Future<Nothing> newMasterDetected1;
+ EXPECT_CALL(mock1, newMasterDetected(mock1.self()))
+ .WillOnce(FutureSatisfy(&newMasterDetected1));
+
+ std::string master = "zk://" + server->connectString() + "/mesos";
+
+ Try<MasterDetector*> detector1 =
+ MasterDetector::create(master, mock1.self(), true, true);
+
+ ASSERT_SOME(detector1);
+
+ AWAIT_READY(newMasterDetected1);
+
+ MockMasterDetectorListenerProcess mock2;
+ process::spawn(mock2);
+
+ Future<Nothing> newMasterDetected2;
+ EXPECT_CALL(mock2, newMasterDetected(mock1.self())) // N.B. mock1
+ .WillOnce(FutureSatisfy(&newMasterDetected2));
+
+ Try<MasterDetector*> detector2 =
+ MasterDetector::create(master, mock2.self(), true, true);
+
+ ASSERT_SOME(detector2);
+
+ AWAIT_READY(newMasterDetected2);
+
+ // Destroying detector1 (below) might cause another election so we
+ // need to set up expectations appropriately.
+ EXPECT_CALL(mock2, newMasterDetected(_))
+ .WillRepeatedly(Return());
+
+ MasterDetector::destroy(detector1.get());
+
+ process::terminate(mock1);
+ process::wait(mock1);
+
+ MasterDetector::destroy(detector2.get());
+
+ process::terminate(mock2);
+ process::wait(mock2);
+}
+
+
+TEST_F(ZooKeeperMasterDetectorTest, MasterDetectorShutdownNetwork)
+{
+ Clock::pause();
+
+ MockMasterDetectorListenerProcess mock;
+ process::spawn(mock);
+
+ Future<Nothing> newMasterDetected1;
+ EXPECT_CALL(mock, newMasterDetected(mock.self()))
+ .WillOnce(FutureSatisfy(&newMasterDetected1));
+
+ std::string master = "zk://" + server->connectString() + "/mesos";
+
+ Try<MasterDetector*> detector =
+ MasterDetector::create(master, mock.self(), true, true);
+
+ ASSERT_SOME(detector);
+
+ AWAIT_READY(newMasterDetected1);
+
+ Future<Nothing> noMasterDetected;
+ EXPECT_CALL(mock, noMasterDetected())
+ .WillOnce(FutureSatisfy(&noMasterDetected));
+
+ server->shutdownNetwork();
+
+ Clock::advance(Seconds(10)); // TODO(benh): Get session timeout from detector.
+
+ AWAIT_READY(noMasterDetected);
+
+ Future<Nothing> newMasterDetected2;
+ EXPECT_CALL(mock, newMasterDetected(mock.self()))
+ .WillOnce(FutureSatisfy(&newMasterDetected2));
+
+ server->startNetwork();
+
+ AWAIT_READY(newMasterDetected2);
+
+ MasterDetector::destroy(detector.get());
+
+ process::terminate(mock);
+ process::wait(mock);
+
+ Clock::resume();
+}
+
+
+// Tests that a detector sends a NoMasterDetectedMessage when we
+// reach our ZooKeeper session timeout. This is to enforce that we
+// manually expire the session when we don't get reconnected within
+// the ZOOKEEPER_SESSION_TIMEOUT.
+TEST_F(ZooKeeperTest, MasterDetectorTimedoutSession)
+{
+ Try<zookeeper::URL> url =
+ zookeeper::URL::parse("zk://" + server->connectString() + "/mesos");
+ ASSERT_SOME(url);
+
+ // First we bring up three master detector listeners:
+ // 1. A leading contender.
+ // 2. A non-leading contender.
+ // 3. A non-contender.
+
+ // 1. Simulate a leading contender.
+ MockMasterDetectorListenerProcess leader;
+
+ Future<Nothing> newMasterDetected;
+ EXPECT_CALL(leader, newMasterDetected(_))
+ .WillOnce(FutureSatisfy(&newMasterDetected));
+
+ process::spawn(leader);
+
+ ZooKeeperMasterDetector leaderDetector(
+ url.get(), leader.self(), true, true);
+
+ AWAIT_READY(newMasterDetected);
+
+ // 2. Simulate a non-leading contender.
+ MockMasterDetectorListenerProcess follower;
+
+ EXPECT_CALL(follower, newMasterDetected(_))
+ .WillOnce(FutureSatisfy(&newMasterDetected));
+
+ process::spawn(follower);
+
+ ZooKeeperMasterDetector followerDetector(
+ url.get(), follower.self(), true, true);
+
+ AWAIT_READY(newMasterDetected);
+
+ // 3. Simulate a non-contender.
+ MockMasterDetectorListenerProcess nonContender;
+
+ EXPECT_CALL(nonContender, newMasterDetected(_))
+ .WillOnce(FutureSatisfy(&newMasterDetected));
+
+ process::spawn(nonContender);
+
+ ZooKeeperMasterDetector nonContenderDetector(
+ url.get(), nonContender.self(), false, true);
+
+ AWAIT_READY(newMasterDetected);
+
+ // Now we want to induce lost connections on each of the
+ // master detectors.
+ // Induce a reconnection on the leader.
+ Future<Nothing> leaderReconnecting = FUTURE_DISPATCH(
+ leaderDetector.process->self(),
+ &ZooKeeperMasterDetectorProcess::reconnecting);
+
+ dispatch(leaderDetector.process,
+ &ZooKeeperMasterDetectorProcess::reconnecting);
+
+ AWAIT_READY(leaderReconnecting);
+
+ // Induce a reconnection on the follower.
+ Future<Nothing> followerReconnecting = FUTURE_DISPATCH(
+ followerDetector.process->self(),
+ &ZooKeeperMasterDetectorProcess::reconnecting);
+
+ dispatch(followerDetector.process,
+ &ZooKeeperMasterDetectorProcess::reconnecting);
+
+ AWAIT_READY(followerReconnecting);
+
+ // Induce a reconnection on the non-contender.
+ Future<Nothing> nonContenderReconnecting = FUTURE_DISPATCH(
+ nonContenderDetector.process->self(),
+ &ZooKeeperMasterDetectorProcess::reconnecting);
+
+ dispatch(nonContenderDetector.process,
+ &ZooKeeperMasterDetectorProcess::reconnecting);
+
+ AWAIT_READY(nonContenderReconnecting);
+
+ // Now induce the reconnection timeout.
+ Future<Nothing> leaderNoMasterDetected;
+ EXPECT_CALL(leader, noMasterDetected())
+ .WillOnce(FutureSatisfy(&leaderNoMasterDetected));
+
+ Future<Nothing> followerNoMasterDetected;
+ EXPECT_CALL(follower, noMasterDetected())
+ .WillOnce(FutureSatisfy(&followerNoMasterDetected));
+
+ Future<Nothing> nonContenderNoMasterDetected;
+ EXPECT_CALL(nonContender, noMasterDetected())
+ .WillOnce(FutureSatisfy(&nonContenderNoMasterDetected));
+
+ Clock::pause();
+ Clock::advance(ZOOKEEPER_SESSION_TIMEOUT);
+ Clock::settle();
+
+ AWAIT_READY(leaderNoMasterDetected);
+ AWAIT_READY(followerNoMasterDetected);
+ AWAIT_READY(nonContenderNoMasterDetected);
+
+ process::terminate(leader);
+ process::wait(leader);
+
+ process::terminate(follower);
+ process::wait(follower);
+
+ process::terminate(nonContender);
+ process::wait(nonContender);
+}
+
+
+// Tests whether a leading master correctly detects a new master when
+// its ZooKeeper session is expired.
+TEST_F(ZooKeeperMasterDetectorTest, MasterDetectorExpireMasterZKSession)
+{
+ // Simulate a leading master.
+ MockMasterDetectorListenerProcess leader;
+
+ Future<Nothing> newMasterDetected1, newMasterDetected2;
+ EXPECT_CALL(leader, newMasterDetected(_))
+ .WillOnce(FutureSatisfy(&newMasterDetected1))
+ .WillOnce(FutureSatisfy(&newMasterDetected2));
+
+ EXPECT_CALL(leader, noMasterDetected())
+ .Times(0);
+
+ process::spawn(leader);
+
+ std::string znode = "zk://" + server->connectString() + "/mesos";
+
+ Try<zookeeper::URL> url = zookeeper::URL::parse(znode);
+ ASSERT_SOME(url);
+
+ // Leader's detector.
+ ZooKeeperMasterDetector leaderDetector(
+ url.get(), leader.self(), true, true);
+
+ AWAIT_READY(newMasterDetected1);
+
+ // Simulate a following master.
+ MockMasterDetectorListenerProcess follower;
+
+ Future<Nothing> newMasterDetected3;
+ EXPECT_CALL(follower, newMasterDetected(_))
+ .WillOnce(FutureSatisfy(&newMasterDetected3))
+ .WillRepeatedly(Return());
+
+ EXPECT_CALL(follower, noMasterDetected())
+ .Times(0);
+
+ process::spawn(follower);
+
+ // Follower's detector.
+ ZooKeeperMasterDetector followerDetector(
+ url.get(),
+ follower.self(),
+ true,
+ true);
+
+ AWAIT_READY(newMasterDetected3);
+
+ // Now expire the leader's zk session.
+ Future<int64_t> session = leaderDetector.session();
+ AWAIT_READY(session);
+
+ server->expireSession(session.get());
+
+ // Wait for session expiration and ensure we receive a
+ // NewMasterDetected message.
+ AWAIT_READY(newMasterDetected2);
+
+ process::terminate(follower);
+ process::wait(follower);
+
+ process::terminate(leader);
+ process::wait(leader);
+}
+
+
+// Tests whether a slave correctly DOES NOT disconnect from the master
+// when its ZooKeeper session is expired, but the master still stays
+// the leader when the slave re-connects with the ZooKeeper.
+TEST_F(ZooKeeperMasterDetectorTest, MasterDetectorExpireSlaveZKSession)
+{
+ // Simulate a leading master.
+ MockMasterDetectorListenerProcess master;
+
+ Future<Nothing> newMasterDetected1;
+ EXPECT_CALL(master, newMasterDetected(_))
+ .WillOnce(FutureSatisfy(&newMasterDetected1));
+
+ EXPECT_CALL(master, noMasterDetected())
+ .Times(0);
+
+ process::spawn(master);
+
+ std::string znode = "zk://" + server->connectString() + "/mesos";
+
+ Try<zookeeper::URL> url = zookeeper::URL::parse(znode);
+ ASSERT_SOME(url);
+
+ // Leading master's detector.
+ ZooKeeperMasterDetector masterDetector(
+ url.get(), master.self(), true, true);
+
+ AWAIT_READY(newMasterDetected1);
+
+ // Simulate a slave.
+ MockMasterDetectorListenerProcess slave;
+
+ Future<Nothing> newMasterDetected2, newMasterDetected3;
+ EXPECT_CALL(slave, newMasterDetected(_))
+ .Times(1)
+ .WillOnce(FutureSatisfy(&newMasterDetected2));
+
+ EXPECT_CALL(slave, noMasterDetected())
+ .Times(0);
+
+ process::spawn(slave);
+
+ // Slave's master detector.
+ ZooKeeperMasterDetector slaveDetector(
+ url.get(), slave.self(), false, true);
+
+ AWAIT_READY(newMasterDetected2);
+
+ // Now expire the slave's zk session.
+ Future<int64_t> session = slaveDetector.session();
+ AWAIT_READY(session);
+
+ server->expireSession(session.get());
+
+ // Wait for enough time to ensure no NewMasterDetected message is sent.
+ os::sleep(Seconds(4)); // ZooKeeper needs extra time for session expiration.
+
+ process::terminate(slave);
+ process::wait(slave);
+
+ process::terminate(master);
+ process::wait(master);
+}
+
+
+// Tests whether a slave correctly detects the new master when its
+// ZooKeeper session is expired and a new master is elected before the
+// slave reconnects with ZooKeeper.
+TEST_F(ZooKeeperMasterDetectorTest, MasterDetectorExpireSlaveZKSessionNewMaster)
+{
+ // Simulate a leading master.
+ MockMasterDetectorListenerProcess master1;
+
+ Future<Nothing> newMasterDetected1;
+ EXPECT_CALL(master1, newMasterDetected(_))
+ .WillOnce(FutureSatisfy(&newMasterDetected1))
+ .WillRepeatedly(Return());
+
+ EXPECT_CALL(master1, noMasterDetected())
+ .Times(0);
+
+ process::spawn(master1);
+
+ std::string znode = "zk://" + server->connectString() + "/mesos";
+
+ Try<zookeeper::URL> url = zookeeper::URL::parse(znode);
+ ASSERT_SOME(url);
+
+ // Leading master's detector.
+ ZooKeeperMasterDetector masterDetector1(
+ url.get(), master1.self(), true, true);
+
+ AWAIT_READY(newMasterDetected1);
+
+ // Simulate a non-leading master.
+ MockMasterDetectorListenerProcess master2;
+
+ Future<Nothing> newMasterDetected2;
+ EXPECT_CALL(master2, newMasterDetected(_))
+ .WillOnce(FutureSatisfy(&newMasterDetected2))
+ .WillRepeatedly(Return());
+
+ EXPECT_CALL(master2, noMasterDetected())
+ .Times(0);
+
+ process::spawn(master2);
+
+ // Non-leading master's detector.
+ ZooKeeperMasterDetector masterDetector2(
+ url.get(), master2.self(), true, true);
+
+ AWAIT_READY(newMasterDetected2);
+
+ // Simulate a slave.
+ MockMasterDetectorListenerProcess slave;
+
+ Future<Nothing> newMasterDetected3, newMasterDetected4;
+ EXPECT_CALL(slave, newMasterDetected(_))
+ .WillOnce(FutureSatisfy(&newMasterDetected3))
+ .WillOnce(FutureSatisfy(&newMasterDetected4));
+
+ EXPECT_CALL(slave, noMasterDetected())
+ .Times(AtMost(1));
+
+ process::spawn(slave);
+
+ // Slave's master detector.
+ ZooKeeperMasterDetector slaveDetector(
+ url.get(), slave.self(), false, true);
+
+ AWAIT_READY(newMasterDetected3);
+
+ // Now expire the slave's and leading master's zk sessions.
+ // NOTE: Here we assume that slave stays disconnected from the ZK when the
+ // leading master loses its session.
+ Future<int64_t> slaveSession = slaveDetector.session();
+ AWAIT_READY(slaveSession);
+
+ server->expireSession(slaveSession.get());
+
+ Future<int64_t> masterSession = masterDetector1.session();
+ AWAIT_READY(masterSession);
+
+ server->expireSession(masterSession.get());
+
+ // Wait for session expiration and ensure we receive a
+ // NewMasterDetected message.
+ AWAIT_READY(newMasterDetected4);
+
+ process::terminate(slave);
+ process::wait(slave);
+
+ process::terminate(master2);
+ process::wait(master2);
+
+ process::terminate(master1);
+ process::wait(master1);
+}
+#endif // MESOS_HAS_JAVA
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/0ebf3933/src/tests/zookeeper_test.hpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_test.hpp b/src/tests/zookeeper_test.hpp
index b5215b0..61a3d25 100644
--- a/src/tests/zookeeper_test.hpp
+++ b/src/tests/zookeeper_test.hpp
@@ -38,6 +38,37 @@ namespace mesos {
namespace internal {
namespace tests {
+// Helper for invoking ZooKeeper::get(path, ...) in order to check the
+// data stored at a specified znode path.
+inline ::testing::AssertionResult AssertZKGet(
+ const char* expectedExpr,
+ const char* zkExpr,
+ const char* pathExpr,
+ const std::string& expected,
+ ZooKeeper* zk,
+ const std::string& path)
+{
+ std::string result;
+ int code = zk->get(path, false, &result, NULL);
+ if (code == ZOK) {
+ if (expected == result) {
+ return ::testing::AssertionSuccess();
+ } else {
+ return ::testing::AssertionFailure()
+ << "Expected data at znode '" << pathExpr << "' "
+ << "to be '" << expected << "', but actually '" << result << "'";
+ }
+ } else {
+ return ::testing::AssertionFailure()
+ << "(" << zkExpr << ").get(" << pathExpr << ", ...): "
+ << zk->message(code);
+ }
+}
+
+#define ASSERT_ZK_GET(expected, zk, path) \
+ ASSERT_PRED_FORMAT3(mesos::internal::tests::AssertZKGet, expected, zk, path)
+
+
// A fixture for tests that need to interact with a ZooKeeper server
// ensemble. Tests can access the in process ZooKeeperTestServer via
// the variable 'server'. This test fixture ensures the server is
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/0ebf3933/src/tests/zookeeper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_tests.cpp b/src/tests/zookeeper_tests.cpp
index e9180bf..5193d03 100644
--- a/src/tests/zookeeper_tests.cpp
+++ b/src/tests/zookeeper_tests.cpp
@@ -22,68 +22,14 @@
#include <string>
-#include <process/clock.hpp>
-#include <process/process.hpp>
-#include <process/protobuf.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/os.hpp>
#include <stout/strings.hpp>
-#include <stout/nothing.hpp>
-#include <stout/try.hpp>
-
-#include "detector/detector.hpp"
-
-#include "messages/messages.hpp"
#include "tests/utils.hpp"
#include "tests/zookeeper_test.hpp"
-#include "zookeeper/authentication.hpp"
-#include "zookeeper/group.hpp"
-#include "zookeeper/url.hpp"
-
using namespace mesos::internal;
using namespace mesos::internal::tests;
-using process::Clock;
-using process::Future;
-
-using testing::_;
-using testing::AtMost;
-using testing::Return;
-
-
-// Helper for invoking ZooKeeper::get(path, ...) in order to check the
-// data stored at a specified znode path.
-::testing::AssertionResult AssertZKGet(
- const char* expectedExpr,
- const char* zkExpr,
- const char* pathExpr,
- const std::string& expected,
- ZooKeeper* zk,
- const std::string& path)
-{
- std::string result;
- int code = zk->get(path, false, &result, NULL);
- if (code == ZOK) {
- if (expected == result) {
- return ::testing::AssertionSuccess();
- } else {
- return ::testing::AssertionFailure()
- << "Expected data at znode '" << pathExpr << "' "
- << "to be '" << expected << "', but actually '" << result << "'";
- }
- } else {
- return ::testing::AssertionFailure()
- << "(" << zkExpr << ").get(" << pathExpr << ", ...): "
- << zk->message(code);
- }
-}
-
-#define ASSERT_ZK_GET(expected, zk, path) \
- ASSERT_PRED_FORMAT3(AssertZKGet, expected, zk, path)
-
TEST_F(ZooKeeperTest, Auth)
{
@@ -158,745 +104,3 @@ TEST_F(ZooKeeperTest, Create)
true));
EXPECT_TRUE(strings::startsWith(result, "/foo/bar/baz/0"));
}
-
-
-class MockMasterDetectorListenerProcess
- : public ProtobufProcess<MockMasterDetectorListenerProcess>
-{
-public:
- MockMasterDetectorListenerProcess() {}
- virtual ~MockMasterDetectorListenerProcess() {}
-
- MOCK_METHOD1(newMasterDetected, void(const process::UPID&));
- MOCK_METHOD0(noMasterDetected, void(void));
-
-protected:
- virtual void initialize()
- {
- install<NewMasterDetectedMessage>(
- &MockMasterDetectorListenerProcess::newMasterDetected,
- &NewMasterDetectedMessage::pid);
-
- install<NoMasterDetectedMessage>(
- &MockMasterDetectorListenerProcess::noMasterDetected);
- }
-};
-
-
-TEST_F(ZooKeeperTest, MasterDetector)
-{
- MockMasterDetectorListenerProcess mock;
- process::spawn(mock);
-
- Future<Nothing> newMasterDetected;
- EXPECT_CALL(mock, newMasterDetected(mock.self()))
- .WillOnce(FutureSatisfy(&newMasterDetected));
-
- std::string master = "zk://" + server->connectString() + "/mesos";
-
- Try<MasterDetector*> detector =
- MasterDetector::create(master, mock.self(), true, true);
-
- ASSERT_SOME(detector);
-
- AWAIT_READY(newMasterDetected);
-
- MasterDetector::destroy(detector.get());
-
- process::terminate(mock);
- process::wait(mock);
-}
-
-
-TEST_F(ZooKeeperTest, MasterDetectors)
-{
- MockMasterDetectorListenerProcess mock1;
- process::spawn(mock1);
-
- Future<Nothing> newMasterDetected1;
- EXPECT_CALL(mock1, newMasterDetected(mock1.self()))
- .WillOnce(FutureSatisfy(&newMasterDetected1));
-
- std::string master = "zk://" + server->connectString() + "/mesos";
-
- Try<MasterDetector*> detector1 =
- MasterDetector::create(master, mock1.self(), true, true);
-
- ASSERT_SOME(detector1);
-
- AWAIT_READY(newMasterDetected1);
-
- MockMasterDetectorListenerProcess mock2;
- process::spawn(mock2);
-
- Future<Nothing> newMasterDetected2;
- EXPECT_CALL(mock2, newMasterDetected(mock1.self())) // N.B. mock1
- .WillOnce(FutureSatisfy(&newMasterDetected2));
-
- Try<MasterDetector*> detector2 =
- MasterDetector::create(master, mock2.self(), true, true);
-
- ASSERT_SOME(detector2);
-
- AWAIT_READY(newMasterDetected2);
-
- // Destroying detector1 (below) might cause another election so we
- // need to set up expectations appropriately.
- EXPECT_CALL(mock2, newMasterDetected(_))
- .WillRepeatedly(Return());
-
- MasterDetector::destroy(detector1.get());
-
- process::terminate(mock1);
- process::wait(mock1);
-
- MasterDetector::destroy(detector2.get());
-
- process::terminate(mock2);
- process::wait(mock2);
-}
-
-
-TEST_F(ZooKeeperTest, MasterDetectorShutdownNetwork)
-{
- Clock::pause();
-
- MockMasterDetectorListenerProcess mock;
- process::spawn(mock);
-
- Future<Nothing> newMasterDetected1;
- EXPECT_CALL(mock, newMasterDetected(mock.self()))
- .WillOnce(FutureSatisfy(&newMasterDetected1));
-
- std::string master = "zk://" + server->connectString() + "/mesos";
-
- Try<MasterDetector*> detector =
- MasterDetector::create(master, mock.self(), true, true);
-
- ASSERT_SOME(detector);
-
- AWAIT_READY(newMasterDetected1);
-
- Future<Nothing> noMasterDetected;
- EXPECT_CALL(mock, noMasterDetected())
- .WillOnce(FutureSatisfy(&noMasterDetected));
-
- server->shutdownNetwork();
-
- Clock::advance(Seconds(10)); // TODO(benh): Get session timeout from detector.
-
- AWAIT_READY(noMasterDetected);
-
- Future<Nothing> newMasterDetected2;
- EXPECT_CALL(mock, newMasterDetected(mock.self()))
- .WillOnce(FutureSatisfy(&newMasterDetected2));
-
- server->startNetwork();
-
- AWAIT_READY(newMasterDetected2);
-
- MasterDetector::destroy(detector.get());
-
- process::terminate(mock);
- process::wait(mock);
-
- Clock::resume();
-}
-
-
-// Tests that a detector sends a NoMasterDetectedMessage when we
-// reach our ZooKeeper session timeout. This is to enforce that we
-// manually expire the session when we don't get reconnected within
-// the ZOOKEEPER_SESSION_TIMEOUT.
-TEST_F(ZooKeeperTest, MasterDetectorTimedoutSession)
-{
- Try<zookeeper::URL> url =
- zookeeper::URL::parse("zk://" + server->connectString() + "/mesos");
- ASSERT_SOME(url);
-
- // First we bring up three master detector listeners:
- // 1. A leading contender.
- // 2. A non-leading contender.
- // 3. A non-contender.
-
- // 1. Simulate a leading contender.
- MockMasterDetectorListenerProcess leader;
-
- Future<Nothing> newMasterDetected;
- EXPECT_CALL(leader, newMasterDetected(_))
- .WillOnce(FutureSatisfy(&newMasterDetected));
-
- process::spawn(leader);
-
- ZooKeeperMasterDetector leaderDetector(
- url.get(), leader.self(), true, true);
-
- AWAIT_READY(newMasterDetected);
-
- // 2. Simulate a non-leading contender.
- MockMasterDetectorListenerProcess follower;
-
- EXPECT_CALL(follower, newMasterDetected(_))
- .WillOnce(FutureSatisfy(&newMasterDetected));
-
- process::spawn(follower);
-
- ZooKeeperMasterDetector followerDetector(
- url.get(), follower.self(), true, true);
-
- AWAIT_READY(newMasterDetected);
-
- // 3. Simulate a non-contender.
- MockMasterDetectorListenerProcess nonContender;
-
- EXPECT_CALL(nonContender, newMasterDetected(_))
- .WillOnce(FutureSatisfy(&newMasterDetected));
-
- process::spawn(nonContender);
-
- ZooKeeperMasterDetector nonContenderDetector(
- url.get(), nonContender.self(), false, true);
-
- AWAIT_READY(newMasterDetected);
-
- // Now we want to induce lost connections on each of the
- // master detectors.
- // Induce a reconnection on the leader.
- Future<Nothing> leaderReconnecting = FUTURE_DISPATCH(
- leaderDetector.process->self(),
- &ZooKeeperMasterDetectorProcess::reconnecting);
-
- dispatch(leaderDetector.process,
- &ZooKeeperMasterDetectorProcess::reconnecting);
-
- AWAIT_READY(leaderReconnecting);
-
- // Induce a reconnection on the follower.
- Future<Nothing> followerReconnecting = FUTURE_DISPATCH(
- followerDetector.process->self(),
- &ZooKeeperMasterDetectorProcess::reconnecting);
-
- dispatch(followerDetector.process,
- &ZooKeeperMasterDetectorProcess::reconnecting);
-
- AWAIT_READY(followerReconnecting);
-
- // Induce a reconnection on the non-contender.
- Future<Nothing> nonContenderReconnecting = FUTURE_DISPATCH(
- nonContenderDetector.process->self(),
- &ZooKeeperMasterDetectorProcess::reconnecting);
-
- dispatch(nonContenderDetector.process,
- &ZooKeeperMasterDetectorProcess::reconnecting);
-
- AWAIT_READY(nonContenderReconnecting);
-
- // Now induce the reconnection timeout.
- Future<Nothing> leaderNoMasterDetected;
- EXPECT_CALL(leader, noMasterDetected())
- .WillOnce(FutureSatisfy(&leaderNoMasterDetected));
-
- Future<Nothing> followerNoMasterDetected;
- EXPECT_CALL(follower, noMasterDetected())
- .WillOnce(FutureSatisfy(&followerNoMasterDetected));
-
- Future<Nothing> nonContenderNoMasterDetected;
- EXPECT_CALL(nonContender, noMasterDetected())
- .WillOnce(FutureSatisfy(&nonContenderNoMasterDetected));
-
- Clock::pause();
- Clock::advance(ZOOKEEPER_SESSION_TIMEOUT);
- Clock::settle();
-
- AWAIT_READY(leaderNoMasterDetected);
- AWAIT_READY(followerNoMasterDetected);
- AWAIT_READY(nonContenderNoMasterDetected);
-
- process::terminate(leader);
- process::wait(leader);
-
- process::terminate(follower);
- process::wait(follower);
-
- process::terminate(nonContender);
- process::wait(nonContender);
-}
-
-
-// Tests whether a leading master correctly detects a new master when its
-// ZooKeeper session is expired.
-TEST_F(ZooKeeperTest, MasterDetectorExpireMasterZKSession)
-{
- // Simulate a leading master.
- MockMasterDetectorListenerProcess leader;
-
- Future<Nothing> newMasterDetected1, newMasterDetected2;
- EXPECT_CALL(leader, newMasterDetected(_))
- .WillOnce(FutureSatisfy(&newMasterDetected1))
- .WillOnce(FutureSatisfy(&newMasterDetected2));
-
- EXPECT_CALL(leader, noMasterDetected())
- .Times(0);
-
- process::spawn(leader);
-
- std::string znode = "zk://" + server->connectString() + "/mesos";
-
- Try<zookeeper::URL> url = zookeeper::URL::parse(znode);
- ASSERT_SOME(url);
-
- // Leader's detector.
- ZooKeeperMasterDetector leaderDetector(url.get(), leader.self(), true, true);
-
- AWAIT_READY(newMasterDetected1);
-
- // Simulate a following master.
- MockMasterDetectorListenerProcess follower;
-
- Future<Nothing> newMasterDetected3;
- EXPECT_CALL(follower, newMasterDetected(_))
- .WillOnce(FutureSatisfy(&newMasterDetected3))
- .WillRepeatedly(Return());
-
- EXPECT_CALL(follower, noMasterDetected())
- .Times(0);
-
- process::spawn(follower);
-
- // Follower's detector.
- ZooKeeperMasterDetector followerDetector(
- url.get(),
- follower.self(),
- true,
- true);
-
- AWAIT_READY(newMasterDetected3);
-
- // Now expire the leader's zk session.
- process::Future<int64_t> session = leaderDetector.session();
- AWAIT_READY(session);
-
- server->expireSession(session.get());
-
- // Wait for session expiration and ensure we receive a
- // NewMasterDetected message.
- AWAIT_READY(newMasterDetected2);
-
- process::terminate(follower);
- process::wait(follower);
-
- process::terminate(leader);
- process::wait(leader);
-}
-
-
-// Tests whether a slave correctly DOES NOT disconnect from the master
-// when its ZooKeeper session is expired, but the master still stays the leader
-// when the slave re-connects with the ZooKeeper.
-TEST_F(ZooKeeperTest, MasterDetectorExpireSlaveZKSession)
-{
- // Simulate a leading master.
- MockMasterDetectorListenerProcess master;
-
- Future<Nothing> newMasterDetected1;
- EXPECT_CALL(master, newMasterDetected(_))
- .WillOnce(FutureSatisfy(&newMasterDetected1));
-
- EXPECT_CALL(master, noMasterDetected())
- .Times(0);
-
- process::spawn(master);
-
- std::string znode = "zk://" + server->connectString() + "/mesos";
-
- Try<zookeeper::URL> url = zookeeper::URL::parse(znode);
- ASSERT_SOME(url);
-
- // Leading master's detector.
- ZooKeeperMasterDetector masterDetector(url.get(), master.self(), true, true);
-
- AWAIT_READY(newMasterDetected1);
-
- // Simulate a slave.
- MockMasterDetectorListenerProcess slave;
-
- Future<Nothing> newMasterDetected2, newMasterDetected3;
- EXPECT_CALL(slave, newMasterDetected(_))
- .Times(1)
- .WillOnce(FutureSatisfy(&newMasterDetected2));
-
- EXPECT_CALL(slave, noMasterDetected())
- .Times(0);
-
- process::spawn(slave);
-
- // Slave's master detector.
- ZooKeeperMasterDetector slaveDetector(url.get(), slave.self(), false, true);
-
- AWAIT_READY(newMasterDetected2);
-
- // Now expire the slave's zk session.
- process::Future<int64_t> session = slaveDetector.session();
- AWAIT_READY(session);
-
- server->expireSession(session.get());
-
- // Wait for enough time to ensure no NewMasterDetected message is sent.
- os::sleep(Seconds(4)); // ZooKeeper needs extra time for session expiration.
-
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
-}
-
-
-// Tests whether a slave correctly detects the new master
-// when its ZooKeeper session is expired and a new master is elected before the
-// slave reconnects with ZooKeeper.
-TEST_F(ZooKeeperTest, MasterDetectorExpireSlaveZKSessionNewMaster)
-{
- // Simulate a leading master.
- MockMasterDetectorListenerProcess master1;
-
- Future<Nothing> newMasterDetected1;
- EXPECT_CALL(master1, newMasterDetected(_))
- .WillOnce(FutureSatisfy(&newMasterDetected1))
- .WillRepeatedly(Return());
-
- EXPECT_CALL(master1, noMasterDetected())
- .Times(0);
-
- process::spawn(master1);
-
- std::string znode = "zk://" + server->connectString() + "/mesos";
-
- Try<zookeeper::URL> url = zookeeper::URL::parse(znode);
- ASSERT_SOME(url);
-
- // Leading master's detector.
- ZooKeeperMasterDetector masterDetector1(
- url.get(), master1.self(), true, true);
-
- AWAIT_READY(newMasterDetected1);
-
- // Simulate a non-leading master.
- MockMasterDetectorListenerProcess master2;
-
- Future<Nothing> newMasterDetected2;
- EXPECT_CALL(master2, newMasterDetected(_))
- .WillOnce(FutureSatisfy(&newMasterDetected2))
- .WillRepeatedly(Return());
-
- EXPECT_CALL(master2, noMasterDetected())
- .Times(0);
-
- process::spawn(master2);
-
- // Non-leading master's detector.
- ZooKeeperMasterDetector masterDetector2(
- url.get(), master2.self(), true, true);
-
- AWAIT_READY(newMasterDetected2);
-
- // Simulate a slave.
- MockMasterDetectorListenerProcess slave;
-
- Future<Nothing> newMasterDetected3, newMasterDetected4;
- EXPECT_CALL(slave, newMasterDetected(_))
- .WillOnce(FutureSatisfy(&newMasterDetected3))
- .WillOnce(FutureSatisfy(&newMasterDetected4));
-
- EXPECT_CALL(slave, noMasterDetected())
- .Times(AtMost(1));
-
- process::spawn(slave);
-
- // Slave's master detector.
- ZooKeeperMasterDetector slaveDetector(url.get(), slave.self(), false, true);
-
- AWAIT_READY(newMasterDetected3);
-
- // Now expire the slave's and leading master's zk sessions.
- // NOTE: Here we assume that slave stays disconnected from the ZK when the
- // leading master loses its session.
- process::Future<int64_t> slaveSession = slaveDetector.session();
- AWAIT_READY(slaveSession);
-
- server->expireSession(slaveSession.get());
-
- process::Future<int64_t> masterSession = masterDetector1.session();
- AWAIT_READY(masterSession);
-
- server->expireSession(masterSession.get());
-
- // Wait for session expiration and ensure we receive a
- // NewMasterDetected message.
- AWAIT_READY(newMasterDetected4);
-
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master2);
- process::wait(master2);
-
- process::terminate(master1);
- process::wait(master1);
-}
-
-
-TEST_F(ZooKeeperTest, Group)
-{
- zookeeper::Group group(server->connectString(), NO_TIMEOUT, "/test/");
-
- process::Future<zookeeper::Group::Membership> membership =
- group.join("hello world");
-
- AWAIT_READY(membership);
-
- process::Future<std::set<zookeeper::Group::Membership> > memberships =
- group.watch();
-
- AWAIT_READY(memberships);
- EXPECT_EQ(1u, memberships.get().size());
- EXPECT_EQ(1u, memberships.get().count(membership.get()));
-
- process::Future<std::string> data = group.data(membership.get());
-
- AWAIT_EXPECT_EQ("hello world", data);
-
- process::Future<bool> cancellation = group.cancel(membership.get());
-
- AWAIT_EXPECT_EQ(true, cancellation);
-
- memberships = group.watch(memberships.get());
-
- AWAIT_READY(memberships);
- EXPECT_EQ(0u, memberships.get().size());
-
- ASSERT_TRUE(membership.get().cancelled().isReady());
- ASSERT_TRUE(membership.get().cancelled().get());
-}
-
-
-TEST_F(ZooKeeperTest, GroupJoinWithDisconnect)
-{
- zookeeper::Group group(server->connectString(), NO_TIMEOUT, "/test/");
-
- server->shutdownNetwork();
-
- process::Future<zookeeper::Group::Membership> membership =
- group.join("hello world");
-
- EXPECT_TRUE(membership.isPending());
-
- server->startNetwork();
-
- AWAIT_READY(membership);
-
- process::Future<std::set<zookeeper::Group::Membership> > memberships =
- group.watch();
-
- AWAIT_READY(memberships);
- EXPECT_EQ(1u, memberships.get().size());
- EXPECT_EQ(1u, memberships.get().count(membership.get()));
-}
-
-
-TEST_F(ZooKeeperTest, GroupDataWithDisconnect)
-{
- zookeeper::Group group(server->connectString(), NO_TIMEOUT, "/test/");
-
- process::Future<zookeeper::Group::Membership> membership =
- group.join("hello world");
-
- AWAIT_READY(membership);
-
- process::Future<std::set<zookeeper::Group::Membership> > memberships =
- group.watch();
-
- AWAIT_READY(memberships);
- EXPECT_EQ(1u, memberships.get().size());
- EXPECT_EQ(1u, memberships.get().count(membership.get()));
-
- server->shutdownNetwork();
-
- process::Future<std::string> data = group.data(membership.get());
-
- EXPECT_TRUE(data.isPending());
-
- server->startNetwork();
-
- AWAIT_EXPECT_EQ("hello world", data);
-}
-
-
-TEST_F(ZooKeeperTest, GroupCancelWithDisconnect)
-{
- zookeeper::Group group(server->connectString(), NO_TIMEOUT, "/test/");
-
- process::Future<zookeeper::Group::Membership> membership =
- group.join("hello world");
-
- AWAIT_READY(membership);
-
- process::Future<std::set<zookeeper::Group::Membership> > memberships =
- group.watch();
-
- AWAIT_READY(memberships);
- EXPECT_EQ(1u, memberships.get().size());
- EXPECT_EQ(1u, memberships.get().count(membership.get()));
-
- process::Future<std::string> data = group.data(membership.get());
-
- AWAIT_EXPECT_EQ("hello world", data);
-
- server->shutdownNetwork();
-
- process::Future<bool> cancellation = group.cancel(membership.get());
-
- EXPECT_TRUE(cancellation.isPending());
-
- server->startNetwork();
-
- AWAIT_EXPECT_EQ(true, cancellation);
-
- memberships = group.watch(memberships.get());
-
- AWAIT_READY(memberships);
- EXPECT_EQ(0u, memberships.get().size());
-
- ASSERT_TRUE(membership.get().cancelled().isReady());
- ASSERT_TRUE(membership.get().cancelled().get());
-}
-
-
-TEST_F(ZooKeeperTest, GroupWatchWithSessionExpiration)
-{
- zookeeper::Group group(server->connectString(), NO_TIMEOUT, "/test/");
-
- process::Future<zookeeper::Group::Membership> membership =
- group.join("hello world");
-
- AWAIT_READY(membership);
-
- process::Future<std::set<zookeeper::Group::Membership> > memberships =
- group.watch();
-
- AWAIT_READY(memberships);
- EXPECT_EQ(1u, memberships.get().size());
- EXPECT_EQ(1u, memberships.get().count(membership.get()));
-
- process::Future<Option<int64_t> > session = group.session();
-
- AWAIT_READY(session);
- ASSERT_SOME(session.get());
-
- memberships = group.watch(memberships.get());
-
- server->expireSession(session.get().get());
-
- AWAIT_READY(memberships);
- EXPECT_EQ(0u, memberships.get().size());
-
- ASSERT_TRUE(membership.get().cancelled().isReady());
- ASSERT_FALSE(membership.get().cancelled().get());
-}
-
-
-TEST_F(ZooKeeperTest, MultipleGroups)
-{
- zookeeper::Group group1(server->connectString(), NO_TIMEOUT, "/test/");
- zookeeper::Group group2(server->connectString(), NO_TIMEOUT, "/test/");
-
- process::Future<zookeeper::Group::Membership> membership1 =
- group1.join("group 1");
-
- AWAIT_READY(membership1);
-
- process::Future<zookeeper::Group::Membership> membership2 =
- group2.join("group 2");
-
- AWAIT_READY(membership2);
-
- process::Future<std::set<zookeeper::Group::Membership> > memberships1 =
- group1.watch();
-
- AWAIT_READY(memberships1);
- EXPECT_EQ(2u, memberships1.get().size());
- EXPECT_EQ(1u, memberships1.get().count(membership1.get()));
- EXPECT_EQ(1u, memberships1.get().count(membership2.get()));
-
- process::Future<std::set<zookeeper::Group::Membership> > memberships2 =
- group2.watch();
-
- AWAIT_READY(memberships2);
- EXPECT_EQ(2u, memberships2.get().size());
- EXPECT_EQ(1u, memberships2.get().count(membership1.get()));
- EXPECT_EQ(1u, memberships2.get().count(membership2.get()));
-
- process::Future<bool> cancelled;
-
- // Now watch the membership owned by group1 from group2.
- foreach (const zookeeper::Group::Membership& membership, memberships2.get()) {
- if (membership == membership1.get()) {
- cancelled = membership.cancelled();
- break;
- }
- }
-
- process::Future<Option<int64_t> > session1 = group1.session();
-
- AWAIT_READY(session1);
- ASSERT_SOME(session1.get());
-
- server->expireSession(session1.get().get());
-
- AWAIT_ASSERT_EQ(false, cancelled);
-}
-
-
-TEST_F(ZooKeeperTest, GroupPathWithRestrictivePerms)
-{
- ZooKeeperTest::TestWatcher watcher;
-
- ZooKeeper authenticatedZk(server->connectString(), NO_TIMEOUT, &watcher);
- watcher.awaitSessionEvent(ZOO_CONNECTED_STATE);
- authenticatedZk.authenticate("digest", "creator:creator");
- authenticatedZk.create("/read-only",
- "42",
- zookeeper::EVERYONE_READ_CREATOR_ALL,
- 0,
- NULL);
- ASSERT_ZK_GET("42", &authenticatedZk, "/read-only");
- authenticatedZk.create("/read-only/writable",
- "37",
- ZOO_OPEN_ACL_UNSAFE,
- 0,
- NULL);
- ASSERT_ZK_GET("37", &authenticatedZk, "/read-only/writable");
-
- zookeeper::Authentication auth("digest", "non-creator:non-creator");
-
- zookeeper::Group failedGroup1(server->connectString(), NO_TIMEOUT,
- "/read-only/", auth);
- process::Future<zookeeper::Group::Membership> failedMembership1 =
- failedGroup1.join("fail");
-
- AWAIT_FAILED(failedMembership1);
-
- zookeeper::Group failedGroup2(server->connectString(), NO_TIMEOUT,
- "/read-only/new", auth);
- process::Future<zookeeper::Group::Membership> failedMembership2 =
- failedGroup2.join("fail");
-
- AWAIT_FAILED(failedMembership2);
-
- zookeeper::Group successGroup(server->connectString(), NO_TIMEOUT,
- "/read-only/writable/", auth);
- process::Future<zookeeper::Group::Membership> successMembership =
- successGroup.join("succeed");
-
- AWAIT_READY(successMembership);
-}
[05/28] git commit: Minor cleanup in stout/exit.hpp.
Posted by be...@apache.org.
Minor cleanup in stout/exit.hpp.
Review: https://reviews.apache.org/r/11269
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/07c44ce2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/07c44ce2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/07c44ce2
Branch: refs/heads/master
Commit: 07c44ce216d96ecdc1a639ec489d30590308e9af
Parents: 65e2fba
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sat May 4 12:09:42 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Fri May 24 22:05:05 2013 -0700
----------------------------------------------------------------------
.../third_party/stout/include/stout/exit.hpp | 17 ++++++++-------
1 files changed, 9 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/07c44ce2/third_party/libprocess/third_party/stout/include/stout/exit.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/exit.hpp b/third_party/libprocess/third_party/stout/include/stout/exit.hpp
index c588ac0..e8da726 100644
--- a/third_party/libprocess/third_party/stout/include/stout/exit.hpp
+++ b/third_party/libprocess/third_party/stout/include/stout/exit.hpp
@@ -3,34 +3,35 @@
#include <stdlib.h>
+#include <iostream> // For std::cerr.
#include <ostream>
#include <sstream>
#include <string>
-// Exit takes an exit code and provides a stream for output prior to
+// Exit takes an exit status and provides a stream for output prior to
// exiting. This is like glog's LOG(FATAL) or CHECK, except that it
-// does _not_ print a stack trace because we don't want to freak out
-// the user.
+// does _not_ print a stack trace.
//
// Ex: EXIT(1) << "Cgroups are not present in this system.";
-#define EXIT __Exit().stream
+#define EXIT(status) __Exit(status).stream()
struct __Exit
{
+ __Exit(int _status) : status(_status) {}
+
~__Exit()
{
std::cerr << out.str() << std::endl;
- exit(exitCode);
+ exit(status);
}
- std::ostream& stream(int exitCode)
+ std::ostream& stream()
{
- this->exitCode = exitCode;
return out;
}
std::ostringstream out;
- int exitCode;
+ const int status;
};
#endif // __STOUT_EXIT_HPP__
[21/28] Refactored base 'State' implementation to be serialization
agnostic and use a 'Storage' instance. Changed the LevelDB and ZooKeeper
implementations to implement 'Storage' instead of 'State'. Provided a
protobuf specific implementation on top of '
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/33f4ff4b/src/tests/state_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/state_tests.cpp b/src/tests/state_tests.cpp
index 2e75673..ca12499 100644
--- a/src/tests/state_tests.cpp
+++ b/src/tests/state_tests.cpp
@@ -31,14 +31,15 @@
#include <stout/gtest.hpp>
#include <stout/option.hpp>
#include <stout/os.hpp>
+#include <stout/try.hpp>
#include "common/type_utils.hpp"
-#include "messages/messages.hpp"
+#include "master/registry.hpp"
#include "state/leveldb.hpp"
-#include "state/serializer.hpp"
-#include "state/state.hpp"
+#include "state/protobuf.hpp"
+#include "state/storage.hpp"
#include "state/zookeeper.hpp"
#ifdef MESOS_HAS_JAVA
@@ -47,166 +48,272 @@
using namespace mesos;
using namespace mesos::internal;
-using namespace mesos::internal::state;
+using namespace mesos::internal::tests;
using namespace process;
+using mesos::internal::registry::Registry;
+using mesos::internal::registry::Slave;
-void GetSetGet(State<ProtobufSerializer>* state)
-{
- Future<Variable<Slaves> > variable = state->get<Slaves>("slaves");
- AWAIT_READY(variable);
+using state::LevelDBStorage;
+using state::Storage;
+#ifdef MESOS_HAS_JAVA
+using state::ZooKeeperStorage;
+#endif
- Variable<Slaves> slaves1 = variable.get();
- EXPECT_TRUE(slaves1->infos().size() == 0);
+using state::protobuf::State;
+using state::protobuf::Variable;
- SlaveInfo info;
- info.set_hostname("localhost");
- info.set_webui_hostname("localhost");
- slaves1->add_infos()->MergeFrom(info);
+void FetchAndStoreAndFetch(State* state)
+{
+ Future<Variable<Registry> > future1 = state->fetch<Registry>("registry");
+ AWAIT_READY(future1);
- Future<Option<Variable<Slaves> > > result = state->set(slaves1);
+ Variable<Registry> variable = future1.get();
- result.await();
+ Registry registry1 = variable.get();
+ EXPECT_TRUE(registry1.slaves().size() == 0);
- ASSERT_TRUE(result.isReady());
- ASSERT_SOME(result.get());
+ Slave* slave = registry1.add_slaves();
+ slave->mutable_info()->set_hostname("localhost");
+ slave->mutable_info()->set_webui_hostname("localhost");
- variable = state->get<Slaves>("slaves");
+ variable = variable.mutate(registry1);
- variable.await();
+ Future<Option<Variable<Registry> > > future2 = state->store(variable);
+ AWAIT_READY(future2);
+ ASSERT_SOME(future2.get());
- ASSERT_TRUE(variable.isReady());
+ future1 = state->fetch<Registry>("registry");
+ AWAIT_READY(future1);
- Variable<Slaves> slaves2 = variable.get();
+ variable = future1.get();
- ASSERT_TRUE(slaves2->infos().size() == 1);
- EXPECT_EQ("localhost", slaves2->infos(0).hostname());
- EXPECT_EQ("localhost", slaves2->infos(0).webui_hostname());
+ Registry registry2 = variable.get();
+ ASSERT_TRUE(registry2.slaves().size() == 1);
+ EXPECT_EQ("localhost", registry2.slaves(0).info().hostname());
+ EXPECT_EQ("localhost", registry2.slaves(0).info().webui_hostname());
}
-void GetSetSetGet(State<ProtobufSerializer>* state)
+void FetchAndStoreAndStoreAndFetch(State* state)
{
- Future<Variable<Slaves> > variable = state->get<Slaves>("slaves");
- AWAIT_READY(variable);
+ Future<Variable<Registry> > future1 = state->fetch<Registry>("registry");
+ AWAIT_READY(future1);
+
+ Variable<Registry> variable = future1.get();
+
+ Registry registry1 = variable.get();
+ EXPECT_TRUE(registry1.slaves().size() == 0);
+
+ Slave* slave = registry1.add_slaves();
+ slave->mutable_info()->set_hostname("localhost");
+ slave->mutable_info()->set_webui_hostname("localhost");
+
+ variable = variable.mutate(registry1);
- Variable<Slaves> slaves1 = variable.get();
- EXPECT_TRUE(slaves1->infos().size() == 0);
+ Future<Option<Variable<Registry> > > future2 = state->store(variable);
+ AWAIT_READY(future2);
+ ASSERT_SOME(future2.get());
- SlaveInfo info;
- info.set_hostname("localhost");
- info.set_webui_hostname("localhost");
+ variable = future2.get().get();
- slaves1->add_infos()->MergeFrom(info);
+ future2 = state->store(variable);
+ AWAIT_READY(future2);
+ ASSERT_SOME(future2.get());
- Future<Option<Variable<Slaves> > > result = state->set(slaves1);
+ future1 = state->fetch<Registry>("registry");
+ AWAIT_READY(future1);
- result.await();
+ variable = future1.get();
- ASSERT_TRUE(result.isReady());
- ASSERT_SOME(result.get());
+ Registry registry2 = variable.get();
+ ASSERT_TRUE(registry2.slaves().size() == 1);
+ EXPECT_EQ("localhost", registry2.slaves(0).info().hostname());
+ EXPECT_EQ("localhost", registry2.slaves(0).info().webui_hostname());
+}
+
+
+void FetchAndStoreAndStoreFailAndFetch(State* state)
+{
+ Future<Variable<Registry> > future1 = state->fetch<Registry>("registry");
+ AWAIT_READY(future1);
- slaves1 = result.get().get();
+ Variable<Registry> variable1 = future1.get();
- result = state->set(slaves1);
+ Registry registry1 = variable1.get();
+ EXPECT_TRUE(registry1.slaves().size() == 0);
- result.await();
+ Slave* slave1 = registry1.add_slaves();
+ slave1->mutable_info()->set_hostname("localhost1");
+ slave1->mutable_info()->set_webui_hostname("localhost1");
- ASSERT_TRUE(result.isReady());
- ASSERT_SOME(result.get());
+ Variable<Registry> variable2 = variable1.mutate(registry1);
- variable = state->get<Slaves>("slaves");
+ Future<Option<Variable<Registry> > > future2 = state->store(variable2);
+ AWAIT_READY(future2);
+ ASSERT_SOME(future2.get());
- variable.await();
+ Registry registry2 = variable1.get();
+ EXPECT_TRUE(registry2.slaves().size() == 0);
- ASSERT_TRUE(variable.isReady());
+ Slave* slave2 = registry2.add_slaves();
+ slave2->mutable_info()->set_hostname("localhost2");
+ slave2->mutable_info()->set_webui_hostname("localhost2");
- Variable<Slaves> slaves2 = variable.get();
+ variable2 = variable1.mutate(registry2);
- ASSERT_TRUE(slaves2->infos().size() == 1);
- EXPECT_EQ("localhost", slaves2->infos(0).hostname());
- EXPECT_EQ("localhost", slaves2->infos(0).webui_hostname());
+ future2 = state->store(variable2);
+ AWAIT_READY(future2);
+ EXPECT_TRUE(future2.get().isNone());
+
+ future1 = state->fetch<Registry>("registry");
+ AWAIT_READY(future1);
+
+ variable1 = future1.get();
+
+ registry1 = variable1.get();
+ ASSERT_TRUE(registry1.slaves().size() == 1);
+ EXPECT_EQ("localhost1", registry1.slaves(0).info().hostname());
+ EXPECT_EQ("localhost1", registry1.slaves(0).info().webui_hostname());
}
-void GetGetSetSetGet(State<ProtobufSerializer>* state)
+void FetchAndStoreAndExpungeAndFetch(State* state)
{
- Future<Variable<Slaves> > variable = state->get<Slaves>("slaves");
- AWAIT_READY(variable);
+ Future<Variable<Registry> > future1 = state->fetch<Registry>("registry");
+ AWAIT_READY(future1);
- Variable<Slaves> slaves1 = variable.get();
- EXPECT_TRUE(slaves1->infos().size() == 0);
+ Variable<Registry> variable = future1.get();
- variable = state->get<Slaves>("slaves");
- AWAIT_READY(variable);
+ Registry registry1 = variable.get();
+ EXPECT_TRUE(registry1.slaves().size() == 0);
- Variable<Slaves> slaves2 = variable.get();
- EXPECT_TRUE(slaves2->infos().size() == 0);
+ Slave* slave = registry1.add_slaves();
+ slave->mutable_info()->set_hostname("localhost");
+ slave->mutable_info()->set_webui_hostname("localhost");
- SlaveInfo info2;
- info2.set_hostname("localhost2");
- info2.set_webui_hostname("localhost2");
+ variable = variable.mutate(registry1);
- slaves2->add_infos()->MergeFrom(info2);
+ Future<Option<Variable<Registry> > > future2 = state->store(variable);
+ AWAIT_READY(future2);
+ ASSERT_SOME(future2.get());
- Future<Option<Variable<Slaves> > > result = state->set(slaves2);
+ variable = future2.get().get();
- result.await();
+ Future<bool> future3 = state->expunge(variable);
+ AWAIT_READY(future3);
+ ASSERT_TRUE(future3.get());
- ASSERT_TRUE(result.isReady());
- ASSERT_SOME(result.get());
+ future1 = state->fetch<Registry>("registry");
+ AWAIT_READY(future1);
- SlaveInfo info1;
- info1.set_hostname("localhost1");
- info1.set_webui_hostname("localhost1");
+ variable = future1.get();
- slaves1->add_infos()->MergeFrom(info1);
+ Registry registry2 = variable.get();
+ ASSERT_EQ(0, registry2.slaves().size());
+}
- result = state->set(slaves1);
- AWAIT_READY(result);
- EXPECT_TRUE(result.get().isNone());
- variable = state->get<Slaves>("slaves");
- AWAIT_READY(variable);
+void FetchAndStoreAndExpungeAndExpunge(State* state)
+{
+ Future<Variable<Registry> > future1 = state->fetch<Registry>("registry");
+ AWAIT_READY(future1);
+
+ Variable<Registry> variable = future1.get();
+
+ Registry registry1 = variable.get();
+ EXPECT_TRUE(registry1.slaves().size() == 0);
+
+ Slave* slave = registry1.add_slaves();
+ slave->mutable_info()->set_hostname("localhost");
+ slave->mutable_info()->set_webui_hostname("localhost");
- slaves1 = variable.get();
+ variable = variable.mutate(registry1);
- ASSERT_TRUE(slaves1->infos().size() == 1);
- EXPECT_EQ("localhost2", slaves1->infos(0).hostname());
- EXPECT_EQ("localhost2", slaves1->infos(0).webui_hostname());
+ Future<Option<Variable<Registry> > > future2 = state->store(variable);
+ AWAIT_READY(future2);
+ ASSERT_SOME(future2.get());
+
+ variable = future2.get().get();
+
+ Future<bool> future3 = state->expunge(variable);
+ AWAIT_READY(future3);
+ ASSERT_TRUE(future3.get());
+
+ future3 = state->expunge(variable);
+ AWAIT_READY(future3);
+ ASSERT_FALSE(future3.get());
}
-void Names(State<ProtobufSerializer>* state)
+void FetchAndStoreAndExpungeAndStoreAndFetch(State* state)
{
- Future<Variable<Slaves> > variable = state->get<Slaves>("slaves");
- AWAIT_READY(variable);
+ Future<Variable<Registry> > future1 = state->fetch<Registry>("registry");
+ AWAIT_READY(future1);
- Variable<Slaves> slaves1 = variable.get();
- EXPECT_TRUE(slaves1->infos().size() == 0);
+ Variable<Registry> variable = future1.get();
- SlaveInfo info;
- info.set_hostname("localhost");
- info.set_webui_hostname("localhost");
+ Registry registry1 = variable.get();
+ EXPECT_TRUE(registry1.slaves().size() == 0);
- slaves1->add_infos()->MergeFrom(info);
+ Slave* slave = registry1.add_slaves();
+ slave->mutable_info()->set_hostname("localhost");
+ slave->mutable_info()->set_webui_hostname("localhost");
- Future<Option<Variable<Slaves> > > result = state->set(slaves1);
+ variable = variable.mutate(registry1);
- result.await();
+ Future<Option<Variable<Registry> > > future2 = state->store(variable);
+ AWAIT_READY(future2);
+ ASSERT_SOME(future2.get());
- ASSERT_TRUE(result.isReady());
- EXPECT_SOME(result.get());
+ variable = future2.get().get();
- Future<std::vector<std::string> > names = state->names();
+ Future<bool> future3 = state->expunge(variable);
+ AWAIT_READY(future3);
+ ASSERT_TRUE(future3.get());
+
+ future2 = state->store(variable);
+ AWAIT_READY(future2);
+ ASSERT_SOME(future2.get());
+
+ future1 = state->fetch<Registry>("registry");
+ AWAIT_READY(future1);
+
+ variable = future1.get();
+
+ Registry registry2 = variable.get();
+ ASSERT_TRUE(registry2.slaves().size() == 1);
+ EXPECT_EQ("localhost", registry2.slaves(0).info().hostname());
+ EXPECT_EQ("localhost", registry2.slaves(0).info().webui_hostname());
+}
+
+
+void Names(State* state)
+{
+ Future<Variable<Registry> > future1 = state->fetch<Registry>("registry");
+ AWAIT_READY(future1);
+
+ Variable<Registry> variable = future1.get();
+
+ Registry registry1 = variable.get();
+ EXPECT_TRUE(registry1.slaves().size() == 0);
+
+ Slave* slave = registry1.add_slaves();
+ slave->mutable_info()->set_hostname("localhost");
+ slave->mutable_info()->set_webui_hostname("localhost");
- names.await();
+ variable = variable.mutate(registry1);
- ASSERT_TRUE(names.isReady());
+ Future<Option<Variable<Registry> > > future2 = state->store(variable);
+ AWAIT_READY(future2);
+ ASSERT_SOME(future2.get());
+
+ Future<std::vector<std::string> > names = state->names();
+ AWAIT_READY(names);
ASSERT_TRUE(names.get().size() == 1);
- EXPECT_EQ("slaves", names.get()[0]);
+ EXPECT_EQ("registry", names.get()[0]);
}
@@ -214,43 +321,66 @@ class LevelDBStateTest : public ::testing::Test
{
public:
LevelDBStateTest()
- : state(NULL), path(os::getcwd() + "/.state") {}
+ : storage(NULL),
+ state(NULL),
+ path(os::getcwd() + "/.state") {}
protected:
virtual void SetUp()
{
os::rmdir(path);
- state = new LevelDBState<ProtobufSerializer>(path);
+ storage = new state::LevelDBStorage(path);
+ state = new State(storage);
}
virtual void TearDown()
{
delete state;
+ delete storage;
os::rmdir(path);
}
- State<ProtobufSerializer>* state;
+ state::Storage* storage;
+ State* state;
private:
const std::string path;
};
-TEST_F(LevelDBStateTest, GetSetGet)
+TEST_F(LevelDBStateTest, FetchAndStoreAndFetch)
+{
+ FetchAndStoreAndFetch(state);
+}
+
+
+TEST_F(LevelDBStateTest, FetchAndStoreAndStoreAndFetch)
+{
+ FetchAndStoreAndStoreAndFetch(state);
+}
+
+
+TEST_F(LevelDBStateTest, FetchAndStoreAndStoreFailAndFetch)
{
- GetSetGet(state);
+ FetchAndStoreAndStoreFailAndFetch(state);
}
-TEST_F(LevelDBStateTest, GetSetSetGet)
+TEST_F(LevelDBStateTest, FetchAndStoreAndExpungeAndFetch)
{
- GetSetSetGet(state);
+ FetchAndStoreAndExpungeAndFetch(state);
}
-TEST_F(LevelDBStateTest, GetGetSetSetGet)
+TEST_F(LevelDBStateTest, FetchAndStoreAndExpungeAndExpunge)
{
- GetGetSetSetGet(state);
+ FetchAndStoreAndExpungeAndExpunge(state);
+}
+
+
+TEST_F(LevelDBStateTest, FetchAndStoreAndExpungeAndStoreAndFetch)
+{
+ FetchAndStoreAndExpungeAndStoreAndFetch(state);
}
@@ -265,45 +395,68 @@ class ZooKeeperStateTest : public tests::ZooKeeperTest
{
public:
ZooKeeperStateTest()
- : state(NULL) {}
+ : storage(NULL),
+ state(NULL) {}
protected:
virtual void SetUp()
{
ZooKeeperTest::SetUp();
- state = new ZooKeeperState<ProtobufSerializer>(
+ storage = new state::ZooKeeperStorage(
server->connectString(),
NO_TIMEOUT,
"/state/");
+ state = new State(storage);
}
virtual void TearDown()
{
delete state;
+ delete storage;
ZooKeeperTest::TearDown();
}
- State<ProtobufSerializer>* state;
+ state::Storage* storage;
+ State* state;
};
-TEST_F(ZooKeeperStateTest, GetSetGet)
+TEST_F(ZooKeeperStateTest, FetchAndStoreAndFetch)
+{
+ FetchAndStoreAndFetch(state);
+}
+
+
+TEST_F(ZooKeeperStateTest, FetchAndStoreAndStoreAndFetch)
{
- GetSetGet(state);
+ FetchAndStoreAndStoreAndFetch(state);
}
-TEST_F(ZooKeeperStateTest, GetSetSetGet)
+TEST_F(ZooKeeperStateTest, FetchAndStoreAndStoreFailAndFetch)
{
- GetSetSetGet(state);
+ FetchAndStoreAndStoreFailAndFetch(state);
}
-TEST_F(ZooKeeperStateTest, GetGetSetSetGet)
+TEST_F(ZooKeeperStateTest, FetchAndStoreAndExpungeAndFetch)
{
- GetGetSetSetGet(state);
+ FetchAndStoreAndExpungeAndFetch(state);
}
+
+TEST_F(ZooKeeperStateTest, FetchAndStoreAndExpungeAndExpunge)
+{
+ FetchAndStoreAndExpungeAndExpunge(state);
+}
+
+
+TEST_F(ZooKeeperStateTest, FetchAndStoreAndExpungeAndStoreAndFetch)
+{
+ FetchAndStoreAndExpungeAndStoreAndFetch(state);
+}
+
+
TEST_F(ZooKeeperStateTest, Names)
{
Names(state);
[27/28] git commit: Added some helpers for failing a collection of
futures.
Posted by be...@apache.org.
Added some helpers for failing a collection of futures.
Review: https://reviews.apache.org/r/11311
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/50d93fc7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/50d93fc7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/50d93fc7
Branch: refs/heads/master
Commit: 50d93fc78e42770f0a90725df751c5d9592bc40e
Parents: 023e431
Author: Benjamin Hindman <be...@twitter.com>
Authored: Mon Jan 14 15:55:33 2013 -0800
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 09:28:38 2013 -0700
----------------------------------------------------------------------
third_party/libprocess/include/process/future.hpp | 22 ++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/50d93fc7/third_party/libprocess/include/process/future.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/future.hpp b/third_party/libprocess/include/process/future.hpp
index b458997..daf4b92 100644
--- a/third_party/libprocess/include/process/future.hpp
+++ b/third_party/libprocess/include/process/future.hpp
@@ -450,6 +450,28 @@ void discard(const std::list<Future<T> >& futures)
}
+template <class T>
+void fail(const std::vector<Promise<T>*>& promises, const std::string& message)
+{
+ typename std::vector<Promise<T>*>::const_iterator iterator;
+ for (iterator = promises.begin(); iterator != promises.end(); ++iterator) {
+ Promise<T>* promise = *iterator;
+ promise->fail(message);
+ }
+}
+
+
+template <class T>
+void fail(const std::list<Promise<T>*>& promises, const std::string& message)
+{
+ typename std::list<Promise<T>*>::const_iterator iterator;
+ for (iterator = promises.begin(); iterator != promises.end(); ++iterator) {
+ Promise<T>* promise = *iterator;
+ promise->fail(message);
+ }
+}
+
+
template <typename T>
Future<T> Future<T>::failed(const std::string& message)
{
[25/28] git commit: Updated MonitorTest.WatchUnwatch to be
deterministic.
Posted by be...@apache.org.
Updated MonitorTest.WatchUnwatch to be deterministic.
Review: https://reviews.apache.org/r/11353
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/4392c6e3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/4392c6e3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/4392c6e3
Branch: refs/heads/master
Commit: 4392c6e3b7b3dfabfc11a73f930063ad9fe92bc8
Parents: bc9cb87
Author: Benjamin Hindman <be...@twitter.com>
Authored: Thu May 23 13:44:30 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 09:28:38 2013 -0700
----------------------------------------------------------------------
src/tests/monitor_tests.cpp | 34 ++++++++++++++++++++++++----------
1 files changed, 24 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/4392c6e3/src/tests/monitor_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/monitor_tests.cpp b/src/tests/monitor_tests.cpp
index 5681af2..53920a0 100644
--- a/src/tests/monitor_tests.cpp
+++ b/src/tests/monitor_tests.cpp
@@ -29,6 +29,8 @@
#include <process/pid.hpp>
#include <process/process.hpp>
+#include <stout/nothing.hpp>
+
#include "slave/constants.hpp"
#include "slave/monitor.hpp"
@@ -49,6 +51,7 @@ using process::http::Response;
using std::string;
using testing::_;
+using testing::DoAll;
using testing::Return;
@@ -79,14 +82,17 @@ TEST(MonitorTest, WatchUnwatch)
process::spawn(isolator);
+ Future<Nothing> usage;
EXPECT_CALL(isolator, usage(frameworkId, executorId))
- .WillRepeatedly(Return(statistics));
+ .WillOnce(DoAll(FutureSatisfy(&usage),
+ Return(statistics)));
slave::ResourceMonitor monitor(&isolator);
- // Monitor the executor.
- Future<Nothing> watch =
- FUTURE_DISPATCH(_, &slave::ResourceMonitorProcess::watch);
+ // We pause the clock first in order to make sure that we can
+ // advance time below to force the 'delay' in
+ // ResourceMonitorProcess::watch to execute.
+ process::Clock::pause();
monitor.watch(
frameworkId,
@@ -94,12 +100,18 @@ TEST(MonitorTest, WatchUnwatch)
executorInfo,
slave::RESOURCE_MONITORING_INTERVAL);
- AWAIT_READY(watch);
+ // Now wait for ResouorceMonitorProcess::watch to finish so we can
+ // advance time to cause collection to begin.
+ process::Clock::settle();
- process::Clock::pause();
process::Clock::advance(slave::RESOURCE_MONITORING_INTERVAL);
process::Clock::settle();
+ AWAIT_READY(usage);
+
+ // Wait until the isolator has finished returning the statistics.
+ process::Clock::settle();
+
process::UPID upid("monitor", process::ip(), process::port());
Future<Response> response = process::http::get(upid, "usage.json");
@@ -130,12 +142,14 @@ TEST(MonitorTest, WatchUnwatch)
response);
// Ensure the monitor stops polling the isolator.
- Future<Nothing> unwatch =
- FUTURE_DISPATCH(_, &slave::ResourceMonitorProcess::unwatch);
-
monitor.unwatch(frameworkId, executorId);
- AWAIT_READY(unwatch);
+ // Wait until ResourceMonitorProcess::unwatch has completed.
+ process::Clock::settle();
+
+ // This time, Isolator::usage should not get called.
+ EXPECT_CALL(isolator, usage(frameworkId, executorId))
+ .Times(0);
process::Clock::advance(slave::RESOURCE_MONITORING_INTERVAL);
process::Clock::settle();
[28/28] git commit: Fixed output bug with CHECK_SOME.
Posted by be...@apache.org.
Fixed output bug with CHECK_SOME.
Review: https://reviews.apache.org/r/11310
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/023e431e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/023e431e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/023e431e
Branch: refs/heads/master
Commit: 023e431e8944a2bd9293b49ebefe47eede9baae0
Parents: 7b36ed5
Author: Benjamin Hindman <be...@twitter.com>
Authored: Mon Jan 14 15:47:43 2013 -0800
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 09:28:38 2013 -0700
----------------------------------------------------------------------
src/logging/check_some.hpp | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/023e431e/src/logging/check_some.hpp
----------------------------------------------------------------------
diff --git a/src/logging/check_some.hpp b/src/logging/check_some.hpp
index 8c8e136..cbfd78b 100644
--- a/src/logging/check_some.hpp
+++ b/src/logging/check_some.hpp
@@ -83,12 +83,12 @@ struct _CheckSome
expression(_expression),
error(_error)
{
- out << "CHECK_SOME(" << expression << ") failed: ";
+ out << "CHECK_SOME(" << expression << "): ";
}
~_CheckSome()
{
- out << ": " << error;
+ out << error;
google::LogMessageFatal(file.c_str(), line).stream() << out.str();
}
[24/28] git commit: Added a 'port' field to SlaveInfo and updated
default master and slave ports.
Posted by be...@apache.org.
Added a 'port' field to SlaveInfo and updated default master and slave
ports.
Review: https://reviews.apache.org/r/11309
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/7b36ed50
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/7b36ed50
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/7b36ed50
Branch: refs/heads/master
Commit: 7b36ed5007d6db9e895a4d703d6064991416db2f
Parents: 33f4ff4
Author: Benjamin Hindman <be...@twitter.com>
Authored: Wed Nov 28 18:57:45 2012 -0800
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 09:28:38 2013 -0700
----------------------------------------------------------------------
include/mesos/mesos.proto | 4 ++--
src/master/main.cpp | 16 ++++++++++------
src/slave/main.cpp | 18 ++++++++++--------
src/slave/slave.cpp | 1 +
4 files changed, 23 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/7b36ed50/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index 1c242d6..ece6559 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -156,7 +156,7 @@ message ExecutorInfo {
message MasterInfo {
required string id = 1;
required uint32 ip = 2;
- required uint32 port = 3;
+ required uint32 port = 3 [default = 5050];
}
@@ -172,7 +172,7 @@ message MasterInfo {
*/
message SlaveInfo {
required string hostname = 1;
- // TODO(benh,andyk): Send bound ports, not just hostname.
+ optional int32 port = 8 [default = 5051];
required string webui_hostname = 2; // Deprecated!
optional int32 webui_port = 4 [default = 8081]; // Deprecated!
repeated Resource resources = 3;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/7b36ed50/src/master/main.cpp
----------------------------------------------------------------------
diff --git a/src/master/main.cpp b/src/master/main.cpp
index 19b6524..06c265a 100644
--- a/src/master/main.cpp
+++ b/src/master/main.cpp
@@ -16,6 +16,8 @@
* limitations under the License.
*/
+#include <mesos/mesos.hpp>
+
#include <stout/os.hpp>
#include <stout/stringify.hpp>
#include <stout/try.hpp>
@@ -40,6 +42,8 @@
using namespace mesos::internal;
using namespace mesos::internal::master;
+using mesos::MasterInfo;
+
using std::cerr;
using std::endl;
using std::string;
@@ -62,13 +66,13 @@ int main(int argc, char** argv)
// The following flags are executable specific (e.g., since we only
// have one instance of libprocess per execution, we only want to
- // advertise the port and ip option once, here).
- uint16_t port;
- flags.add(&port, "port", "Port to listen on", 5050);
-
+ // advertise the IP and port option once, here).
Option<string> ip;
flags.add(&ip, "ip", "IP address to listen on");
+ uint16_t port;
+ flags.add(&port, "port", "Port to listen on", MasterInfo().port());
+
string zk;
flags.add(&zk,
"zk",
@@ -103,12 +107,12 @@ int main(int argc, char** argv)
}
// Initialize libprocess.
- os::setenv("LIBPROCESS_PORT", stringify(port));
-
if (ip.isSome()) {
os::setenv("LIBPROCESS_IP", ip.get());
}
+ os::setenv("LIBPROCESS_PORT", stringify(port));
+
process::initialize("master");
logging::initialize(argv[0], flags, true); // Catch signals.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/7b36ed50/src/slave/main.cpp
----------------------------------------------------------------------
diff --git a/src/slave/main.cpp b/src/slave/main.cpp
index da286a2..97c818a 100644
--- a/src/slave/main.cpp
+++ b/src/slave/main.cpp
@@ -16,6 +16,8 @@
* limitations under the License.
*/
+#include <mesos/mesos.hpp>
+
#include <stout/os.hpp>
#include <stout/stringify.hpp>
#include <stout/try.hpp>
@@ -37,6 +39,8 @@
using namespace mesos::internal;
using namespace mesos::internal::slave;
+using mesos::SlaveInfo;
+
using std::cerr;
using std::endl;
using std::string;
@@ -59,13 +63,13 @@ int main(int argc, char** argv)
// The following flags are executable specific (e.g., since we only
// have one instance of libprocess per execution, we only want to
- // advertise the port and ip option once, here).
- Option<uint16_t> port;
- flags.add(&port, "port", "Port to listen on");
-
+ // advertise the IP and port option once, here).
Option<string> ip;
flags.add(&ip, "ip", "IP address to listen on");
+ uint16_t port;
+ flags.add(&port, "port", "Port to listen on", SlaveInfo().port());
+
string isolation;
flags.add(&isolation,
"isolation",
@@ -109,14 +113,12 @@ int main(int argc, char** argv)
}
// Initialize libprocess.
- if (port.isSome()) {
- os::setenv("LIBPROCESS_PORT", stringify(port.get()));
- }
-
if (ip.isSome()) {
os::setenv("LIBPROCESS_IP", ip.get());
}
+ os::setenv("LIBPROCESS_PORT", stringify(port));
+
process::initialize();
logging::initialize(argv[0], flags, true); // Catch signals.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/7b36ed50/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index b451d90..25c91d9 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -235,6 +235,7 @@ void Slave::initialize()
// Initialize slave info.
info.set_hostname(hostname);
+ info.set_port(self().port);
info.set_webui_hostname(webui_hostname); // Deprecated!
info.mutable_resources()->MergeFrom(resources);
info.mutable_attributes()->MergeFrom(attributes);
[08/28] git commit: Moved 'tests::mkdtemp' to Environment.
Posted by be...@apache.org.
Moved 'tests::mkdtemp' to Environment.
Review: https://reviews.apache.org/r/11268
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/65e2fba7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/65e2fba7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/65e2fba7
Branch: refs/heads/master
Commit: 65e2fba73b10368cf5b5e13f273cad0cb8aef223
Parents: 6f6ca87
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sun Apr 28 18:53:58 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Fri May 24 22:05:05 2013 -0700
----------------------------------------------------------------------
src/tests/environment.cpp | 57 +++++++++++++++++++++++++++++++++++++++-
src/tests/environment.hpp | 24 ++++++++++++++++-
src/tests/main.cpp | 7 ++++-
src/tests/script.cpp | 3 +-
src/tests/utils.cpp | 30 +-------------------
src/tests/utils.hpp | 11 ++-----
6 files changed, 92 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/65e2fba7/src/tests/environment.cpp
----------------------------------------------------------------------
diff --git a/src/tests/environment.cpp b/src/tests/environment.cpp
index 15ef205..2a22acd 100644
--- a/src/tests/environment.cpp
+++ b/src/tests/environment.cpp
@@ -24,6 +24,7 @@
#include <process/gmock.hpp>
#include <process/gtest.hpp>
+#include <stout/error.hpp>
#include <stout/exit.hpp>
#include <stout/os.hpp>
#include <stout/strings.hpp>
@@ -35,6 +36,7 @@
#endif
#include "tests/environment.hpp"
+#include "tests/flags.hpp"
using std::list;
using std::string;
@@ -43,6 +45,10 @@ namespace mesos {
namespace internal {
namespace tests {
+// Storage for the global environment instance.
+Environment* environment;
+
+
// Returns true if we should enable the provided test. Similar to how
// tests can be disabled using the 'DISABLED_' prefix on a test case
// name or test name, we use:
@@ -169,6 +175,18 @@ Environment::Environment()
}
+Environment::~Environment()
+{
+ foreach (const string& directory, directories) {
+ Try<Nothing> rmdir = os::rmdir(directory);
+ if (rmdir.isError()) {
+ LOG(ERROR) << "Failed to remove '" << directory
+ << "': " << rmdir.error();
+ }
+ }
+}
+
+
void Environment::SetUp()
{
// Clear any MESOS_ environment variables so they don't affect our tests.
@@ -177,10 +195,47 @@ void Environment::SetUp()
if (!GTEST_IS_THREADSAFE) {
EXIT(1) << "Testing environment is not thread safe, bailing!";
}
+
+ // For locating killtree.sh.
+ os::setenv("MESOS_SOURCE_DIR", tests::flags.source_dir);
}
-void Environment::TearDown() {}
+void Environment::TearDown()
+{
+ os::unsetenv("MESOS_SOURCE_DIR");
+}
+
+
+Try<string> Environment::mkdtemp()
+{
+ const ::testing::TestInfo* const testInfo =
+ ::testing::UnitTest::GetInstance()->current_test_info();
+
+ if (testInfo == NULL) {
+ return Error("Failed to determine the current test information");
+ }
+
+ // We replace any slashes present in the test names (e.g. TYPED_TEST),
+ // to make sure the temporary directory resides under '/tmp/'.
+ const string& testCase =
+ strings::replace(testInfo->test_case_name(), "/", "_");
+
+ string testName = strings::replace(testInfo->name(), "/", "_");
+
+ // Adjust the test name to remove any 'DISABLED_' prefix (to make
+ // things easier to read). While this might seem alarming, if we are
+ // "running" a disabled test it must be the case that the test was
+ // explicitly enabled (e.g., via 'gtest_filter').
+ if (strings::startsWith(testName, "DISABLED_")) {
+ testName = strings::remove(testName, "DISABLED_", strings::PREFIX);
+ }
+
+ const string& path =
+ path::join("/tmp", strings::join("_", testCase, testName, "XXXXXX"));
+
+ return os::mkdtemp(path);
+}
} // namespace tests {
} // namespace internal {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/65e2fba7/src/tests/environment.hpp
----------------------------------------------------------------------
diff --git a/src/tests/environment.hpp b/src/tests/environment.hpp
index 61aa84d..691291f 100644
--- a/src/tests/environment.hpp
+++ b/src/tests/environment.hpp
@@ -21,18 +21,40 @@
#include <gtest/gtest.h>
+#include <list>
+#include <string>
+
+#include <stout/try.hpp>
+
namespace mesos {
namespace internal {
namespace tests {
-// Used to set up our particular test environment.
+// Used to set up and manage the test environment.
class Environment : public ::testing::Environment {
public:
Environment();
+ virtual ~Environment();
+
virtual void SetUp();
virtual void TearDown();
+
+ // Helper to create a temporary directory based on the current test
+ // case name and test name (derived from TestInfo via
+ // ::testing::UnitTest::GetInstance()->current_test_info()). Note
+ // that the directory will automagically get removed when the
+ // environment instance gets destructed.
+ Try<std::string> mkdtemp();
+
+private:
+ // Temporary directories that we created and need to remove.
+ std::list<std::string> directories;
};
+
+// Global environment instance.
+extern Environment* environment;
+
} // namespace tests {
} // namespace internal {
} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/65e2fba7/src/tests/main.cpp
----------------------------------------------------------------------
diff --git a/src/tests/main.cpp b/src/tests/main.cpp
index e32ec0c..b06c0d1 100644
--- a/src/tests/main.cpp
+++ b/src/tests/main.cpp
@@ -30,6 +30,7 @@
#include "logging/logging.hpp"
#include "tests/environment.hpp"
+#include "tests/flags.hpp"
#include "tests/utils.hpp"
using namespace mesos::internal;
@@ -98,7 +99,11 @@ int main(int argc, char** argv)
std::cout << "Source directory: " << flags.source_dir << std::endl;
std::cout << "Build directory: " << flags.build_dir << std::endl;
- testing::AddGlobalTestEnvironment(new Environment());
+ // Instantiate our environment. Note that it will be managed by
+ // gtest after we add it via testing::AddGlobalTestEnvironment.
+ environment = new Environment();
+
+ testing::AddGlobalTestEnvironment(environment);
return RUN_ALL_TESTS();
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/65e2fba7/src/tests/script.cpp
----------------------------------------------------------------------
diff --git a/src/tests/script.cpp b/src/tests/script.cpp
index d7f103e..e2b4efa 100644
--- a/src/tests/script.cpp
+++ b/src/tests/script.cpp
@@ -28,6 +28,7 @@
#include <stout/path.hpp>
#include <stout/strings.hpp>
+#include "tests/environment.hpp"
#include "tests/script.hpp"
#include "tests/utils.hpp"
@@ -40,7 +41,7 @@ namespace tests {
void execute(const string& script)
{
// Create a temporary directory for the test.
- Try<string> directory = mkdtemp();
+ Try<string> directory = environment->mkdtemp();
CHECK_SOME(directory) << "Failed to create temporary directory";
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/65e2fba7/src/tests/utils.cpp
----------------------------------------------------------------------
diff --git a/src/tests/utils.cpp b/src/tests/utils.cpp
index 0bb1536..9a83053 100644
--- a/src/tests/utils.cpp
+++ b/src/tests/utils.cpp
@@ -26,6 +26,7 @@
#include <stout/path.hpp>
#include <stout/strings.hpp>
+#include "tests/environment.hpp"
#include "tests/flags.hpp"
#include "tests/utils.hpp"
@@ -35,40 +36,13 @@ namespace mesos {
namespace internal {
namespace tests {
-Try<string> mkdtemp()
-{
- const ::testing::TestInfo* const testInfo =
- ::testing::UnitTest::GetInstance()->current_test_info();
-
- // We replace any slashes present in the test names (e.g. TYPED_TEST),
- // to make sure the temporary directory resides under '/tmp/'.
- const string& testCase =
- strings::replace(testInfo->test_case_name(), "/", "_");
-
- string testName = strings::replace(testInfo->name(), "/", "_");
-
- // Adjust the test name to remove any 'DISABLED_' prefix (to make
- // things easier to read). While this might seem alarming, if we are
- // "running" a disabled test it must be the case that the test was
- // explicitly enabled (e.g., via 'gtest_filter').
- if (strings::startsWith(testName, "DISABLED_")) {
- testName = strings::remove(testName, "DISABLED_", strings::PREFIX);
- }
-
- const string& path =
- path::join("/tmp", strings::join("_", testCase, testName, "XXXXXX"));
-
- return os::mkdtemp(path);
-}
-
-
void TemporaryDirectoryTest::SetUp()
{
// Save the current working directory.
cwd = os::getcwd();
// Create a temporary directory for the test.
- Try<string> directory = mkdtemp();
+ Try<string> directory = environment->mkdtemp();
ASSERT_SOME(directory) << "Failed to mkdtemp";
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/65e2fba7/src/tests/utils.hpp
----------------------------------------------------------------------
diff --git a/src/tests/utils.hpp b/src/tests/utils.hpp
index 2e47734..60e4678 100644
--- a/src/tests/utils.hpp
+++ b/src/tests/utils.hpp
@@ -72,6 +72,7 @@
#include "slave/state.hpp"
#include "tests/cluster.hpp"
+#include "tests/environment.hpp"
#include "tests/flags.hpp"
#include "tests/isolator.hpp"
@@ -88,12 +89,6 @@ const static std::string TEST_CGROUPS_ROOT = "mesos_test";
#endif
-// Helper to create a temporary directory based on the current test
-// case name and test name (derived from TestInfo via
-// ::testing::UnitTest::GetInstance()->current_test_info()).
-Try<std::string> mkdtemp();
-
-
// Test fixture for creating a temporary directory for each test.
class TemporaryDirectoryTest : public ::testing::Test
{
@@ -118,7 +113,7 @@ protected:
virtual void SetUp()
{
// Create a temporary directory for the test.
- Try<std::string> directory = mkdtemp();
+ Try<std::string> directory = environment->mkdtemp();
CHECK(directory.isSome())
<< "Failed to create temporary directory: " << directory.error();
@@ -154,7 +149,7 @@ protected:
virtual void SetUp()
{
// Create a temporary directory for the test.
- Try<std::string> directory = mkdtemp();
+ Try<std::string> directory = environment->mkdtemp();
CHECK(directory.isSome())
<< "Failed to create temporary directory: " << directory.error();
[14/28] git commit: A little spring cleaning in the allocator tests.
Posted by be...@apache.org.
A little spring cleaning in the allocator tests.
Review: https://reviews.apache.org/r/11278
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/bfa22550
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/bfa22550
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/bfa22550
Branch: refs/heads/master
Commit: bfa22550d1818d2add7a4f46a40eb9a0c4373003
Parents: fd981ce
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sat May 11 19:23:44 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 00:13:41 2013 -0700
----------------------------------------------------------------------
src/tests/allocator_tests.cpp | 535 ++++++++++++++++++------------------
1 files changed, 274 insertions(+), 261 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bfa22550/src/tests/allocator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/allocator_tests.cpp b/src/tests/allocator_tests.cpp
index e8f833d..8b868bc 100644
--- a/src/tests/allocator_tests.cpp
+++ b/src/tests/allocator_tests.cpp
@@ -50,18 +50,14 @@ using process::Clock;
using process::Future;
using process::PID;
-using std::map;
using std::string;
using std::vector;
using testing::_;
using testing::AtMost;
-using testing::ByRef;
using testing::DoAll;
using testing::DoDefault;
using testing::Eq;
-using testing::InSequence;
-using testing::Return;
using testing::SaveArg;
@@ -96,6 +92,7 @@ TEST_F(DRFAllocatorTest, DRFAllocatorProcess)
FrameworkInfo frameworkInfo1;
frameworkInfo1.set_name("framework1");
frameworkInfo1.set_user("user1");
+
MockScheduler sched1;
MesosSchedulerDriver driver1(&sched1, frameworkInfo1, master.get());
@@ -228,12 +225,17 @@ TEST_F(DRFAllocatorTest, DRFAllocatorProcess)
EXPECT_CALL(allocator, frameworkRemoved(_))
.Times(AtMost(3));
- EXPECT_CALL(allocator, slaveRemoved(_))
- .Times(AtMost(4));
-
driver1.stop();
+ driver1.join();
+
driver2.stop();
+ driver2.join();
+
driver3.stop();
+ driver3.join();
+
+ EXPECT_CALL(allocator, slaveRemoved(_))
+ .Times(AtMost(4));
Shutdown();
}
@@ -290,41 +292,33 @@ TYPED_TEST(AllocatorTest, MockAllocator)
EXPECT_CALL(sched, registered(_, _, _));
- Future<vector<Offer> > offers;
- EXPECT_CALL(sched, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers));
+ // The framework should be offered all of the resources on the slave
+ // since it is the only framework in the cluster.
+ Future<Nothing> resourceOffers;
+ EXPECT_CALL(sched, resourceOffers(_, OfferEq(2, 1024)))
+ .WillOnce(FutureSatisfy(&resourceOffers));
driver.start();
- AWAIT_READY(offers);
-
- // The framework should be offered all of the resources on the slave
- // since it is the only framework in the cluster.
- EXPECT_THAT(offers.get(), OfferEq(2, 1024));
+ AWAIT_READY(resourceOffers);
// Shut everything down.
- EXPECT_CALL(this->allocator, resourcesRecovered(_, _, _));
+ EXPECT_CALL(this->allocator, resourcesRecovered(_, _, _))
+ .WillRepeatedly(DoDefault());
EXPECT_CALL(this->allocator, frameworkDeactivated(_))
- .WillRepeatedly(DoDefault());
+ .Times(AtMost(1));
- Future<Nothing> frameworkRemoved;
EXPECT_CALL(this->allocator, frameworkRemoved(_))
- .WillOnce(FutureSatisfy(&frameworkRemoved));
+ .Times(AtMost(1));
driver.stop();
+ driver.join();
- AWAIT_READY(frameworkRemoved);
-
- Future<Nothing> slaveRemoved;
EXPECT_CALL(this->allocator, slaveRemoved(_))
- .WillOnce(FutureSatisfy(&slaveRemoved));
-
- this->ShutdownSlaves();
-
- AWAIT_READY(slaveRemoved);
+ .Times(AtMost(1));
- this->ShutdownMasters();
+ this->Shutdown();
}
@@ -353,19 +347,25 @@ TYPED_TEST(AllocatorTest, ResourcesUnused)
EXPECT_CALL(this->allocator, frameworkAdded(_, _, _));
- Future<Nothing> resourcesUnused;
- EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _))
- .WillOnce(DoAll(InvokeResourcesUnused(&this->allocator),
- FutureSatisfy(&resourcesUnused)));
-
EXPECT_CALL(sched1, registered(_, _, _));
+ // We decline offers that we aren't expecting so that the resources
+ // get aggregated. Note that we need to do this _first_ and
+ // _separate_ from the expectation below so that this expectation is
+ // checked last and matches all possible offers.
+ EXPECT_CALL(sched1, resourceOffers(_, _))
+ .WillRepeatedly(DeclineOffers());
+
// The first offer will contain all of the slave's resources, since
// this is the only framework running so far. Launch a task that
// uses less than that to leave some resources unused.
EXPECT_CALL(sched1, resourceOffers(_, OfferEq(2, 1024)))
- .WillOnce(LaunchTasks(1, 1, 512))
- .WillRepeatedly(DeclineOffers());
+ .WillOnce(LaunchTasks(1, 1, 512));
+
+ Future<Nothing> resourcesUnused;
+ EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _))
+ .WillOnce(DoAll(InvokeResourcesUnused(&this->allocator),
+ FutureSatisfy(&resourcesUnused)));
EXPECT_CALL(exec, registered(_, _, _, _));
@@ -375,51 +375,55 @@ TYPED_TEST(AllocatorTest, ResourcesUnused)
driver1.start();
+ AWAIT_READY(launchTask);
+
+ // We need to wait until the allocator knows about the unused
+ // resources to start the second framework so that we get the
+ // expected offer.
AWAIT_READY(resourcesUnused);
- AWAIT_READY(launchTask);
+ FrameworkInfo frameworkInfo2;
+ frameworkInfo2.set_user("user2");
+ frameworkInfo2.set_name("framework2");
- FrameworkInfo info2;
- info2.set_user("user2");
- info2.set_name("framework2");
MockScheduler sched2;
- MesosSchedulerDriver driver2(&sched2, info2, master.get());
+ MesosSchedulerDriver driver2(&sched2, frameworkInfo2, master.get());
EXPECT_CALL(this->allocator, frameworkAdded(_, _, _));
EXPECT_CALL(sched2, registered(_, _, _));
- Future<vector<Offer> > offers;
- EXPECT_CALL(sched2, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers));
+ // We should expect that framework2 gets offered all of the
+ // resources on the slave not being used by the launched task.
+ Future<Nothing> resourceOffers;
+ EXPECT_CALL(sched2, resourceOffers(_, OfferEq(1, 512)))
+ .WillOnce(FutureSatisfy(&resourceOffers));
driver2.start();
- AWAIT_READY(offers);
-
- // framework2 will be offered all of the resources on the slave not
- // being used by the task that was launched.
- EXPECT_THAT(offers.get(), OfferEq(1, 512));
+ AWAIT_READY(resourceOffers);
// Shut everything down.
EXPECT_CALL(this->allocator, resourcesRecovered(_, _, _))
.WillRepeatedly(DoDefault());
EXPECT_CALL(this->allocator, frameworkDeactivated(_))
- .Times(2);
+ .Times(AtMost(2));
- Future<Nothing> frameworkRemoved;
EXPECT_CALL(this->allocator, frameworkRemoved(_))
- .WillOnce(DoDefault())
- .WillOnce(FutureSatisfy(&frameworkRemoved));
+ .Times(AtMost(2));
+ Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .Times(AtMost(1));
+ .WillOnce(FutureSatisfy(&shutdown));
driver1.stop();
+ driver1.join();
+
driver2.stop();
+ driver2.join();
- AWAIT_READY(frameworkRemoved);
+ AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
@@ -449,28 +453,31 @@ TYPED_TEST(AllocatorTest, OutOfOrderDispatch)
FrameworkInfo frameworkInfo1;
frameworkInfo1.set_user("user1");
frameworkInfo1.set_name("framework1");
+
MockScheduler sched1;
MesosSchedulerDriver driver1(&sched1, frameworkInfo1, master.get());
- FrameworkID frameworkId1;
EXPECT_CALL(this->allocator, frameworkAdded(_, Eq(frameworkInfo1), _))
- .WillOnce(DoAll(InvokeFrameworkAdded(&this->allocator),
- SaveArg<0>(&frameworkId1)));
+ .WillOnce(InvokeFrameworkAdded(&this->allocator));
- EXPECT_CALL(sched1, registered(_, _, _));
+ FrameworkID frameworkId1;
+ EXPECT_CALL(sched1, registered(_, _, _))
+ .WillOnce(SaveArg<1>(&frameworkId1));
- Future<vector<Offer> > offers1;
- EXPECT_CALL(sched1, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers1));
+ // All of the slave's resources should be offered to start.
+ Future<Nothing> resourceOffers;
+ EXPECT_CALL(sched1, resourceOffers(_, OfferEq(2, 1024)))
+ .WillOnce(FutureSatisfy(&resourceOffers));
driver1.start();
- AWAIT_READY(offers1);
-
- // framework1 will be offered all of the slave's resources, since
- // it is the only framework running right now.
- EXPECT_THAT(offers1.get(), OfferEq(2, 1024));
+ AWAIT_READY(resourceOffers);
+ // TODO(benh): I don't see why we want to "catch" (i.e., block) this
+ // resourcesRecovered call. It seems like we want this one to
+ // properly be executed and later we want to _inject_ a
+ // resourcesRecovered to simulate the code in Master::offer after a
+ // framework has terminated or is inactive.
FrameworkID frameworkId;
SlaveID slaveId;
Resources savedResources;
@@ -502,46 +509,45 @@ TYPED_TEST(AllocatorTest, OutOfOrderDispatch)
// that recovering resources from a removed framework works.
this->a->resourcesRecovered(frameworkId, slaveId, savedResources);
+ // TODO(benh): Seems like we should wait for the above
+ // resourcesRecovered to be executed.
+
FrameworkInfo frameworkInfo2;
frameworkInfo2.set_user("user2");
frameworkInfo2.set_name("framework2");
+
MockScheduler sched2;
MesosSchedulerDriver driver2(&sched2, frameworkInfo2, master.get());
- FrameworkID frameworkId2;
EXPECT_CALL(this->allocator, frameworkAdded(_, Eq(frameworkInfo2), _))
- .WillOnce(DoAll(InvokeFrameworkAdded(&this->allocator),
- SaveArg<0>(&frameworkId2)));
+ .WillOnce(InvokeFrameworkAdded(&this->allocator));
- EXPECT_CALL(sched2, registered(_, _, _));
+ FrameworkID frameworkId2;
+ EXPECT_CALL(sched2, registered(_, _, _))
+ .WillOnce(SaveArg<1>(&frameworkId2));
- Future<vector<Offer> > offers2;
- EXPECT_CALL(sched2, resourceOffers(_, _))
- .WillOnce(FutureArg<1>(&offers2));
+ // All of the slave's resources should be offered since no other
+ // frameworks should be running.
+ EXPECT_CALL(sched2, resourceOffers(_, OfferEq(2, 1024)))
+ .WillOnce(FutureSatisfy(&resourceOffers));
driver2.start();
- AWAIT_READY(offers2);
-
- // framework2 will be offered all of the slave's resources, since
- // it is the only framework running right now.
- EXPECT_THAT(offers2.get(), OfferEq(2, 1024));
+ AWAIT_READY(resourceOffers);
// Shut everything down.
EXPECT_CALL(this->allocator, resourcesRecovered(_, _, _))
.WillRepeatedly(DoDefault());
- EXPECT_CALL(this->allocator, frameworkDeactivated(_));
+ EXPECT_CALL(this->allocator, frameworkDeactivated(_))
+ .Times(AtMost(1));
- Future<Nothing> frameworkRemoved2;
EXPECT_CALL(this->allocator, frameworkRemoved(Eq(frameworkId2)))
- .WillOnce(FutureSatisfy(&frameworkRemoved2));
+ .Times(AtMost(1));
driver2.stop();
driver2.join();
- AWAIT_READY(frameworkRemoved2);
-
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
@@ -573,27 +579,33 @@ TYPED_TEST(AllocatorTest, SchedulerFailover)
frameworkInfo1.set_name("framework1");
frameworkInfo1.set_user("user1");
frameworkInfo1.set_failover_timeout(.1);
+
// Launch the first (i.e., failing) scheduler.
MockScheduler sched1;
MesosSchedulerDriver driver1(&sched1, frameworkInfo1, master.get());
EXPECT_CALL(this->allocator, frameworkAdded(_, _, _));
- // We don't filter the unused resources to make sure that
- // they get offered to the framework as soon as it fails over.
- EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _))
- .WillOnce(InvokeUnusedWithFilters(&this->allocator, 0));
-
FrameworkID frameworkId;
EXPECT_CALL(sched1, registered(&driver1, _, _))
.WillOnce(SaveArg<1>(&frameworkId));
- Future<vector<Offer> > offers1;
+ // We decline offers that we aren't expecting so that the resources
+ // get aggregated. Note that we need to do this _first_ and
+ // _separate_ from the expectation below so that this expectation is
+ // checked last and matches all possible offers.
EXPECT_CALL(sched1, resourceOffers(_, _))
- .WillOnce(DoAll(LaunchTasks(1, 1, 256),
- FutureArg<1>(&offers1)))
.WillRepeatedly(DeclineOffers());
+ // Initially, all of slave1's resources are avaliable.
+ EXPECT_CALL(sched1, resourceOffers(_, OfferEq(3, 1024)))
+ .WillOnce(LaunchTasks(1, 1, 256));
+
+ // We don't filter the unused resources to make sure that
+ // they get offered to the framework as soon as it fails over.
+ EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _))
+ .WillOnce(InvokeUnusedWithFilters(&this->allocator, 0));
+
EXPECT_CALL(exec, registered(_, _, _, _));
Future<Nothing> launchTask;
@@ -602,11 +614,6 @@ TYPED_TEST(AllocatorTest, SchedulerFailover)
driver1.start();
- AWAIT_READY(offers1);
-
- // Initially, all cluster resources are avaliable.
- EXPECT_THAT(offers1.get(), OfferEq(3, 1024));
-
// Ensures that the task has been completely launched
// before we have the framework fail over.
AWAIT_READY(launchTask);
@@ -614,7 +621,7 @@ TYPED_TEST(AllocatorTest, SchedulerFailover)
// When we shut down the first framework, we don't want it to tell
// the master it's shutting down so that the master will wait to see
// if it fails over.
- DROP_MESSAGES(Eq(UnregisterFrameworkMessage().GetTypeName()), _, _);
+ DROP_PROTOBUFS(UnregisterFrameworkMessage(), _, _);
Future<Nothing> frameworkDeactivated;
EXPECT_CALL(this->allocator, frameworkDeactivated(_))
@@ -625,13 +632,14 @@ TYPED_TEST(AllocatorTest, SchedulerFailover)
AWAIT_READY(frameworkDeactivated);
- FrameworkInfo framework2; // Bug in gcc 4.1.*, must assign on next line.
- framework2 = DEFAULT_FRAMEWORK_INFO;
- framework2.mutable_id()->MergeFrom(frameworkId);
+ FrameworkInfo frameworkInfo2; // Bug in gcc 4.1.*, must assign on next line.
+ frameworkInfo2 = DEFAULT_FRAMEWORK_INFO;
+ frameworkInfo2.mutable_id()->MergeFrom(frameworkId);
+
// Now launch the second (i.e., failover) scheduler using the
// framework id recorded from the first scheduler.
MockScheduler sched2;
- MesosSchedulerDriver driver2(&sched2, framework2, master.get());
+ MesosSchedulerDriver driver2(&sched2, frameworkInfo2, master.get());
EXPECT_CALL(this->allocator, frameworkActivated(_, _));
@@ -640,31 +648,32 @@ TYPED_TEST(AllocatorTest, SchedulerFailover)
// Even though the scheduler failed over, the 1 cpu, 512 mem
// task that it launched earlier should still be running, so
// only 2 cpus and 768 mem are available.
- Future<Nothing> resourceOffers2;
+ Future<Nothing> resourceOffers;
EXPECT_CALL(sched2, resourceOffers(_, OfferEq(2, 768)))
- .WillOnce(FutureSatisfy(&resourceOffers2));
+ .WillOnce(FutureSatisfy(&resourceOffers));
driver2.start();
- AWAIT_READY(resourceOffers2);
+ AWAIT_READY(resourceOffers);
// Shut everything down.
EXPECT_CALL(this->allocator, resourcesRecovered(_, _, _))
.WillRepeatedly(DoDefault());
- EXPECT_CALL(this->allocator, frameworkDeactivated(_));
+ EXPECT_CALL(this->allocator, frameworkDeactivated(_))
+ .Times(AtMost(1));
- Future<Nothing> frameworkRemoved;
EXPECT_CALL(this->allocator, frameworkRemoved(_))
- .WillOnce(FutureSatisfy(&frameworkRemoved));
+ .Times(AtMost(1));
+ Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .Times(AtMost(1));
+ .WillOnce(FutureSatisfy(&shutdown));
driver2.stop();
driver2.join();
- AWAIT_READY(frameworkRemoved);
+ AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
@@ -684,17 +693,9 @@ TYPED_TEST(AllocatorTest, FrameworkExited)
Try<PID<Master> > master = this->StartMaster(&this->allocator, masterFlags);
ASSERT_SOME(master);
+ // TODO(benh): We use this executor for two frameworks in this test
+ // which works but is brittle and harder to reason about.
MockExecutor exec(DEFAULT_EXECUTOR_ID);
- EXPECT_CALL(exec, registered(_, _, _, _))
- .Times(2);
-
- Future<Nothing> launchTask;
- EXPECT_CALL(exec, launchTask(_, _))
- .WillOnce(FutureSatisfy(&launchTask))
- .WillOnce(DoDefault());
-
- EXPECT_CALL(exec, shutdown(_))
- .Times(AtMost(2));
slave::Flags flags = this->CreateSlaveFlags();
flags.resources = Option<string>("cpus:3;mem:1024");
@@ -709,87 +710,110 @@ TYPED_TEST(AllocatorTest, FrameworkExited)
EXPECT_CALL(this->allocator, frameworkAdded(_, _, _));
- Future<Nothing> resourcesUnused;
- EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _))
- .WillOnce(DoAll(InvokeResourcesUnused(&this->allocator),
- FutureSatisfy(&resourcesUnused)));
-
EXPECT_CALL(sched1, registered(_, _, _));
+ // We decline offers that we aren't expecting so that the resources
+ // get aggregated. Note that we need to do this _first_ and
+ // _separate_ from the expectation below so that this expectation is
+ // checked last and matches all possible offers.
EXPECT_CALL(sched1, resourceOffers(_, _))
.WillRepeatedly(DeclineOffers());
- // The first time the framework is offered resources,
- // all of the cluster's resources should be avaliable.
- Future<Nothing> resourcesOffers1;
+ // The first time the framework is offered resources, all of the
+ // cluster's resources should be avaliable.
EXPECT_CALL(sched1, resourceOffers(_, OfferEq(3, 1024)))
- .WillOnce(DoAll(LaunchTasks(1, 2, 512),
- FutureSatisfy(&resourcesOffers1)));
+ .WillOnce(LaunchTasks(1, 2, 512));
- driver1.start();
+ // The framework does not use all the resources.
+ Future<Nothing> resourcesUnused;
+ EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _))
+ .WillOnce(DoAll(InvokeResourcesUnused(&this->allocator),
+ FutureSatisfy(&resourcesUnused)));
- AWAIT_READY(resourcesOffers1);
+ EXPECT_CALL(exec, registered(_, _, _, _));
- AWAIT_READY(resourcesUnused);
+ Future<Nothing> launchTask;
+ EXPECT_CALL(exec, launchTask(_, _))
+ .WillOnce(FutureSatisfy(&launchTask));
+
+ driver1.start();
// Ensures that framework 1's task is completely launched
// before we kill the framework to test if its resources
// are recovered correctly.
AWAIT_READY(launchTask);
+ // We need to wait until the allocator knows about the unused
+ // resources to start the second framework so that we get the
+ // expected offer.
+ AWAIT_READY(resourcesUnused);
+
MockScheduler sched2;
MesosSchedulerDriver driver2(&sched2, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(this->allocator, frameworkAdded(_, _, _));
- EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _));
-
EXPECT_CALL(sched2, registered(_, _, _));
+ // We decline offers that we aren't expecting so that the resources
+ // get aggregated. Note that we need to do this _first_ and
+ // _separate_ from the expectation below so that this expectation is
+ // checked last and matches all possible offers.
EXPECT_CALL(sched2, resourceOffers(_, _))
.WillRepeatedly(DeclineOffers());
- // The first time sched2 gets an offer, framework 1 has a
- // task running with 2 cpus and 512 mem, leaving 1 cpu and 512 mem.
- Future<Nothing> resourceOffers2;
+ // The first time sched2 gets an offer, framework 1 has a task
+ // running with 2 cpus and 512 mem, leaving 1 cpu and 512 mem.
EXPECT_CALL(sched2, resourceOffers(_, OfferEq(1, 512)))
- .WillOnce(DoAll(LaunchTasks(1, 1, 256),
- FutureSatisfy(&resourceOffers2)));
+ .WillOnce(LaunchTasks(1, 1, 256));
+
+ EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _));
+
+ EXPECT_CALL(exec, registered(_, _, _, _));
+
+ EXPECT_CALL(exec, launchTask(_, _))
+ .WillOnce(FutureSatisfy(&launchTask));
driver2.start();
- AWAIT_READY(resourceOffers2);
+ AWAIT_READY(launchTask);
+ // Shut everything down but check that framework 2 gets the
+ // resources from framework 1 after it is shutdown.
EXPECT_CALL(this->allocator, resourcesRecovered(_, _, _))
.WillRepeatedly(DoDefault());
- EXPECT_CALL(this->allocator, frameworkDeactivated(_));
+ EXPECT_CALL(this->allocator, frameworkDeactivated(_))
+ .Times(AtMost(2)); // Once for each framework.
- EXPECT_CALL(this->allocator, frameworkRemoved(_));
+ EXPECT_CALL(this->allocator, frameworkRemoved(_))
+ .Times(AtMost(2)); // Once for each framework.
- // After we kill framework 1, all of it's resources should
+ // After we stop framework 1, all of it's resources should
// have been returned, but framework 2 should still have a
// task with 1 cpu and 256 mem, leaving 2 cpus and 768 mem.
- Future<Nothing> resourceOffers3;
+ Future<Nothing> resourceOffers;
EXPECT_CALL(sched2, resourceOffers(_, OfferEq(2, 768)))
- .WillOnce(FutureSatisfy(&resourceOffers3));
+ .WillOnce(FutureSatisfy(&resourceOffers));
+
+ Future<Nothing> shutdown;
+ EXPECT_CALL(exec, shutdown(_))
+ .WillOnce(FutureSatisfy(&shutdown));
driver1.stop();
driver1.join();
- AWAIT_READY(resourceOffers3);
+ AWAIT_READY(resourceOffers);
- // Shut everything down.
- EXPECT_CALL(this->allocator, frameworkDeactivated(_));
+ AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
- Future<Nothing> frameworkRemoved;
- EXPECT_CALL(this->allocator, frameworkRemoved(_))
- .WillOnce(FutureSatisfy(&frameworkRemoved));
+ EXPECT_CALL(exec, shutdown(_))
+ .WillOnce(FutureSatisfy(&shutdown));
driver2.stop();
driver2.join();
- AWAIT_READY(frameworkRemoved);
+ AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
@@ -819,23 +843,18 @@ TYPED_TEST(AllocatorTest, SlaveLost)
Try<PID<Slave> > slave1 = this->StartSlave(&exec, flags1);
ASSERT_SOME(slave1);
- MockScheduler sched1;
- MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master.get());
+ MockScheduler sched;
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(this->allocator, frameworkAdded(_, _, _));
- EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _));
-
- EXPECT_CALL(sched1, registered(_, _, _));
+ EXPECT_CALL(sched, registered(_, _, _));
- EXPECT_CALL(sched1, statusUpdate(_, _))
- .WillRepeatedly(DoDefault());
+ // Initially, all of slave1's resources are available.
+ EXPECT_CALL(sched, resourceOffers(_, OfferEq(2, 1024)))
+ .WillOnce(LaunchTasks(1, 2, 512));
- Future<vector<Offer> > resourceOffers1;
- // Initially, all of slave1's resources are avaliable.
- EXPECT_CALL(sched1, resourceOffers(_, OfferEq(2, 1024)))
- .WillOnce(DoAll(LaunchTasks(1, 2, 512),
- FutureArg<1>(&resourceOffers1)));
+ EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _));
EXPECT_CALL(exec, registered(_, _, _, _));
@@ -844,11 +863,10 @@ TYPED_TEST(AllocatorTest, SlaveLost)
.WillOnce(DoAll(SendStatusUpdateFromTask(TASK_RUNNING),
FutureSatisfy(&launchTask)));
- driver1.start();
-
- AWAIT_READY(resourceOffers1);
+ EXPECT_CALL(sched, statusUpdate(_, _))
+ .WillRepeatedly(DoDefault());
- EXPECT_THAT(resourceOffers1.get(), OfferEq(2, 1024));
+ driver.start();
// Ensures the task is completely launched before we
// kill the slave, to test that the task's resources
@@ -858,22 +876,22 @@ TYPED_TEST(AllocatorTest, SlaveLost)
EXPECT_CALL(this->allocator, resourcesRecovered(_, _, _));
- Future<Nothing> slaveRemoved1;
+ Future<Nothing> slaveRemoved;
EXPECT_CALL(this->allocator, slaveRemoved(_))
.WillOnce(DoAll(InvokeSlaveRemoved(&this->allocator),
- FutureSatisfy(&slaveRemoved1)));
+ FutureSatisfy(&slaveRemoved)));
- Future<Nothing> shutdownCall;
+ Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .WillOnce(FutureSatisfy(&shutdownCall));
+ .WillOnce(FutureSatisfy(&shutdown));
- EXPECT_CALL(sched1, slaveLost(_, _));
+ EXPECT_CALL(sched, slaveLost(_, _));
this->ShutdownSlaves();
- AWAIT_READY(slaveRemoved1);
+ AWAIT_READY(slaveRemoved);
- AWAIT_READY(shutdownCall);
+ AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
MockExecutor exec2(DEFAULT_EXECUTOR_ID);
@@ -885,34 +903,32 @@ TYPED_TEST(AllocatorTest, SlaveLost)
// Eventually after slave2 is launched, we should get
// an offer that contains all of slave2's resources
// and none of slave1's resources.
- Future<vector<Offer> > resourceOffers2;
- EXPECT_CALL(sched1, resourceOffers(_, OfferEq(3, 256)))
- .WillOnce(FutureArg<1>(&resourceOffers2));
+ Future<Nothing> resourceOffers;
+ EXPECT_CALL(sched, resourceOffers(_, OfferEq(3, 256)))
+ .WillOnce(FutureSatisfy(&resourceOffers));
Try<PID<Slave> > slave2 = this->StartSlave(&exec2, flags2);
ASSERT_SOME(slave2);
- AWAIT_READY(resourceOffers2);
-
- EXPECT_THAT(resourceOffers2.get(), OfferEq(3, 256));
+ AWAIT_READY(resourceOffers);
// Shut everything down.
EXPECT_CALL(this->allocator, resourcesRecovered(_, _, _))
.WillRepeatedly(DoDefault());
- EXPECT_CALL(this->allocator, frameworkDeactivated(_));
+ EXPECT_CALL(this->allocator, frameworkDeactivated(_))
+ .Times(AtMost(1));
- Future<Nothing> frameworkRemoved;
EXPECT_CALL(this->allocator, frameworkRemoved(_))
- .WillOnce(FutureSatisfy(&frameworkRemoved));
+ .Times(AtMost(1));
EXPECT_CALL(exec2, shutdown(_))
- .Times(AtMost(1));
+ .WillOnce(FutureSatisfy(&shutdown));
- driver1.stop();
- driver1.join();
+ driver.stop();
+ driver.join();
- AWAIT_READY(frameworkRemoved);
+ AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
@@ -943,33 +959,32 @@ TYPED_TEST(AllocatorTest, SlaveAdded)
Try<PID<Slave> > slave1 = this->StartSlave(&exec, flags1);
ASSERT_SOME(slave1);
- MockScheduler sched1;
- MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master.get());
+ MockScheduler sched;
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(this->allocator, frameworkAdded(_, _, _));
+ EXPECT_CALL(sched, registered(_, _, _));
+
+ // We decline offers that we aren't expecting so that the resources
+ // get aggregated. Note that we need to do this _first_ and
+ // _separate_ from the expectation below so that this expectation is
+ // checked last and matches all possible offers.
+ EXPECT_CALL(sched, resourceOffers(_, _))
+ .WillRepeatedly(DeclineOffers());
+
+ // Initially, all of slave1's resources are avaliable.
+ EXPECT_CALL(sched, resourceOffers(_, OfferEq(3, 1024)))
+ .WillOnce(LaunchTasks(1, 2, 512));
+
// We filter the first time so that the unused resources
// on slave1 from the task launch won't get reoffered
// immediately and will get combined with slave2's
// resources for a single offer.
EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _))
- .WillOnce(InvokeUnusedWithFilters(&this->allocator, .1))
+ .WillOnce(InvokeUnusedWithFilters(&this->allocator, 0.1))
.WillRepeatedly(InvokeUnusedWithFilters(&this->allocator, 0));
- EXPECT_CALL(sched1, registered(_, _, _));
-
- EXPECT_CALL(sched1, statusUpdate(_, _))
- .WillRepeatedly(DoDefault());
-
- EXPECT_CALL(sched1, resourceOffers(_, _))
- .WillRepeatedly(DeclineOffers());
-
- // Initially, all of slave1's resources are avaliable.
- Future<Nothing> resourceOffers1;
- EXPECT_CALL(sched1, resourceOffers(_, OfferEq(3, 1024)))
- .WillOnce(DoAll(LaunchTasks(1, 2, 512),
- FutureSatisfy(&resourceOffers1)));
-
EXPECT_CALL(exec, registered(_, _, _, _));
Future<Nothing> launchTask;
@@ -977,9 +992,10 @@ TYPED_TEST(AllocatorTest, SlaveAdded)
.WillOnce(DoAll(SendStatusUpdateFromTask(TASK_RUNNING),
FutureSatisfy(&launchTask)));
- driver1.start();
+ EXPECT_CALL(sched, statusUpdate(_, _))
+ .WillRepeatedly(DoDefault());
- AWAIT_READY(resourceOffers1);
+ driver.start();
AWAIT_READY(launchTask);
@@ -988,35 +1004,35 @@ TYPED_TEST(AllocatorTest, SlaveAdded)
EXPECT_CALL(this->allocator, slaveAdded(_, _, _));
- // After slave2 launches, all of its resources are
- // combined with the resources on slave1 that the
- // task isn't using.
- Future<Nothing> resourceOffers2;
- EXPECT_CALL(sched1, resourceOffers(_, OfferEq(5, 2560)))
- .WillOnce(FutureSatisfy(&resourceOffers2));
+ // After slave2 launches, all of its resources are combined with the
+ // resources on slave1 that the task isn't using.
+ Future<Nothing> resourceOffers;
+ EXPECT_CALL(sched, resourceOffers(_, OfferEq(5, 2560)))
+ .WillOnce(FutureSatisfy(&resourceOffers));
Try<PID<Slave> > slave2 = this->StartSlave(flags2);
ASSERT_SOME(slave2);
- AWAIT_READY(resourceOffers2);
+ AWAIT_READY(resourceOffers);
// Shut everything down.
EXPECT_CALL(this->allocator, resourcesRecovered(_, _, _))
.WillRepeatedly(DoDefault());
- EXPECT_CALL(this->allocator, frameworkDeactivated(_));
+ EXPECT_CALL(this->allocator, frameworkDeactivated(_))
+ .Times(AtMost(1));
- Future<Nothing> frameworkRemoved;
EXPECT_CALL(this->allocator, frameworkRemoved(_))
- .WillOnce(FutureSatisfy(&frameworkRemoved));
+ .Times(AtMost(1));
+ Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .Times(AtMost(1));
+ .WillOnce(FutureSatisfy(&shutdown));
- driver1.stop();
- driver1.join();
+ driver.stop();
+ driver.join();
- AWAIT_READY(frameworkRemoved);
+ AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(2));
@@ -1046,35 +1062,32 @@ TYPED_TEST(AllocatorTest, TaskFinished)
Try<PID<Slave> > slave = this->StartSlave(&exec, flags);
ASSERT_SOME(slave);
- MockScheduler sched1;
- MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master.get());
+ MockScheduler sched;
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(this->allocator, frameworkAdded(_, _, _));
- // We don't filter because we want to see the unused resources
- // from the task launch get reoffered to us.
- EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _))
- .WillRepeatedly(InvokeUnusedWithFilters(&this->allocator, 0));
-
- EXPECT_CALL(sched1, registered(_, _, _));
-
- EXPECT_CALL(sched1, statusUpdate(_, _))
- .WillRepeatedly(DoDefault());
+ EXPECT_CALL(sched, registered(_, _, _));
- EXPECT_CALL(sched1, resourceOffers(_, _))
+ // We decline offers that we aren't expecting so that the resources
+ // get aggregated. Note that we need to do this _first_ and
+ // _separate_ from the expectation below so that this expectation is
+ // checked last and matches all possible offers.
+ EXPECT_CALL(sched, resourceOffers(_, _))
.WillRepeatedly(DeclineOffers());
// Initially, all of the slave's resources.
- Future<Nothing> resourceOffers1;
- EXPECT_CALL(sched1, resourceOffers(_, OfferEq(3, 1024)))
- .WillOnce(DoAll(LaunchTasks(2, 1, 256),
- FutureSatisfy(&resourceOffers1)));
+ EXPECT_CALL(sched, resourceOffers(_, OfferEq(3, 1024)))
+ .WillOnce(LaunchTasks(2, 1, 256));
- // After the tasks are launched.
- Future<Nothing> resourceOffers2;
- EXPECT_CALL(sched1, resourceOffers(_, OfferEq(1, 512)))
- .WillOnce(DoAll(DeclineOffers(),
- FutureSatisfy(&resourceOffers2)));
+ // Some resources will be unused and we need to make sure that we
+ // don't send the TASK_FINISHED status update below until after the
+ // allocator knows about the unused resources so that it can
+ // aggregate them with the resources from the finished task.
+ Future<Nothing> resourcesUnused;
+ EXPECT_CALL(this->allocator, resourcesUnused(_, _, _, _))
+ .WillRepeatedly(DoAll(InvokeResourcesUnused(&this->allocator),
+ FutureSatisfy(&resourcesUnused)));
EXPECT_CALL(exec, registered(_, _, _, _));
@@ -1088,13 +1101,14 @@ TYPED_TEST(AllocatorTest, TaskFinished)
FutureSatisfy(&launchTask)))
.WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));
- driver1.start();
+ EXPECT_CALL(sched, statusUpdate(_, _))
+ .WillRepeatedly(DoDefault());
- AWAIT_READY(resourceOffers1);
+ driver.start();
AWAIT_READY(launchTask);
- AWAIT_READY(resourceOffers2);
+ AWAIT_READY(resourcesUnused);
TaskStatus status;
status.mutable_task_id()->MergeFrom(taskInfo.task_id());
@@ -1103,31 +1117,32 @@ TYPED_TEST(AllocatorTest, TaskFinished)
EXPECT_CALL(this->allocator, resourcesRecovered(_, _, _));
// After the first task gets killed.
- Future<Nothing> resourceOffers3;
- EXPECT_CALL(sched1, resourceOffers(_, OfferEq(2, 768)))
- .WillOnce(FutureSatisfy(&resourceOffers3));
+ Future<Nothing> resourceOffers;
+ EXPECT_CALL(sched, resourceOffers(_, OfferEq(2, 768)))
+ .WillOnce(FutureSatisfy(&resourceOffers));
execDriver->sendStatusUpdate(status);
- AWAIT_READY(resourceOffers3);
+ AWAIT_READY(resourceOffers);
// Shut everything down.
EXPECT_CALL(this->allocator, resourcesRecovered(_, _, _))
.WillRepeatedly(DoDefault());
- EXPECT_CALL(this->allocator, frameworkDeactivated(_));
+ EXPECT_CALL(this->allocator, frameworkDeactivated(_))
+ .Times(AtMost(1));
- Future<Nothing> frameworkRemoved;
EXPECT_CALL(this->allocator, frameworkRemoved(_))
- .WillOnce(FutureSatisfy(&frameworkRemoved));
+ .Times(AtMost(1));
+ Future<Nothing> shutdown;
EXPECT_CALL(exec, shutdown(_))
- .Times(AtMost(1));
+ .WillOnce(FutureSatisfy(&shutdown));
- driver1.stop();
- driver1.join();
+ driver.stop();
+ driver.join();
- AWAIT_READY(frameworkRemoved);
+ AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
@@ -1216,17 +1231,15 @@ TYPED_TEST(AllocatorTest, WhitelistSlave)
EXPECT_CALL(this->allocator, resourcesRecovered(_, _, _))
.WillRepeatedly(DoDefault());
- EXPECT_CALL(this->allocator, frameworkDeactivated(_));
+ EXPECT_CALL(this->allocator, frameworkDeactivated(_))
+ .Times(AtMost(1));
- Future<Nothing> frameworkRemoved;
EXPECT_CALL(this->allocator, frameworkRemoved(_))
- .WillOnce(FutureSatisfy(&frameworkRemoved));
+ .Times(AtMost(1));
driver.stop();
driver.join();
- AWAIT_READY(frameworkRemoved);
-
EXPECT_CALL(this->allocator, slaveRemoved(_))
.Times(AtMost(1));
[16/28] git commit: Cleanups in configure.ac.
Posted by be...@apache.org.
Cleanups in configure.ac.
Review: https://reviews.apache.org/r/11282
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/1e35e9e3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/1e35e9e3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/1e35e9e3
Branch: refs/heads/master
Commit: 1e35e9e3862c1586c4e2b3603b60faec1014fec4
Parents: 5e87116
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sun May 19 20:29:11 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 00:13:41 2013 -0700
----------------------------------------------------------------------
third_party/libprocess/configure.ac | 23 +++++++++++------------
1 files changed, 11 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1e35e9e3/third_party/libprocess/configure.ac
----------------------------------------------------------------------
diff --git a/third_party/libprocess/configure.ac b/third_party/libprocess/configure.ac
index 329fa47..efa7783 100644
--- a/third_party/libprocess/configure.ac
+++ b/third_party/libprocess/configure.ac
@@ -69,6 +69,15 @@ AC_ARG_WITH([zlib],
will be far less responsive; not recommended]),
[], [with_zlib=yes])
+# Do some OS specific setup.
+case "${target_os}" in
+ linux*)
+ LIBS="$LIBS -lrt" # For clock_gettime() in stout/stopwatch.hpp.
+ OS_NAME=linux # Used below for OS_LINUX.
+ ;;
+ *)
+ ;;
+esac
# Checks for gcc toolchain (we rely on some atomic builtins for now).
AC_PROG_CXX([g++])
@@ -101,18 +110,8 @@ fi
AM_CONDITIONAL([HAS_GPERFTOOLS], [test "x$gperftools" = "xyes"])
-# Added for clock_gettime() call in stout/stopwatch.hpp.
-# We also only want to use stout/proc.hpp on linux.
-case "${target_os}" in
- linux*)
- LIBS="$LIBS -lrt"
- OS_NAME=linux
- ;;
- *)
- ;;
-esac
-
-# Used for conditionally including source files.
+# Used for conditionally building source files (e.g., only want to
+# build stout/tests/proc_tests.cpp on Linux).
AM_CONDITIONAL([OS_LINUX], [test "x$OS_NAME" = "xlinux"])
AC_OUTPUT
[23/28] git commit: Fixed synchronization bug when waiting for a
process.
Posted by be...@apache.org.
Fixed synchronization bug when waiting for a process.
Review: https://reviews.apache.org/r/11351
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/6958e6d2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/6958e6d2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/6958e6d2
Branch: refs/heads/master
Commit: 6958e6d298bf211fe199a0560d601a5aea6f8590
Parents: 50d93fc
Author: Benjamin Hindman <be...@twitter.com>
Authored: Tue May 21 23:34:07 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 09:28:38 2013 -0700
----------------------------------------------------------------------
third_party/libprocess/src/process.cpp | 19 ++++++++++++-------
1 files changed, 12 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6958e6d2/third_party/libprocess/src/process.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/process.cpp b/third_party/libprocess/src/process.cpp
index 91b00f8..56f1ec5 100644
--- a/third_party/libprocess/src/process.cpp
+++ b/third_party/libprocess/src/process.cpp
@@ -2545,15 +2545,20 @@ void ProcessManager::cleanup(ProcessBase* process)
// process until after we have used the process in
// SocketManager::exited).
socket_manager->exited(process);
- }
- // ***************************************************************
- // At this point we can no longer dereference the process since it
- // might already be deallocated (e.g., by the garbage collector).
- // ***************************************************************
+ // ***************************************************************
+ // At this point we can no longer dereference the process since it
+ // might already be deallocated (e.g., by the garbage collector).
+ // ***************************************************************
- if (gate != NULL) {
- gate->open();
+ // Note that we need to open the gate while synchronized on
+ // processes because otherwise we might _open_ the gate before
+ // another thread _approaches_ the gate causing that thread to
+ // wait on _arrival_ to the gate forever (see
+ // ProcessManager::wait).
+ if (gate != NULL) {
+ gate->open();
+ }
}
}
[20/28] git commit: Removed unused local::launch overload.
Posted by be...@apache.org.
Removed unused local::launch overload.
Review: https://reviews.apache.org/r/11281
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/5e871160
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/5e871160
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/5e871160
Branch: refs/heads/master
Commit: 5e87116047fd16da5a6923b7ce3f558c76520644
Parents: 5690d20
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sun May 12 14:21:37 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 00:13:41 2013 -0700
----------------------------------------------------------------------
src/local/local.cpp | 20 --------------------
src/local/local.hpp | 17 +++--------------
2 files changed, 3 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5e871160/src/local/local.cpp
----------------------------------------------------------------------
diff --git a/src/local/local.cpp b/src/local/local.cpp
index f43ab2a..eb33e5d 100644
--- a/src/local/local.cpp
+++ b/src/local/local.cpp
@@ -73,26 +73,6 @@ static map<Isolator*, Slave*> slaves;
static MasterDetector* detector = NULL;
static Files* files = NULL;
-PID<Master> launch(
- int numSlaves,
- double cpus,
- uint64_t mem,
- uint64_t disk,
- bool quiet,
- Allocator* _allocator)
-{
- Configuration configuration;
- configuration.set("slaves", "*");
- configuration.set("num_slaves", numSlaves);
- configuration.set("quiet", quiet);
-
- stringstream out;
- out << "cpus:" << cpus << ";" << "mem:" << mem << ";" << "disk:" << disk;
- configuration.set("resources", out.str());
-
- return launch(configuration, _allocator);
-}
-
PID<Master> launch(const Configuration& configuration, Allocator* _allocator)
{
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5e871160/src/local/local.hpp
----------------------------------------------------------------------
diff --git a/src/local/local.hpp b/src/local/local.hpp
index 2633d25..51324e2 100644
--- a/src/local/local.hpp
+++ b/src/local/local.hpp
@@ -36,21 +36,10 @@ class Configuration;
namespace local {
-
-// Launch a local cluster with a given number of slaves and given numbers
-// of CPUs and memory per slave. Additionally one can also toggle whether
-// to initialize Google Logging and whether to log quietly.
-process::PID<master::Master> launch(int numSlaves,
- double cpus,
- uint64_t mem,
- uint64_t disk,
- bool quiet,
- master::Allocator* _allocator = NULL);
-
-
// Launch a local cluster with a given configuration.
-process::PID<master::Master> launch(const Configuration& configuration,
- master::Allocator* _allocator = NULL);
+process::PID<master::Master> launch(
+ const Configuration& configuration,
+ master::Allocator* _allocator = NULL);
void shutdown();
[10/28] Refactored MesosTest/MesosClusterTest into a generic fixture
for launching in-memory Mesos clusters and updated all tests appropriately.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/utils.hpp
----------------------------------------------------------------------
diff --git a/src/tests/utils.hpp b/src/tests/utils.hpp
index 60e4678..3b80933 100644
--- a/src/tests/utils.hpp
+++ b/src/tests/utils.hpp
@@ -19,76 +19,16 @@
#ifndef __TESTS_UTILS_HPP__
#define __TESTS_UTILS_HPP__
-#include <unistd.h> // For usleep.
+#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
-#include <fstream>
-#include <map>
#include <string>
-#include <mesos/executor.hpp>
-#include <mesos/scheduler.hpp>
-
-#include <process/future.hpp>
-#include <process/gmock.hpp>
-#include <process/gtest.hpp>
-#include <process/http.hpp>
-#include <process/process.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/gtest.hpp>
-#include <stout/lambda.hpp>
-#include <stout/nothing.hpp>
#include <stout/option.hpp>
-#include <stout/os.hpp>
-#include <stout/path.hpp>
-#include <stout/stringify.hpp>
-#include <stout/try.hpp>
-#include <stout/uuid.hpp>
-
-#include "common/resources.hpp"
-#include "common/type_utils.hpp"
-
-#ifdef __linux__
-#include "linux/cgroups.hpp"
-#endif
-
-#include "logging/logging.hpp"
-
-#include "master/allocator.hpp"
-#include "master/drf_sorter.hpp"
-#include "master/hierarchical_allocator_process.hpp"
-#include "master/master.hpp"
-
-#include "messages/messages.hpp"
-
-#ifdef __linux__
-#include "slave/cgroups_isolator.hpp"
-#endif
-#include "slave/isolator.hpp"
-#include "slave/reaper.hpp"
-#include "slave/slave.hpp"
-#include "slave/state.hpp"
-
-#include "tests/cluster.hpp"
-#include "tests/environment.hpp"
-#include "tests/flags.hpp"
-#include "tests/isolator.hpp"
namespace mesos {
namespace internal {
namespace tests {
-#ifdef __linux__
-// Cgroups hierarchy used by the cgroups related tests.
-const static std::string TEST_CGROUPS_HIERARCHY = "/tmp/mesos_test_cgroup";
-
-// Name of the root cgroup used by the cgroups related tests.
-const static std::string TEST_CGROUPS_ROOT = "mesos_test";
-#endif
-
-
// Test fixture for creating a temporary directory for each test.
class TemporaryDirectoryTest : public ::testing::Test
{
@@ -101,671 +41,6 @@ private:
Option<std::string> sandbox;
};
-
-// Test fixture to setup mesos configuration for tests.
-// This fixture creates a new temporary working directory for each test and
-// deletes it when a test finishes. It also supports setting slave resources.
-// TODO(vinod): Make this fixture more generic to provide a basic set of
-// setup abstractions for tests.
-class MesosTest : public ::testing::Test
-{
-protected:
- virtual void SetUp()
- {
- // Create a temporary directory for the test.
- Try<std::string> directory = environment->mkdtemp();
-
- CHECK(directory.isSome())
- << "Failed to create temporary directory: " << directory.error();
-
- slaveFlags.work_dir = directory.get();
- slaveFlags.launcher_dir = path::join(tests::flags.build_dir, "src");
-
- // For locating killtree.sh.
- os::setenv("MESOS_SOURCE_DIR", tests::flags.source_dir);
-
- setSlaveResources("cpus:2;mem:1024;disk:1024;ports:[31000-32000]");
- }
-
- virtual void TearDown()
- {
- os::rmdir(slaveFlags.work_dir);
-
- os::unsetenv("MESOS_SOURCE_DIR");
- }
-
- void setSlaveResources(const std::string& resources)
- {
- slaveFlags.resources = Option<std::string>::some(resources);
- }
-
- slave::Flags slaveFlags;
-};
-
-
-class MesosClusterTest : public ::testing::Test
-{
-protected:
- virtual void SetUp()
- {
- // Create a temporary directory for the test.
- Try<std::string> directory = environment->mkdtemp();
-
- CHECK(directory.isSome())
- << "Failed to create temporary directory: " << directory.error();
-
- cluster.slaves.flags.work_dir = directory.get();
- cluster.slaves.flags.launcher_dir =
- path::join(tests::flags.build_dir, "src");
-
- // For locating killtree.sh.
- os::setenv("MESOS_SOURCE_DIR", tests::flags.source_dir);
-
- cluster.slaves.flags.resources =
- Option<std::string>("cpus:2;mem:1024;disk:1024;ports:[31000-32000]");
- }
-
- virtual void TearDown()
- {
- os::rmdir(cluster.slaves.flags.work_dir);
-
- os::unsetenv("MESOS_SOURCE_DIR");
- }
-
- Cluster cluster;
-};
-
-
-
-template <typename T>
-class IsolatorTest : public MesosTest
-{};
-
-
-#ifdef __linux__
-template <>
-class IsolatorTest<slave::CgroupsIsolator> : public MesosTest
-{
-public:
- static void SetUpTestCase()
- {
- // Clean up the testing hierarchy, in case it wasn't cleaned up
- // properly from previous tests.
- AWAIT_READY(cgroups::cleanup(TEST_CGROUPS_HIERARCHY));
- }
-
- static void TearDownTestCase()
- {
- AWAIT_READY(cgroups::cleanup(TEST_CGROUPS_HIERARCHY));
- }
-
-protected:
- virtual void SetUp()
- {
- const std::string subsystems = "cpu,cpuacct,memory,freezer";
- Result<std::string> hierarchy_ = cgroups::hierarchy(subsystems);
- ASSERT_FALSE(hierarchy_.isError());
- if (hierarchy_.isNone()) {
- // Try to mount a hierarchy for testing.
- ASSERT_SOME(cgroups::mount(TEST_CGROUPS_HIERARCHY, subsystems))
- << "-------------------------------------------------------------\n"
- << "We cannot run any cgroups tests that require\n"
- << "a hierarchy with subsystems '" << subsystems << "'\n"
- << "because we failed to find an existing hierarchy\n"
- << "or create a new one. You can either remove all existing\n"
- << "hierarchies, or disable this test case\n"
- << "(i.e., --gtest_filter=-"
- << ::testing::UnitTest::GetInstance()
- ->current_test_info()
- ->test_case_name() << ".*).\n"
- << "-------------------------------------------------------------";
-
- hierarchy = TEST_CGROUPS_HIERARCHY;
- } else {
- hierarchy = hierarchy_.get();
- }
-
- MesosTest::SetUp();
-
- // Set slave's cgroup flags.
- slaveFlags.cgroups_hierarchy = hierarchy;
- slaveFlags.cgroups_root = TEST_CGROUPS_ROOT;
- }
-
- virtual void TearDown()
- {
- MesosTest::TearDown();
-
- Try<bool> exists = cgroups::exists(hierarchy, TEST_CGROUPS_ROOT);
- ASSERT_SOME(exists);
- if (exists.get()) {
- AWAIT_READY(cgroups::destroy(hierarchy, TEST_CGROUPS_ROOT));
- }
- }
-
-private:
- std::string hierarchy;
-};
-#endif
-
-
-// Macros to get/create (default) ExecutorInfos and FrameworkInfos.
-#define DEFAULT_EXECUTOR_INFO \
- ({ ExecutorInfo executor; \
- executor.mutable_executor_id()->set_value("default"); \
- executor.mutable_command()->set_value("exit 1"); \
- executor; })
-
-
-#define CREATE_EXECUTOR_INFO(executorId, command) \
- ({ ExecutorInfo executor; \
- executor.mutable_executor_id()->MergeFrom(executorId); \
- executor.mutable_command()->set_value(command); \
- executor; })
-
-
-#define DEFAULT_FRAMEWORK_INFO \
- ({ FrameworkInfo framework; \
- framework.set_name("default"); \
- framework; })
-
-
-#define DEFAULT_EXECUTOR_ID \
- DEFAULT_EXECUTOR_INFO.executor_id()
-
-
-inline TaskInfo createTask(
- const Offer& offer,
- const std::string& command,
- const std::string& name = "test-task",
- const std::string& id = UUID::random().toString())
-{
- TaskInfo task;
- task.set_name(name);
- task.mutable_task_id()->set_value(id);
- task.mutable_slave_id()->MergeFrom(offer.slave_id());
- task.mutable_resources()->MergeFrom(offer.resources());
- task.mutable_command()->set_value(command);
-
- return task;
-}
-
-
-// Definition of a mock Scheduler to be used in tests with gmock.
-class MockScheduler : public Scheduler
-{
-public:
- MOCK_METHOD3(registered, void(SchedulerDriver*,
- const FrameworkID&,
- const MasterInfo&));
- MOCK_METHOD2(reregistered, void(SchedulerDriver*, const MasterInfo&));
- MOCK_METHOD1(disconnected, void(SchedulerDriver*));
- MOCK_METHOD2(resourceOffers, void(SchedulerDriver*,
- const std::vector<Offer>&));
- MOCK_METHOD2(offerRescinded, void(SchedulerDriver*, const OfferID&));
- MOCK_METHOD2(statusUpdate, void(SchedulerDriver*, const TaskStatus&));
- MOCK_METHOD4(frameworkMessage, void(SchedulerDriver*,
- const ExecutorID&,
- const SlaveID&,
- const std::string&));
- MOCK_METHOD2(slaveLost, void(SchedulerDriver*, const SlaveID&));
- MOCK_METHOD4(executorLost, void(SchedulerDriver*,
- const ExecutorID&,
- const SlaveID&,
- int));
- MOCK_METHOD2(error, void(SchedulerDriver*, const std::string&));
-};
-
-// For use with a MockScheduler, for example:
-// EXPECT_CALL(sched, resourceOffers(_, _))
-// .WillOnce(LaunchTasks(TASKS, CPUS, MEM));
-// Launches up to TASKS no-op tasks, if possible,
-// each with CPUS cpus and MEM memory.
-ACTION_P3(LaunchTasks, tasks, cpus, mem)
-{
- SchedulerDriver* driver = arg0;
- std::vector<Offer> offers = arg1;
- int numTasks = tasks;
-
- int launched = 0;
- for (size_t i = 0; i < offers.size(); i++) {
- const Offer& offer = offers[i];
- double offeredCpus = 0;
- double offeredMem = 0;
-
- for (int j = 0; j < offer.resources_size(); j++) {
- const Resource& resource = offer.resources(j);
- if (resource.name() == "cpus" &&
- resource.type() == Value::SCALAR) {
- offeredCpus = resource.scalar().value();
- } else if (resource.name() == "mem" &&
- resource.type() == Value::SCALAR) {
- offeredMem = resource.scalar().value();
- }
- }
-
- int nextTaskId = 0;
- std::vector<TaskInfo> tasks;
-
- while (offeredCpus >= cpus && offeredMem >= mem && launched < numTasks) {
- TaskInfo task;
- task.set_name("TestTask");
- task.mutable_task_id()->set_value(stringify(nextTaskId++));
- task.mutable_slave_id()->MergeFrom(offer.slave_id());
-
- ExecutorInfo executor;
- executor.mutable_executor_id()->set_value("default");
- executor.mutable_command()->set_value(":");
- task.mutable_executor()->MergeFrom(executor);
-
- Resource* resource;
- resource = task.add_resources();
- resource->set_name("cpus");
- resource->set_type(Value::SCALAR);
- resource->mutable_scalar()->set_value(cpus);
-
- resource = task.add_resources();
- resource->set_name("mem");
- resource->set_type(Value::SCALAR);
- resource->mutable_scalar()->set_value(mem);
-
- tasks.push_back(task);
- launched++;
- offeredCpus -= cpus;
- offeredMem -= mem;
- }
-
- driver->launchTasks(offer.id(), tasks);
- }
-}
-
-
-// Like LaunchTasks, but decline the entire offer and
-// don't launch any tasks.
-ACTION(DeclineOffers)
-{
- SchedulerDriver* driver = arg0;
- std::vector<Offer> offers = arg1;
-
- for (size_t i = 0; i < offers.size(); i++) {
- driver->declineOffer(offers[i].id());
- }
-}
-
-
-// Definition of a mock Executor to be used in tests with gmock.
-class MockExecutor : public Executor
-{
-public:
- MOCK_METHOD4(registered, void(ExecutorDriver*,
- const ExecutorInfo&,
- const FrameworkInfo&,
- const SlaveInfo&));
- MOCK_METHOD2(reregistered, void(ExecutorDriver*, const SlaveInfo&));
- MOCK_METHOD1(disconnected, void(ExecutorDriver*));
- MOCK_METHOD2(launchTask, void(ExecutorDriver*, const TaskInfo&));
- MOCK_METHOD2(killTask, void(ExecutorDriver*, const TaskID&));
- MOCK_METHOD2(frameworkMessage, void(ExecutorDriver*, const std::string&));
- MOCK_METHOD1(shutdown, void(ExecutorDriver*));
- MOCK_METHOD2(error, void(ExecutorDriver*, const std::string&));
-};
-
-
-class MockProcessListener : public slave::ProcessExitedListener
-{
-public:
- MOCK_METHOD2(processExited, void(pid_t, int));
-};
-
-
-template <typename T = master::AllocatorProcess>
-class MockAllocatorProcess : public master::AllocatorProcess
-{
-public:
- MockAllocatorProcess()
- {
- // Spawn the underlying allocator process.
- process::spawn(real);
-
- using ::testing::_;
-
- ON_CALL(*this, initialize(_, _))
- .WillByDefault(InvokeInitialize(this));
-
- ON_CALL(*this, frameworkAdded(_, _, _))
- .WillByDefault(InvokeFrameworkAdded(this));
-
- ON_CALL(*this, frameworkRemoved(_))
- .WillByDefault(InvokeFrameworkRemoved(this));
-
- ON_CALL(*this, frameworkActivated(_, _))
- .WillByDefault(InvokeFrameworkActivated(this));
-
- ON_CALL(*this, frameworkDeactivated(_))
- .WillByDefault(InvokeFrameworkDeactivated(this));
-
- ON_CALL(*this, slaveAdded(_, _, _))
- .WillByDefault(InvokeSlaveAdded(this));
-
- ON_CALL(*this, slaveRemoved(_))
- .WillByDefault(InvokeSlaveRemoved(this));
-
- ON_CALL(*this, updateWhitelist(_))
- .WillByDefault(InvokeUpdateWhitelist(this));
-
- ON_CALL(*this, resourcesRequested(_, _))
- .WillByDefault(InvokeResourcesRequested(this));
-
- ON_CALL(*this, resourcesUnused(_, _, _, _))
- .WillByDefault(InvokeResourcesUnused(this));
-
- ON_CALL(*this, resourcesRecovered(_, _, _))
- .WillByDefault(InvokeResourcesRecovered(this));
-
- ON_CALL(*this, offersRevived(_))
- .WillByDefault(InvokeOffersRevived(this));
- }
-
- ~MockAllocatorProcess()
- {
- process::terminate(real);
- process::wait(real);
- }
-
- MOCK_METHOD2(initialize, void(const master::Flags&,
- const process::PID<master::Master>&));
- MOCK_METHOD3(frameworkAdded, void(const FrameworkID&,
- const FrameworkInfo&,
- const Resources&));
- MOCK_METHOD1(frameworkRemoved, void(const FrameworkID&));
- MOCK_METHOD2(frameworkActivated, void(const FrameworkID&,
- const FrameworkInfo&));
- MOCK_METHOD1(frameworkDeactivated, void(const FrameworkID&));
- MOCK_METHOD3(slaveAdded, void(const SlaveID&,
- const SlaveInfo&,
- const hashmap<FrameworkID, Resources>&));
- MOCK_METHOD1(slaveRemoved, void(const SlaveID&));
- MOCK_METHOD1(updateWhitelist, void(const Option<hashset<std::string> >&));
- MOCK_METHOD2(resourcesRequested, void(const FrameworkID&,
- const std::vector<Request>&));
- MOCK_METHOD4(resourcesUnused, void(const FrameworkID&,
- const SlaveID&,
- const Resources&,
- const Option<Filters>& filters));
- MOCK_METHOD3(resourcesRecovered, void(const FrameworkID&,
- const SlaveID&,
- const Resources&));
- MOCK_METHOD1(offersRevived, void(const FrameworkID&));
-
- T real;
-};
-
-
-typedef ::testing::Types<master::HierarchicalDRFAllocatorProcess>
-AllocatorTypes;
-
-
-// The following actions make up for the fact that DoDefault
-// cannot be used inside a DoAll, for example:
-// EXPECT_CALL(allocator, frameworkAdded(_, _, _))
-// .WillOnce(DoAll(InvokeFrameworkAdded(&allocator),
-// FutureSatisfy(&frameworkAdded)));
-
-ACTION_P(InvokeInitialize, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::initialize,
- arg0,
- arg1);
-}
-
-
-ACTION_P(InvokeFrameworkAdded, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::frameworkAdded,
- arg0,
- arg1,
- arg2);
-}
-
-
-ACTION_P(InvokeFrameworkRemoved, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::frameworkRemoved, arg0);
-}
-
-
-ACTION_P(InvokeFrameworkActivated, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::frameworkActivated,
- arg0,
- arg1);
-}
-
-
-ACTION_P(InvokeFrameworkDeactivated, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::frameworkDeactivated,
- arg0);
-}
-
-
-ACTION_P(InvokeSlaveAdded, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::slaveAdded,
- arg0,
- arg1,
- arg2);
-}
-
-
-ACTION_P(InvokeSlaveRemoved, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::slaveRemoved,
- arg0);
-}
-
-
-ACTION_P(InvokeUpdateWhitelist, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::updateWhitelist,
- arg0);
-}
-
-
-ACTION_P(InvokeResourcesRequested, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::resourcesRequested,
- arg0,
- arg1);
-}
-
-
-
-ACTION_P(InvokeResourcesUnused, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::resourcesUnused,
- arg0,
- arg1,
- arg2,
- arg3);
-}
-
-
-ACTION_P2(InvokeUnusedWithFilters, allocator, timeout)
-{
- Filters filters;
- filters.set_refuse_seconds(timeout);
-
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::resourcesUnused,
- arg0,
- arg1,
- arg2,
- filters);
-}
-
-
-ACTION_P(InvokeResourcesRecovered, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::resourcesRecovered,
- arg0,
- arg1,
- arg2);
-}
-
-
-ACTION_P(InvokeOffersRevived, allocator)
-{
- process::dispatch(
- allocator->real,
- &master::AllocatorProcess::offersRevived,
- arg0);
-}
-
-
-class OfferEqMatcher
- : public ::testing::MatcherInterface<const std::vector<Offer>& >
-{
-public:
- OfferEqMatcher(int _cpus, int _mem)
- : cpus(_cpus), mem(_mem) {}
-
- virtual bool MatchAndExplain(const std::vector<Offer>& offers,
- ::testing::MatchResultListener* listener) const
- {
- double totalCpus = 0;
- double totalMem = 0;
-
- foreach (const Offer& offer, offers) {
- foreach (const Resource& resource, offer.resources()) {
- if (resource.name() == "cpus") {
- totalCpus += resource.scalar().value();
- } else if (resource.name() == "mem") {
- totalMem += resource.scalar().value();
- }
- }
- }
-
- bool matches = totalCpus == cpus && totalMem == mem;
-
- if (!matches) {
- *listener << totalCpus << " cpus and " << totalMem << "mem";
- }
-
- return matches;
- }
-
- virtual void DescribeTo(::std::ostream* os) const
- {
- *os << "contains " << cpus << " cpus and " << mem << " mem";
- }
-
- virtual void DescribeNegationTo(::std::ostream* os) const
- {
- *os << "does not contain " << cpus << " cpus and " << mem << " mem";
- }
-
-private:
- int cpus;
- int mem;
-};
-
-
-inline const ::testing::Matcher<const std::vector<Offer>& > OfferEq(int cpus, int mem)
-{
- return MakeMatcher(new OfferEqMatcher(cpus, mem));
-}
-
-
-// Definition of the SendStatusUpdateFromTask action to be used with gmock.
-ACTION_P(SendStatusUpdateFromTask, state)
-{
- TaskStatus status;
- status.mutable_task_id()->MergeFrom(arg1.task_id());
- status.set_state(state);
- arg0->sendStatusUpdate(status);
-}
-
-
-// Definition of the SendStatusUpdateFromTaskID action to be used with gmock.
-ACTION_P(SendStatusUpdateFromTaskID, state)
-{
- TaskStatus status;
- status.mutable_task_id()->MergeFrom(arg1);
- status.set_state(state);
- arg0->sendStatusUpdate(status);
-}
-
-
-#define FUTURE_PROTOBUF(message, from, to) \
- FutureProtobuf(message, from, to)
-
-
-#define DROP_PROTOBUF(message, from, to) \
- FutureProtobuf(message, from, to, true)
-
-
-#define DROP_PROTOBUFS(message, from, to) \
- DropProtobufs(message, from, to)
-
-
-// Forward declaration.
-template <typename T>
-T _FutureProtobuf(const process::Message& message);
-
-
-template <typename T, typename From, typename To>
-process::Future<T> FutureProtobuf(T t, From from, To to, bool drop = false)
-{
- // Help debugging by adding some "type constraints".
- { google::protobuf::Message* m = &t; (void) m; }
-
- return process::FutureMessage(testing::Eq(t.GetTypeName()), from, to, drop)
- .then(lambda::bind(&_FutureProtobuf<T>, lambda::_1));
-}
-
-
-template <typename T>
-T _FutureProtobuf(const process::Message& message)
-{
- T t;
- t.ParseFromString(message.body);
- return t;
-}
-
-
-template <typename T, typename From, typename To>
-void DropProtobufs(T t, From from, To to)
-{
- // Help debugging by adding some "type constraints".
- { google::protobuf::Message* m = &t; (void) m; }
-
- process::DropMessages(testing::Eq(t.GetTypeName()), from, to);
-}
-
} // namespace tests {
} // namespace internal {
} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/zookeeper.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper.cpp b/src/tests/zookeeper.cpp
index 3d11209..237d54c 100644
--- a/src/tests/zookeeper.cpp
+++ b/src/tests/zookeeper.cpp
@@ -35,7 +35,7 @@
#include "logging/logging.hpp"
-#include "tests/utils.hpp"
+#include "tests/flags.hpp"
#include "tests/zookeeper.hpp"
#include "tests/zookeeper_test_server.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/zookeeper.hpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper.hpp b/src/tests/zookeeper.hpp
index 17e0886..1bc38c2 100644
--- a/src/tests/zookeeper.hpp
+++ b/src/tests/zookeeper.hpp
@@ -29,7 +29,6 @@
#include <stout/duration.hpp>
-#include "tests/utils.hpp"
#include "tests/zookeeper_test_server.hpp"
namespace mesos {
@@ -72,7 +71,7 @@ inline ::testing::AssertionResult AssertZKGet(
// the variable 'server'. This test fixture ensures the server is
// started before each test and shutdown after it so that each test is
// presented with a ZooKeeper ensemble with no data or watches.
-class ZooKeeperTest : public MesosTest
+class ZooKeeperTest : public ::testing::Test
{
public:
// A watcher that is useful to install in a ZooKeeper client for
@@ -116,17 +115,18 @@ public:
pthread_cond_t cond;
};
- ZooKeeperTest() : server(new ZooKeeperTestServer()) {}
- virtual ~ZooKeeperTest() { delete server; }
-
static void SetUpTestCase();
protected:
+ ZooKeeperTest() : server(new ZooKeeperTestServer()) {}
+ virtual ~ZooKeeperTest() { delete server; }
+
virtual void SetUp();
// A very long session timeout that simulates no timeout for test cases.
static const Duration NO_TIMEOUT;
+ // TODO(benh): Share the same ZooKeeperTestServer across all tests?
ZooKeeperTestServer* server;
};
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/zookeeper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_tests.cpp b/src/tests/zookeeper_tests.cpp
index 27a6048..77a5ab2 100644
--- a/src/tests/zookeeper_tests.cpp
+++ b/src/tests/zookeeper_tests.cpp
@@ -24,7 +24,8 @@
#include <stout/strings.hpp>
-#include "tests/utils.hpp"
+#include "zookeeper/authentication.hpp"
+
#include "tests/zookeeper.hpp"
using namespace mesos::internal;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/zookeeper/authentication.hpp
----------------------------------------------------------------------
diff --git a/src/zookeeper/authentication.hpp b/src/zookeeper/authentication.hpp
index fb0e3ca..7b6b767 100644
--- a/src/zookeeper/authentication.hpp
+++ b/src/zookeeper/authentication.hpp
@@ -5,6 +5,8 @@
#include <string>
+#include "logging/logging.hpp"
+
namespace zookeeper {
struct Authentication
@@ -13,7 +15,11 @@ struct Authentication
const std::string& _scheme,
const std::string& _credentials)
: scheme(_scheme),
- credentials(_credentials) {}
+ credentials(_credentials)
+ {
+ // TODO(benh): Fix output operator below once this changes.
+ CHECK_EQ(scheme, "digest") << "Unsupported authentication scheme";
+ }
const std::string scheme;
const std::string credentials;
@@ -28,6 +34,17 @@ extern const ACL_vector EVERYONE_READ_CREATOR_ALL;
// we're the the only authenticated user to mutate our nodes.
extern const ACL_vector EVERYONE_CREATE_AND_READ_CREATOR_ALL;
+
+inline std::ostream& operator << (
+ std::ostream& stream,
+ const Authentication& authentication)
+{
+ // TODO(benh): Fix this once we support more than just 'digest'.
+ CHECK_EQ(authentication.scheme, "digest");
+ return stream << authentication.credentials;
+}
+
+
} // namespace zookeeper {
#endif // __ZOOKEEPER_AUTHENTICATION_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/zookeeper/url.hpp
----------------------------------------------------------------------
diff --git a/src/zookeeper/url.hpp b/src/zookeeper/url.hpp
index b297a16..11f2bdd 100644
--- a/src/zookeeper/url.hpp
+++ b/src/zookeeper/url.hpp
@@ -108,6 +108,15 @@ inline Try<URL> URL::parse(const std::string& url)
}
}
+inline std::ostream& operator << (std::ostream& stream, const URL& url)
+{
+ stream << "zk://";
+ if (url.authentication.isSome()) {
+ stream << url.authentication.get() << "@";
+ }
+ return stream << url.servers << url.path;
+}
+
} // namespace zookeeper {
#endif // __ZOOKEEPER_URL_HPP__
[19/28] git commit: Replaced local::launch in tests with MesosTest.
Posted by be...@apache.org.
Replaced local::launch in tests with MesosTest.
Review: https://reviews.apache.org/r/11280
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/5690d207
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/5690d207
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/5690d207
Branch: refs/heads/master
Commit: 5690d207f99022948db4a69c5bf654798876de79
Parents: a1e25cb
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sun May 12 14:17:48 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 00:13:41 2013 -0700
----------------------------------------------------------------------
src/tests/exception_tests.cpp | 51 ++++++++++-----
src/tests/fault_tolerance_tests.cpp | 50 +++++++++-----
src/tests/resource_offers_tests.cpp | 105 +++++++++++++++++++-----------
3 files changed, 134 insertions(+), 72 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5690d207/src/tests/exception_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/exception_tests.cpp b/src/tests/exception_tests.cpp
index 60bb690..3fc1ac3 100644
--- a/src/tests/exception_tests.cpp
+++ b/src/tests/exception_tests.cpp
@@ -25,10 +25,13 @@
#include <process/pid.hpp>
#include <process/process.hpp>
-#include "local/local.hpp"
+#include <stout/gtest.hpp>
+#include <stout/try.hpp>
#include "master/master.hpp"
+#include "slave/slave.hpp"
+
#include "tests/mesos.hpp"
using namespace mesos;
@@ -37,6 +40,8 @@ using namespace mesos::internal::tests;
using mesos::internal::master::Master;
+using mesos::internal::slave::Slave;
+
using process::Future;
using process::PID;
@@ -50,13 +55,19 @@ using testing::Eq;
using testing::Return;
-TEST(ExceptionTest, DeactivateFrameworkOnAbort)
+class ExceptionTest : public MesosTest {};
+
+
+TEST_F(ExceptionTest, DeactivateFrameworkOnAbort)
{
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte,1 * Gigabyte, false);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
- MockScheduler sched;
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MockScheduler sched;
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
Future<Nothing> registered;
EXPECT_CALL(sched, registered(&driver, _, _))
@@ -80,17 +91,21 @@ TEST(ExceptionTest, DeactivateFrameworkOnAbort)
AWAIT_READY(deactivateFrameworkMessage);
driver.stop();
- local::shutdown();
+
+ Shutdown();
}
-TEST(ExceptionTest, DisallowSchedulerActionsOnAbort)
+TEST_F(ExceptionTest, DisallowSchedulerActionsOnAbort)
{
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
- MockScheduler sched;
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MockScheduler sched;
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
Future<Nothing> registered;
EXPECT_CALL(sched, registered(&driver, _, _))
@@ -111,17 +126,21 @@ TEST(ExceptionTest, DisallowSchedulerActionsOnAbort)
ASSERT_EQ(DRIVER_ABORTED, driver.reviveOffers());
driver.stop();
- local::shutdown();
+
+ Shutdown();
}
-TEST(ExceptionTest, DisallowSchedulerCallbacksOnAbort)
+TEST_F(ExceptionTest, DisallowSchedulerCallbacksOnAbort)
{
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
- MockScheduler sched;
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MockScheduler sched;
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&driver, _, _))
.Times(1);
@@ -176,5 +195,5 @@ TEST(ExceptionTest, DisallowSchedulerCallbacksOnAbort)
//Ensures reception of RescindResourceOfferMessage.
AWAIT_READY(unregisterMsg);
- local::shutdown();
+ Shutdown();
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5690d207/src/tests/fault_tolerance_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/fault_tolerance_tests.cpp b/src/tests/fault_tolerance_tests.cpp
index e41a044..287453d 100644
--- a/src/tests/fault_tolerance_tests.cpp
+++ b/src/tests/fault_tolerance_tests.cpp
@@ -38,8 +38,6 @@
#include "common/protobuf_utils.hpp"
-#include "local/local.hpp"
-
#include "master/master.hpp"
#include "slave/isolator.hpp"
@@ -134,17 +132,21 @@ TEST_F(FaultToleranceTest, PartitionedSlave)
{
Clock::pause();
- // Set these expectations up before we spawn the slave (in
- // local::launch) so that we don't miss the first PING.
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ // Set these expectations up before we spawn the slave so that we
+ // don't miss the first PING.
Future<Message> ping = FUTURE_MESSAGE(Eq("PING"), _, _);
// Drop all the PONGs to simulate slave partition.
DROP_MESSAGES(Eq("PONG"), _, _);
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&driver, _, _));
@@ -185,7 +187,7 @@ TEST_F(FaultToleranceTest, PartitionedSlave)
driver.stop();
driver.join();
- local::shutdown();
+ Shutdown();
Clock::resume();
}
@@ -638,14 +640,18 @@ TEST_F(FaultToleranceTest, MasterFailover)
TEST_F(FaultToleranceTest, SchedulerFailover)
{
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
// Launch the first (i.e., failing) scheduler and wait until
// registered gets called to launch the second (i.e., failover)
// scheduler.
MockScheduler sched1;
- MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master.get());
Future<FrameworkID> frameworkId;
EXPECT_CALL(sched1, registered(&driver1, _, _))
@@ -668,7 +674,7 @@ TEST_F(FaultToleranceTest, SchedulerFailover)
framework2 = DEFAULT_FRAMEWORK_INFO;
framework2.mutable_id()->MergeFrom(frameworkId.get());
- MesosSchedulerDriver driver2(&sched2, framework2, master);
+ MesosSchedulerDriver driver2(&sched2, framework2, master.get());
Future<Nothing> sched2Registered;
EXPECT_CALL(sched2, registered(&driver2, frameworkId.get(), _))
@@ -700,7 +706,7 @@ TEST_F(FaultToleranceTest, SchedulerFailover)
EXPECT_EQ(DRIVER_ABORTED, driver1.stop());
EXPECT_EQ(DRIVER_STOPPED, driver1.join());
- local::shutdown();
+ Shutdown();
}
@@ -708,10 +714,14 @@ TEST_F(FaultToleranceTest, FrameworkReliableRegistration)
{
Clock::pause();
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
Future<Nothing> registered;
EXPECT_CALL(sched, registered(&driver, _, _))
@@ -739,7 +749,7 @@ TEST_F(FaultToleranceTest, FrameworkReliableRegistration)
driver.stop();
driver.join();
- local::shutdown();
+ Shutdown();
Clock::resume();
}
@@ -747,10 +757,14 @@ TEST_F(FaultToleranceTest, FrameworkReliableRegistration)
TEST_F(FaultToleranceTest, FrameworkReregister)
{
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
Future<Nothing> registered;
EXPECT_CALL(sched, registered(&driver, _, _))
@@ -781,7 +795,7 @@ TEST_F(FaultToleranceTest, FrameworkReregister)
// Simulate a spurious newMasterDetected event (e.g., due to ZooKeeper
// expiration) at the scheduler.
NewMasterDetectedMessage newMasterDetectedMsg;
- newMasterDetectedMsg.set_pid(master);
+ newMasterDetectedMsg.set_pid(master.get());
process::post(message.get().to, newMasterDetectedMsg);
@@ -792,7 +806,7 @@ TEST_F(FaultToleranceTest, FrameworkReregister)
driver.stop();
driver.join();
- local::shutdown();
+ Shutdown();
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5690d207/src/tests/resource_offers_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/resource_offers_tests.cpp b/src/tests/resource_offers_tests.cpp
index 28ec4bc..e030d3d 100644
--- a/src/tests/resource_offers_tests.cpp
+++ b/src/tests/resource_offers_tests.cpp
@@ -23,8 +23,6 @@
#include <mesos/executor.hpp>
#include <mesos/scheduler.hpp>
-#include "local/local.hpp"
-
#include "master/hierarchical_allocator_process.hpp"
#include "master/master.hpp"
@@ -51,12 +49,24 @@ using testing::AtMost;
using testing::Return;
-TEST(ResourceOffersTest, ResourceOfferWithMultipleSlaves)
+class ResourceOffersTest : public MesosTest {};
+
+
+TEST_F(ResourceOffersTest, ResourceOfferWithMultipleSlaves)
{
- PID<Master> master = local::launch(10, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ // Start 10 slaves.
+ for (int i = 0; i < 10; i++) {
+ slave::Flags flags = CreateSlaveFlags();
+ flags.resources = Option<std::string>("cpus:2;mem:1024");
+ Try<PID<Slave> > slave = StartSlave(flags);
+ ASSERT_SOME(slave);
+ }
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&driver, _, _))
.Times(1);
@@ -79,16 +89,20 @@ TEST(ResourceOffersTest, ResourceOfferWithMultipleSlaves)
driver.stop();
driver.join();
- local::shutdown();
+ Shutdown();
}
-TEST(ResourceOffersTest, TaskUsesNoResources)
+TEST_F(ResourceOffersTest, TaskUsesNoResources)
{
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&driver, _, _))
.Times(1);
@@ -127,16 +141,20 @@ TEST(ResourceOffersTest, TaskUsesNoResources)
driver.stop();
driver.join();
- local::shutdown();
+ Shutdown();
}
-TEST(ResourceOffersTest, TaskUsesInvalidResources)
+TEST_F(ResourceOffersTest, TaskUsesInvalidResources)
{
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&driver, _, _))
.Times(1);
@@ -180,16 +198,20 @@ TEST(ResourceOffersTest, TaskUsesInvalidResources)
driver.stop();
driver.join();
- local::shutdown();
+ Shutdown();
}
-TEST(ResourceOffersTest, TaskUsesMoreResourcesThanOffered)
+TEST_F(ResourceOffersTest, TaskUsesMoreResourcesThanOffered)
{
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&driver, _, _))
.Times(1);
@@ -234,17 +256,20 @@ TEST(ResourceOffersTest, TaskUsesMoreResourcesThanOffered)
driver.stop();
driver.join();
- local::shutdown();
+ Shutdown();
}
-TEST(ResourceOffersTest, ResourcesGetReofferedAfterFrameworkStops)
+TEST_F(ResourceOffersTest, ResourcesGetReofferedAfterFrameworkStops)
{
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched1;
- MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched1, registered(&driver1, _, _))
.Times(1);
@@ -262,7 +287,7 @@ TEST(ResourceOffersTest, ResourcesGetReofferedAfterFrameworkStops)
driver1.join();
MockScheduler sched2;
- MesosSchedulerDriver driver2(&sched2, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver2(&sched2, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched2, registered(&driver2, _, _))
.Times(1);
@@ -277,16 +302,20 @@ TEST(ResourceOffersTest, ResourcesGetReofferedAfterFrameworkStops)
driver2.stop();
driver2.join();
- local::shutdown();
+ Shutdown();
}
-TEST(ResourceOffersTest, ResourcesGetReofferedWhenUnused)
+TEST_F(ResourceOffersTest, ResourcesGetReofferedWhenUnused)
{
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched1;
- MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched1, registered(&driver1, _, _))
.Times(1);
@@ -304,7 +333,7 @@ TEST(ResourceOffersTest, ResourcesGetReofferedWhenUnused)
driver1.launchTasks(offers.get()[0].id(), tasks);
MockScheduler sched2;
- MesosSchedulerDriver driver2(&sched2, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver2(&sched2, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched2, registered(&driver2, _, _))
.Times(1);
@@ -323,16 +352,20 @@ TEST(ResourceOffersTest, ResourcesGetReofferedWhenUnused)
driver2.stop();
driver2.join();
- local::shutdown();
+ Shutdown();
}
-TEST(ResourceOffersTest, ResourcesGetReofferedAfterTaskInfoError)
+TEST_F(ResourceOffersTest, ResourcesGetReofferedAfterTaskInfoError)
{
- PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
+ Try<PID<Master> > master = StartMaster();
+ ASSERT_SOME(master);
+
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
MockScheduler sched1;
- MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver1(&sched1, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched1, registered(&driver1, _, _))
.Times(1);
@@ -379,7 +412,7 @@ TEST(ResourceOffersTest, ResourcesGetReofferedAfterTaskInfoError)
EXPECT_EQ("Task uses invalid resources", status.get().message());
MockScheduler sched2;
- MesosSchedulerDriver driver2(&sched2, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver2(&sched2, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched2, registered(&driver2, _, _))
.Times(1);
@@ -398,7 +431,7 @@ TEST(ResourceOffersTest, ResourcesGetReofferedAfterTaskInfoError)
driver2.stop();
driver2.join();
- local::shutdown();
+ Shutdown();
}
// TODO(benh): Add tests for checking correct slave IDs.
@@ -409,11 +442,7 @@ TEST(ResourceOffersTest, ResourcesGetReofferedAfterTaskInfoError)
// unique task IDs and aggregate resource usage.
-// TODO(benh): Eliminate this class once we replace tests above to use
-// MesosTest/Cluster instead of local::launch.
-class ResourceOffersMesosTest : public MesosTest {};
-
-TEST_F(ResourceOffersMesosTest, Request)
+TEST_F(ResourceOffersTest, Request)
{
MockAllocatorProcess<HierarchicalDRFAllocatorProcess> allocator;
[03/28] git commit: Performed GTEST_IS_THREADSAFE check.
Posted by be...@apache.org.
Performed GTEST_IS_THREADSAFE check.
Review: https://reviews.apache.org/r/11264
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/f5be4131
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/f5be4131
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/f5be4131
Branch: refs/heads/master
Commit: f5be4131d1aa4bd858eeedcbefffb842d7252252
Parents: 304835d
Author: Benjamin Hindman <be...@twitter.com>
Authored: Thu Apr 25 17:33:12 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Fri May 24 22:05:05 2013 -0700
----------------------------------------------------------------------
src/tests/environment.cpp | 5 ++++
src/tests/exception_tests.cpp | 6 -----
src/tests/fault_tolerance_tests.cpp | 26 ------------------------
src/tests/gc_tests.cpp | 10 ---------
src/tests/master_detector_tests.cpp | 2 -
src/tests/master_tests.cpp | 24 ----------------------
src/tests/reaper_tests.cpp | 2 -
src/tests/resource_offers_tests.cpp | 17 ---------------
src/tests/slave_recovery_tests.cpp | 2 -
src/tests/status_update_manager_tests.cpp | 8 -------
10 files changed, 5 insertions(+), 97 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/f5be4131/src/tests/environment.cpp
----------------------------------------------------------------------
diff --git a/src/tests/environment.cpp b/src/tests/environment.cpp
index c94c85f..15ef205 100644
--- a/src/tests/environment.cpp
+++ b/src/tests/environment.cpp
@@ -24,6 +24,7 @@
#include <process/gmock.hpp>
#include <process/gtest.hpp>
+#include <stout/exit.hpp>
#include <stout/os.hpp>
#include <stout/strings.hpp>
@@ -172,6 +173,10 @@ void Environment::SetUp()
{
// Clear any MESOS_ environment variables so they don't affect our tests.
Configurator::clearMesosEnvironmentVars();
+
+ if (!GTEST_IS_THREADSAFE) {
+ EXIT(1) << "Testing environment is not thread safe, bailing!";
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/f5be4131/src/tests/exception_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/exception_tests.cpp b/src/tests/exception_tests.cpp
index f405a61..911e786 100644
--- a/src/tests/exception_tests.cpp
+++ b/src/tests/exception_tests.cpp
@@ -62,8 +62,6 @@ using testing::SaveArg;
TEST(ExceptionTest, DeactivateFrameworkOnAbort)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
PID<Master> master = local::launch(1, 2, 1 * Gigabyte,1 * Gigabyte, false);
MockScheduler sched;
@@ -98,8 +96,6 @@ TEST(ExceptionTest, DeactivateFrameworkOnAbort)
TEST(ExceptionTest, DisallowSchedulerActionsOnAbort)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
MockScheduler sched;
@@ -131,8 +127,6 @@ TEST(ExceptionTest, DisallowSchedulerActionsOnAbort)
TEST(ExceptionTest, DisallowSchedulerCallbacksOnAbort)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
MockScheduler sched;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/f5be4131/src/tests/fault_tolerance_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/fault_tolerance_tests.cpp b/src/tests/fault_tolerance_tests.cpp
index 2e9416e..bcfe5db 100644
--- a/src/tests/fault_tolerance_tests.cpp
+++ b/src/tests/fault_tolerance_tests.cpp
@@ -92,8 +92,6 @@ class FaultToleranceTest : public MesosTest {};
// its offer(s) is rescinded.
TEST_F(FaultToleranceTest, SlaveLost)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
HierarchicalDRFAllocatorProcess allocator;
Allocator a(&allocator);
Files files;
@@ -149,8 +147,6 @@ TEST_F(FaultToleranceTest, SlaveLost)
// message for a partioned slave.
TEST_F(FaultToleranceTest, PartitionedSlave)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Clock::pause();
// Set these expectations up before we spawn the slave (in
@@ -662,8 +658,6 @@ TEST_F(FaultToleranceClusterTest, MasterFailover)
TEST_F(FaultToleranceTest, SchedulerFailover)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
// Launch the first (i.e., failing) scheduler and wait until
@@ -732,8 +726,6 @@ TEST_F(FaultToleranceTest, SchedulerFailover)
TEST_F(FaultToleranceTest, FrameworkReliableRegistration)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Clock::pause();
PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
@@ -775,8 +767,6 @@ TEST_F(FaultToleranceTest, FrameworkReliableRegistration)
TEST_F(FaultToleranceTest, FrameworkReregister)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
MockScheduler sched;
@@ -828,8 +818,6 @@ TEST_F(FaultToleranceTest, FrameworkReregister)
TEST_F(FaultToleranceTest, TaskLost)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
HierarchicalDRFAllocatorProcess allocator;
Allocator a(&allocator);
Files files;
@@ -906,8 +894,6 @@ TEST_F(FaultToleranceTest, TaskLost)
// retried status update.
TEST_F(FaultToleranceTest, SchedulerFailoverStatusUpdate)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Clock::pause();
HierarchicalDRFAllocatorProcess allocator;
@@ -1025,8 +1011,6 @@ TEST_F(FaultToleranceTest, SchedulerFailoverStatusUpdate)
TEST_F(FaultToleranceTest, ForwardStatusUpdateUnknownExecutor)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
HierarchicalDRFAllocatorProcess allocator;
Allocator a(&allocator);
Files files;
@@ -1120,8 +1104,6 @@ TEST_F(FaultToleranceTest, ForwardStatusUpdateUnknownExecutor)
TEST_F(FaultToleranceTest, SchedulerFailoverFrameworkMessage)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
HierarchicalDRFAllocatorProcess allocator;
Allocator a(&allocator);
Files files;
@@ -1228,8 +1210,6 @@ TEST_F(FaultToleranceTest, SchedulerFailoverFrameworkMessage)
// This test checks that a scheduler exit shuts down the executor.
TEST_F(FaultToleranceTest, SchedulerExit)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
HierarchicalDRFAllocatorProcess allocator;
Allocator a(&allocator);
Files files;
@@ -1305,8 +1285,6 @@ TEST_F(FaultToleranceTest, SchedulerExit)
TEST_F(FaultToleranceTest, SlaveReliableRegistration)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Clock::pause();
HierarchicalDRFAllocatorProcess allocator;
@@ -1359,8 +1337,6 @@ TEST_F(FaultToleranceTest, SlaveReliableRegistration)
TEST_F(FaultToleranceTest, SlaveReregisterOnZKExpiration)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
HierarchicalDRFAllocatorProcess allocator;
Allocator a(&allocator);
Files files;
@@ -1418,8 +1394,6 @@ TEST_F(FaultToleranceTest, SlaveReregisterOnZKExpiration)
// TODO(vinod): Use 'Cluster' abstraction.
TEST_F(FaultToleranceTest, ConsolidateTasksOnSlaveReregistration)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
HierarchicalDRFAllocatorProcess allocator;
Allocator a(&allocator);
Files files;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/f5be4131/src/tests/gc_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/gc_tests.cpp b/src/tests/gc_tests.cpp
index 97d2685..949678c 100644
--- a/src/tests/gc_tests.cpp
+++ b/src/tests/gc_tests.cpp
@@ -253,8 +253,6 @@ class GarbageCollectorIntegrationTest : public MesosClusterTest {};
TEST_F(GarbageCollectorIntegrationTest, Restart)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -354,8 +352,6 @@ TEST_F(GarbageCollectorIntegrationTest, Restart)
TEST_F(GarbageCollectorIntegrationTest, ExitedFramework)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -453,8 +449,6 @@ TEST_F(GarbageCollectorIntegrationTest, ExitedFramework)
TEST_F(GarbageCollectorIntegrationTest, ExitedExecutor)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -545,8 +539,6 @@ TEST_F(GarbageCollectorIntegrationTest, ExitedExecutor)
TEST_F(GarbageCollectorIntegrationTest, DiskUsage)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -649,8 +641,6 @@ TEST_F(GarbageCollectorIntegrationTest, DiskUsage)
// created by an old executor (with the same id).
TEST_F(GarbageCollectorIntegrationTest, Unschedule)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/f5be4131/src/tests/master_detector_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_detector_tests.cpp b/src/tests/master_detector_tests.cpp
index 521f027..3a7b3b4 100644
--- a/src/tests/master_detector_tests.cpp
+++ b/src/tests/master_detector_tests.cpp
@@ -65,8 +65,6 @@ class MasterDetectorTest : public MesosClusterTest {};
TEST_F(MasterDetectorTest, File)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/f5be4131/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index fe823f6..f99157e 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -77,8 +77,6 @@ class MasterTest : public MesosClusterTest {};
TEST_F(MasterTest, TaskRunning)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -152,8 +150,6 @@ TEST_F(MasterTest, TaskRunning)
TEST_F(MasterTest, ShutdownFrameworkWhileTaskRunning)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -229,8 +225,6 @@ TEST_F(MasterTest, ShutdownFrameworkWhileTaskRunning)
TEST_F(MasterTest, KillTask)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -309,8 +303,6 @@ TEST_F(MasterTest, KillTask)
TEST_F(MasterTest, StatusUpdateAck)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -381,8 +373,6 @@ TEST_F(MasterTest, StatusUpdateAck)
TEST_F(MasterTest, RecoverResources)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -504,8 +494,6 @@ TEST_F(MasterTest, RecoverResources)
TEST_F(MasterTest, FrameworkMessage)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -590,8 +578,6 @@ TEST_F(MasterTest, FrameworkMessage)
TEST_F(MasterTest, MultipleExecutors)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -708,8 +694,6 @@ TEST_F(MasterTest, MultipleExecutors)
TEST_F(MasterTest, ShutdownUnregisteredExecutor)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -793,8 +777,6 @@ TEST_F(MasterTest, ShutdownUnregisteredExecutor)
TEST_F(MasterTest, MasterInfo)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -826,8 +808,6 @@ TEST_F(MasterTest, MasterInfo)
TEST_F(MasterTest, MasterInfoOnReElection)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -895,8 +875,6 @@ protected:
TEST_F(WhitelistTest, WhitelistSlave)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
// Add some hosts to the white list.
Try<string> hostname = os::hostname();
ASSERT_SOME(hostname);
@@ -934,8 +912,6 @@ TEST_F(WhitelistTest, WhitelistSlave)
TEST_F(MasterTest, MasterLost)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/f5be4131/src/tests/reaper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/reaper_tests.cpp b/src/tests/reaper_tests.cpp
index 0809c1f..c1fc1c3 100644
--- a/src/tests/reaper_tests.cpp
+++ b/src/tests/reaper_tests.cpp
@@ -44,8 +44,6 @@ using testing::DoDefault;
// This test checks that the Reaper can monitor a non-child process.
TEST(ReaperTest, NonChildProcess)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
// Use pipes to determine the pid of the grand child process.
int pipes[2];
ASSERT_NE(-1, pipe(pipes));
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/f5be4131/src/tests/resource_offers_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/resource_offers_tests.cpp b/src/tests/resource_offers_tests.cpp
index 5e53a89..0be5497 100644
--- a/src/tests/resource_offers_tests.cpp
+++ b/src/tests/resource_offers_tests.cpp
@@ -53,8 +53,6 @@ using testing::Return;
TEST(ResourceOffersTest, ResourceOfferWithMultipleSlaves)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
PID<Master> master = local::launch(10, 2, 1 * Gigabyte, 1 * Gigabyte, false);
MockScheduler sched;
@@ -87,8 +85,6 @@ TEST(ResourceOffersTest, ResourceOfferWithMultipleSlaves)
TEST(ResourceOffersTest, TaskUsesNoResources)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
MockScheduler sched;
@@ -137,8 +133,6 @@ TEST(ResourceOffersTest, TaskUsesNoResources)
TEST(ResourceOffersTest, TaskUsesInvalidResources)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
MockScheduler sched;
@@ -192,8 +186,6 @@ TEST(ResourceOffersTest, TaskUsesInvalidResources)
TEST(ResourceOffersTest, TaskUsesMoreResourcesThanOffered)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
MockScheduler sched;
@@ -248,7 +240,6 @@ TEST(ResourceOffersTest, TaskUsesMoreResourcesThanOffered)
TEST(ResourceOffersTest, ResourcesGetReofferedAfterFrameworkStops)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
@@ -292,8 +283,6 @@ TEST(ResourceOffersTest, ResourcesGetReofferedAfterFrameworkStops)
TEST(ResourceOffersTest, ResourcesGetReofferedWhenUnused)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
MockScheduler sched1;
@@ -340,8 +329,6 @@ TEST(ResourceOffersTest, ResourcesGetReofferedWhenUnused)
TEST(ResourceOffersTest, ResourcesGetReofferedAfterTaskInfoError)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
PID<Master> master = local::launch(1, 2, 1 * Gigabyte, 1 * Gigabyte, false);
MockScheduler sched1;
@@ -424,8 +411,6 @@ TEST(ResourceOffersTest, ResourcesGetReofferedAfterTaskInfoError)
TEST(ResourceOffersTest, Request)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Cluster cluster;
MockAllocatorProcess<HierarchicalDRFAllocatorProcess> allocator;
@@ -484,8 +469,6 @@ class MultipleExecutorsTest : public MesosClusterTest {};
TEST_F(MultipleExecutorsTest, TasksExecutorInfoDiffers)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/f5be4131/src/tests/slave_recovery_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/slave_recovery_tests.cpp b/src/tests/slave_recovery_tests.cpp
index d963ce1..fd6b9ac 100644
--- a/src/tests/slave_recovery_tests.cpp
+++ b/src/tests/slave_recovery_tests.cpp
@@ -132,8 +132,6 @@ public:
{
IsolatorTest<T>::SetUp();
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
a = new Allocator(&allocator);
m = new Master(a, &files);
master = process::spawn(m);
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/f5be4131/src/tests/status_update_manager_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/status_update_manager_tests.cpp b/src/tests/status_update_manager_tests.cpp
index e375898..042201a 100644
--- a/src/tests/status_update_manager_tests.cpp
+++ b/src/tests/status_update_manager_tests.cpp
@@ -90,8 +90,6 @@ class StatusUpdateManagerTest: public MesosClusterTest {};
TEST_F(StatusUpdateManagerTest, CheckpointStatusUpdate)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -193,8 +191,6 @@ TEST_F(StatusUpdateManagerTest, CheckpointStatusUpdate)
TEST_F(StatusUpdateManagerTest, RetryStatusUpdate)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -272,8 +268,6 @@ TEST_F(StatusUpdateManagerTest, RetryStatusUpdate)
// duplicate ACK is for a retried update.
TEST_F(StatusUpdateManagerTest, IgnoreDuplicateStatusUpdateAck)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
@@ -394,8 +388,6 @@ TEST_F(StatusUpdateManagerTest, IgnoreDuplicateStatusUpdateAck)
// for the original update and sending a random ACK to the slave.
TEST_F(StatusUpdateManagerTest, IgnoreUnexpectedStatusUpdateAck)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
Try<PID<Master> > master = cluster.masters.start();
ASSERT_SOME(master);
[15/28] git commit: Used Milliseconds rather than Duration::parse.
Posted by be...@apache.org.
Used Milliseconds rather than Duration::parse.
Review: https://reviews.apache.org/r/11275
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/bb18d3bc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/bb18d3bc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/bb18d3bc
Branch: refs/heads/master
Commit: bb18d3bcc8208bcfd0deb422323631765236c779
Parents: 7995751
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sat May 11 10:08:35 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Sun May 26 00:13:41 2013 -0700
----------------------------------------------------------------------
src/tests/allocator_tests.cpp | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bb18d3bc/src/tests/allocator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/allocator_tests.cpp b/src/tests/allocator_tests.cpp
index 5a0de33..7ee71de 100644
--- a/src/tests/allocator_tests.cpp
+++ b/src/tests/allocator_tests.cpp
@@ -685,7 +685,7 @@ TYPED_TEST(AllocatorTest, FrameworkExited)
EXPECT_CALL(this->allocator, initialize(_, _));
master::Flags masterFlags = this->CreateMasterFlags();
- masterFlags.allocation_interval = Duration::parse("50ms").get();
+ masterFlags.allocation_interval = Milliseconds(50);
Try<PID<Master> > master = this->StartMaster(&this->allocator, masterFlags);
ASSERT_SOME(master);
@@ -943,7 +943,7 @@ TYPED_TEST(AllocatorTest, SlaveAdded)
EXPECT_CALL(this->allocator, initialize(_, _));
master::Flags masterFlags = this->CreateMasterFlags();
- masterFlags.allocation_interval = Duration::parse("50ms").get();
+ masterFlags.allocation_interval = Milliseconds(50);
Try<PID<Master> > master = this->StartMaster(&this->allocator, masterFlags);
ASSERT_SOME(master);
@@ -1050,7 +1050,7 @@ TYPED_TEST(AllocatorTest, TaskFinished)
EXPECT_CALL(this->allocator, initialize(_, _));
master::Flags masterFlags = this->CreateMasterFlags();
- masterFlags.allocation_interval = Duration::parse("50ms").get();
+ masterFlags.allocation_interval = Milliseconds(50);
Try<PID<Master> > master = this->StartMaster(&this->allocator, masterFlags);
ASSERT_SOME(master);
[11/28] Refactored MesosTest/MesosClusterTest into a generic fixture
for launching in-memory Mesos clusters and updated all tests appropriately.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index f99157e..1d26eeb 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -44,8 +44,8 @@
#include "slave/process_isolator.hpp"
#include "slave/slave.hpp"
-#include "tests/cluster.hpp"
-#include "tests/utils.hpp"
+#include "tests/isolator.hpp"
+#include "tests/mesos.hpp"
using namespace mesos;
using namespace mesos::internal;
@@ -72,19 +72,18 @@ using testing::Eq;
using testing::Return;
-class MasterTest : public MesosClusterTest {};
+class MasterTest : public MesosTest {};
TEST_F(MasterTest, TaskRunning)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+ TestingIsolator isolator(&exec);
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
-
- Try<PID<Slave> > slave = cluster.slaves.start(&isolator);
+ Try<PID<Slave> > slave = StartSlave(&isolator);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -144,22 +143,22 @@ TEST_F(MasterTest, TaskRunning)
AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
- cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
+ Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
TEST_F(MasterTest, ShutdownFrameworkWhileTaskRunning)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
-
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+ TestingIsolator isolator(&exec);
- slave::Flags flags = cluster.slaves.flags;
+ slave::Flags flags = CreateSlaveFlags();
flags.executor_shutdown_grace_period = Seconds(0);
- Try<PID<Slave> > slave = cluster.slaves.start(flags, &isolator);
+
+ Try<PID<Slave> > slave = StartSlave(&isolator, flags);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -219,18 +218,18 @@ TEST_F(MasterTest, ShutdownFrameworkWhileTaskRunning)
AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
- cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
+ Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
TEST_F(MasterTest, KillTask)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- Try<PID<Slave> > slave = cluster.slaves.start(DEFAULT_EXECUTOR_ID, &exec);
+ Try<PID<Slave> > slave = StartSlave(&exec);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -297,18 +296,18 @@ TEST_F(MasterTest, KillTask)
AWAIT_READY(shutdown); // To ensure can deallocate MockExecutor.
- cluster.shutdown();
+ Shutdown();
}
TEST_F(MasterTest, StatusUpdateAck)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- Try<PID<Slave> > slave = cluster.slaves.start(DEFAULT_EXECUTOR_ID, &exec);
+ Try<PID<Slave> > slave = StartSlave(&exec);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -367,23 +366,23 @@ TEST_F(MasterTest, StatusUpdateAck)
AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
- cluster.shutdown();
+ Shutdown();
}
TEST_F(MasterTest, RecoverResources)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
+ TestingIsolator isolator(&exec);
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
+ slave::Flags flags = CreateSlaveFlags();
+ flags.resources = Option<string>(
+ "cpus:2;mem:1024;disk:1024;ports:[1-10, 20-30]");
- slave::Flags flags = cluster.slaves.flags;
- flags.resources =
- Option<string>("cpus:2;mem:1024;disk:1024;ports:[1-10, 20-30]");
- Try<PID<Slave> > slave = cluster.slaves.start(flags, &isolator);
+ Try<PID<Slave> > slave = StartSlave(&isolator, flags);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -488,18 +487,18 @@ TEST_F(MasterTest, RecoverResources)
EXPECT_CALL(exec, shutdown(_))
.Times(AtMost(1));
- cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
+ Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
TEST_F(MasterTest, FrameworkMessage)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- Try<PID<Slave> > slave = cluster.slaves.start(DEFAULT_EXECUTOR_ID, &exec);
+ Try<PID<Slave> > slave = StartSlave(&exec);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -572,13 +571,13 @@ TEST_F(MasterTest, FrameworkMessage)
AWAIT_READY(shutdown); // To ensure can deallocate MockExecutor.
- cluster.shutdown();
+ Shutdown();
}
TEST_F(MasterTest, MultipleExecutors)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
ExecutorID executorId1;
@@ -587,8 +586,8 @@ TEST_F(MasterTest, MultipleExecutors)
ExecutorID executorId2;
executorId2.set_value("executor-2");
- MockExecutor exec1;
- MockExecutor exec2;
+ MockExecutor exec1(executorId1);
+ MockExecutor exec2(executorId2);
map<ExecutorID, Executor*> execs;
execs[executorId1] = &exec1;
@@ -596,7 +595,7 @@ TEST_F(MasterTest, MultipleExecutors)
TestingIsolator isolator(execs);
- Try<PID<Slave> > slave = cluster.slaves.start(&isolator);
+ Try<PID<Slave> > slave = StartSlave(&isolator);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -688,18 +687,21 @@ TEST_F(MasterTest, MultipleExecutors)
AWAIT_READY(shutdown1); // To ensure can deallocate MockExecutor.
AWAIT_READY(shutdown2); // To ensure can deallocate MockExecutor.
- cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
+ Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
TEST_F(MasterTest, ShutdownUnregisteredExecutor)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
ProcessIsolator isolator;
- Try<PID<Slave> > slave = cluster.slaves.start(&isolator);
+ // Need flags for 'executor_registration_timeout'.
+ slave::Flags flags = CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = StartSlave(&isolator);
ASSERT_SOME(slave);
MockScheduler sched;
@@ -751,7 +753,7 @@ TEST_F(MasterTest, ShutdownUnregisteredExecutor)
Future<Nothing> killExecutor =
FUTURE_DISPATCH(_, &Isolator::killExecutor);
- Clock::advance(cluster.slaves.flags.executor_registration_timeout);
+ Clock::advance(flags.executor_registration_timeout);
AWAIT_READY(killExecutor);
@@ -771,16 +773,16 @@ TEST_F(MasterTest, ShutdownUnregisteredExecutor)
driver.stop();
driver.join();
- cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
+ Shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
TEST_F(MasterTest, MasterInfo)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- Try<PID<Slave> > slave = cluster.slaves.start();
+ Try<PID<Slave> > slave = StartSlave();
ASSERT_SOME(slave);
MockScheduler sched;
@@ -802,16 +804,16 @@ TEST_F(MasterTest, MasterInfo)
driver.stop();
driver.join();
- cluster.shutdown();
+ Shutdown();
}
TEST_F(MasterTest, MasterInfoOnReElection)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- Try<PID<Slave> > slave = cluster.slaves.start();
+ Try<PID<Slave> > slave = StartSlave();
ASSERT_SOME(slave);
MockScheduler sched;
@@ -854,7 +856,7 @@ TEST_F(MasterTest, MasterInfoOnReElection)
driver.stop();
driver.join();
- cluster.shutdown();
+ Shutdown();
}
@@ -878,15 +880,17 @@ TEST_F(WhitelistTest, WhitelistSlave)
// Add some hosts to the white list.
Try<string> hostname = os::hostname();
ASSERT_SOME(hostname);
+
string hosts = hostname.get() + "\n" + "dummy-slave";
ASSERT_SOME(os::write(path, hosts)) << "Error writing whitelist";
- master::Flags flags = cluster.masters.flags;
+ master::Flags flags = CreateMasterFlags();
flags.whitelist = "file://" + path;
- Try<PID<Master> > master = cluster.masters.start(flags);
+
+ Try<PID<Master> > master = StartMaster(flags);
ASSERT_SOME(master);
- Try<PID<Slave> > slave = cluster.slaves.start();
+ Try<PID<Slave> > slave = StartSlave();
ASSERT_SOME(slave);
MockScheduler sched;
@@ -906,16 +910,16 @@ TEST_F(WhitelistTest, WhitelistSlave)
driver.stop();
driver.join();
- cluster.shutdown();
+ Shutdown();
}
TEST_F(MasterTest, MasterLost)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- Try<PID<Slave> > slave = cluster.slaves.start();
+ Try<PID<Slave> > slave = StartSlave();
ASSERT_SOME(slave);
MockScheduler sched;
@@ -946,5 +950,5 @@ TEST_F(MasterTest, MasterLost)
driver.stop();
driver.join();
- cluster.shutdown();
+ Shutdown();
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/mesos.cpp
----------------------------------------------------------------------
diff --git a/src/tests/mesos.cpp b/src/tests/mesos.cpp
new file mode 100644
index 0000000..4ddf032
--- /dev/null
+++ b/src/tests/mesos.cpp
@@ -0,0 +1,240 @@
+#include <stout/foreach.hpp>
+#include <stout/os.hpp>
+#include <stout/result.hpp>
+
+#ifdef __linux__
+#include "linux/cgroups.hpp"
+#endif
+
+#include "logging/logging.hpp"
+
+#include "tests/environment.hpp"
+#include "tests/flags.hpp"
+#include "tests/isolator.hpp"
+#include "tests/mesos.hpp"
+
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+MesosTest::MesosTest(const Option<zookeeper::URL>& url) : cluster(url) {}
+
+
+master::Flags MesosTest::CreateMasterFlags()
+{
+ return master::Flags();
+}
+
+
+slave::Flags MesosTest::CreateSlaveFlags()
+{
+ slave::Flags flags;
+
+ // Create a temporary work directory (removed by Environment).
+ Try<std::string> directory = environment->mkdtemp();
+ CHECK_SOME(directory) << "Failed to create temporary directory";
+
+ flags.work_dir = directory.get();
+
+ flags.launcher_dir = path::join(tests::flags.build_dir, "src");
+
+ flags.resources = Option<std::string>(
+ "cpus:2;mem:1024;disk:1024;ports:[31000-32000]");
+
+ return flags;
+}
+
+
+Try<process::PID<master::Master> > MesosTest::StartMaster(
+ const Option<master::Flags>& flags)
+{
+ return cluster.masters.start(
+ flags.isNone() ? CreateMasterFlags() : flags.get());
+}
+
+
+Try<process::PID<master::Master> > MesosTest::StartMaster(
+ master::AllocatorProcess* allocator,
+ const Option<master::Flags>& flags)
+{
+ return cluster.masters.start(
+ allocator, flags.isNone() ? CreateMasterFlags() : flags.get());
+}
+
+
+Try<process::PID<slave::Slave> > MesosTest::StartSlave(
+ const Option<slave::Flags>& flags)
+{
+ TestingIsolator* isolator = new TestingIsolator();
+
+ Try<process::PID<slave::Slave> > pid = StartSlave(isolator, flags);
+
+ if (pid.isError()) {
+ delete isolator;
+ return pid;
+ }
+
+ isolators[pid.get()] = isolator;
+
+ return pid;
+}
+
+
+Try<process::PID<slave::Slave> > MesosTest::StartSlave(
+ MockExecutor* executor,
+ const Option<slave::Flags>& flags)
+{
+ TestingIsolator* isolator = new TestingIsolator(executor);
+
+ Try<process::PID<slave::Slave> > pid = StartSlave(isolator, flags);
+
+ if (pid.isError()) {
+ delete isolator;
+ return pid;
+ }
+
+ isolators[pid.get()] = isolator;
+
+ return pid;
+}
+
+
+Try<process::PID<slave::Slave> > MesosTest::StartSlave(
+ slave::Isolator* isolator,
+ const Option<slave::Flags>& flags)
+{
+ return cluster.slaves.start(
+ isolator, flags.isNone() ? CreateSlaveFlags() : flags.get());
+}
+
+
+void MesosTest::Stop(const process::PID<master::Master>& pid)
+{
+ cluster.masters.stop(pid);
+}
+
+
+void MesosTest::Stop(const process::PID<slave::Slave>& pid, bool shutdown)
+{
+ cluster.slaves.stop(pid, shutdown);
+ if (isolators.count(pid) > 0) {
+ TestingIsolator* isolator = isolators[pid];
+ isolators.erase(pid);
+ delete isolator;
+ }
+}
+
+
+void MesosTest::Shutdown()
+{
+ ShutdownMasters();
+ ShutdownSlaves();
+}
+
+
+void MesosTest::ShutdownMasters()
+{
+ cluster.masters.shutdown();
+}
+
+
+void MesosTest::ShutdownSlaves()
+{
+ cluster.slaves.shutdown();
+
+ foreachvalue (TestingIsolator* isolator, isolators) {
+ delete isolator;
+ }
+ isolators.clear();
+}
+
+
+void MesosTest::SetUp()
+{
+ // For locating killtree.sh.
+ os::setenv("MESOS_SOURCE_DIR", tests::flags.source_dir);
+}
+
+
+void MesosTest::TearDown()
+{
+ os::unsetenv("MESOS_SOURCE_DIR");
+
+ // TODO(benh): Fail the test if shutdown hasn't been called?
+ Shutdown();
+}
+
+
+#ifdef __linux__
+void IsolatorTest<slave::CgroupsIsolator>::SetUpTestCase()
+{
+ // Clean up the testing hierarchy, in case it wasn't cleaned up
+ // properly from previous tests.
+ AWAIT_READY(cgroups::cleanup(TEST_CGROUPS_HIERARCHY));
+}
+
+
+void IsolatorTest<slave::CgroupsIsolator>::TearDownTestCase()
+{
+ AWAIT_READY(cgroups::cleanup(TEST_CGROUPS_HIERARCHY));
+}
+
+
+slave::Flags IsolatorTest<slave::CgroupsIsolator>::CreateSlaveFlags()
+{
+ slave::Flags flags = MesosTest::CreateSlaveFlags();
+
+ flags.cgroups_hierarchy = hierarchy;
+
+ // TODO(benh): Create a different cgroups root for each slave.
+ flags.cgroups_root = TEST_CGROUPS_ROOT;
+
+ return flags;
+}
+
+
+void IsolatorTest<slave::CgroupsIsolator>::SetUp()
+{
+ MesosTest::SetUp();
+
+ const std::string subsystems = "cpu,cpuacct,memory,freezer";
+ Result<std::string> hierarchy_ = cgroups::hierarchy(subsystems);
+ ASSERT_FALSE(hierarchy_.isError());
+ if (hierarchy_.isNone()) {
+ // Try to mount a hierarchy for testing.
+ ASSERT_SOME(cgroups::mount(TEST_CGROUPS_HIERARCHY, subsystems))
+ << "-------------------------------------------------------------\n"
+ << "We cannot run any cgroups tests that require\n"
+ << "a hierarchy with subsystems '" << subsystems << "'\n"
+ << "because we failed to find an existing hierarchy\n"
+ << "or create a new one. You can either remove all existing\n"
+ << "hierarchies, or disable this test case\n"
+ << "(i.e., --gtest_filter=-"
+ << ::testing::UnitTest::GetInstance()
+ ->current_test_info()
+ ->test_case_name() << ".*).\n"
+ << "-------------------------------------------------------------";
+
+ hierarchy = TEST_CGROUPS_HIERARCHY;
+ } else {
+ hierarchy = hierarchy_.get();
+ }
+}
+
+
+void IsolatorTest<slave::CgroupsIsolator>::TearDown()
+{
+ MesosTest::TearDown();
+
+ Try<bool> exists = cgroups::exists(hierarchy, TEST_CGROUPS_ROOT);
+ ASSERT_SOME(exists);
+ if (exists.get()) {
+ AWAIT_READY(cgroups::destroy(hierarchy, TEST_CGROUPS_ROOT));
+ }
+}
+#endif // __linux__
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/mesos.hpp
----------------------------------------------------------------------
diff --git a/src/tests/mesos.hpp b/src/tests/mesos.hpp
new file mode 100644
index 0000000..12298ae
--- /dev/null
+++ b/src/tests/mesos.hpp
@@ -0,0 +1,676 @@
+/**
+ * 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.
+ */
+
+#ifndef __TESTS_MESOS_HPP__
+#define __TESTS_MESOS_HPP__
+
+#include <map>
+#include <string>
+
+#include <mesos/executor.hpp>
+#include <mesos/scheduler.hpp>
+
+#include <process/future.hpp>
+#include <process/gmock.hpp>
+#include <process/gtest.hpp>
+#include <process/pid.hpp>
+#include <process/process.hpp>
+
+#include <stout/gtest.hpp>
+#include <stout/lambda.hpp>
+#include <stout/none.hpp>
+#include <stout/option.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+#include <stout/uuid.hpp>
+
+#include "messages/messages.hpp" // For google::protobuf::Message.
+
+#include "master/allocator.hpp"
+#include "master/hierarchical_allocator_process.hpp"
+#include "master/master.hpp"
+
+#ifdef __linux__
+#include "slave/cgroups_isolator.hpp"
+#endif
+#include "slave/isolator.hpp"
+#include "slave/slave.hpp"
+
+#include "tests/cluster.hpp"
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+// Forward declarations.
+class MockExecutor;
+class TestingIsolator;
+
+
+class MesosTest : public ::testing::Test
+{
+protected:
+ MesosTest(const Option<zookeeper::URL>& url = None());
+
+ virtual void SetUp();
+ virtual void TearDown();
+
+ // Returns the flags used to create masters.
+ virtual master::Flags CreateMasterFlags();
+
+ // Returns the flags used to create slaves.
+ virtual slave::Flags CreateSlaveFlags();
+
+ // Starts a master with the specified flags.
+ virtual Try<process::PID<master::Master> > StartMaster(
+ const Option<master::Flags>& flags = None());
+
+ // Starts a master with the specified allocator process and flags.
+ virtual Try<process::PID<master::Master> > StartMaster(
+ master::AllocatorProcess* allocator,
+ const Option<master::Flags>& flags = None());
+
+ // Starts a slave with the specified flags.
+ virtual Try<process::PID<slave::Slave> > StartSlave(
+ const Option<slave::Flags>& flags = None());
+
+ // Starts a slave with the specified mock executor and flags.
+ virtual Try<process::PID<slave::Slave> > StartSlave(
+ MockExecutor* executor,
+ const Option<slave::Flags>& flags = None());
+
+ // Starts a slave with the specified isolator and flags.
+ virtual Try<process::PID<slave::Slave> > StartSlave(
+ slave::Isolator* isolator,
+ const Option<slave::Flags>& flags = None());
+
+ // Stop the specified master.
+ virtual void Stop(
+ const process::PID<master::Master>& pid);
+
+ // Stop the specified slave.
+ virtual void Stop(
+ const process::PID<slave::Slave>& pid,
+ bool shutdown = false);
+
+ // Stop all masters and slaves.
+ virtual void Shutdown();
+
+ // Stop all masters.
+ virtual void ShutdownMasters();
+
+ // Stop all slaves.
+ virtual void ShutdownSlaves();
+
+ Cluster cluster;
+
+ // TestingIsolator(s) created during test that we need to cleanup.
+ std::map<process::PID<slave::Slave>, TestingIsolator*> isolators;
+};
+
+
+
+template <typename T>
+class IsolatorTest : public MesosTest {};
+
+
+#ifdef __linux__
+// Cgroups hierarchy used by the cgroups related tests.
+const static std::string TEST_CGROUPS_HIERARCHY = "/tmp/mesos_test_cgroup";
+
+// Name of the root cgroup used by the cgroups related tests.
+const static std::string TEST_CGROUPS_ROOT = "mesos_test";
+
+
+template <>
+class IsolatorTest<slave::CgroupsIsolator> : public MesosTest
+{
+public:
+ static void SetUpTestCase();
+ static void TearDownTestCase();
+
+protected:
+ virtual slave::Flags CreateSlaveFlags();
+ virtual void SetUp();
+ virtual void TearDown();
+
+private:
+ std::string hierarchy;
+};
+#endif // __linux__
+
+
+// Macros to get/create (default) ExecutorInfos and FrameworkInfos.
+#define DEFAULT_EXECUTOR_INFO \
+ ({ ExecutorInfo executor; \
+ executor.mutable_executor_id()->set_value("default"); \
+ executor.mutable_command()->set_value("exit 1"); \
+ executor; })
+
+
+#define CREATE_EXECUTOR_INFO(executorId, command) \
+ ({ ExecutorInfo executor; \
+ executor.mutable_executor_id()->MergeFrom(executorId); \
+ executor.mutable_command()->set_value(command); \
+ executor; })
+
+
+#define DEFAULT_FRAMEWORK_INFO \
+ ({ FrameworkInfo framework; \
+ framework.set_name("default"); \
+ framework; })
+
+
+#define DEFAULT_EXECUTOR_ID \
+ DEFAULT_EXECUTOR_INFO.executor_id()
+
+
+inline TaskInfo createTask(
+ const Offer& offer,
+ const std::string& command,
+ const std::string& name = "test-task",
+ const std::string& id = UUID::random().toString())
+{
+ TaskInfo task;
+ task.set_name(name);
+ task.mutable_task_id()->set_value(id);
+ task.mutable_slave_id()->MergeFrom(offer.slave_id());
+ task.mutable_resources()->MergeFrom(offer.resources());
+ task.mutable_command()->set_value(command);
+
+ return task;
+}
+
+
+// Definition of a mock Scheduler to be used in tests with gmock.
+class MockScheduler : public Scheduler
+{
+public:
+ MOCK_METHOD3(registered, void(SchedulerDriver*,
+ const FrameworkID&,
+ const MasterInfo&));
+ MOCK_METHOD2(reregistered, void(SchedulerDriver*, const MasterInfo&));
+ MOCK_METHOD1(disconnected, void(SchedulerDriver*));
+ MOCK_METHOD2(resourceOffers, void(SchedulerDriver*,
+ const std::vector<Offer>&));
+ MOCK_METHOD2(offerRescinded, void(SchedulerDriver*, const OfferID&));
+ MOCK_METHOD2(statusUpdate, void(SchedulerDriver*, const TaskStatus&));
+ MOCK_METHOD4(frameworkMessage, void(SchedulerDriver*,
+ const ExecutorID&,
+ const SlaveID&,
+ const std::string&));
+ MOCK_METHOD2(slaveLost, void(SchedulerDriver*, const SlaveID&));
+ MOCK_METHOD4(executorLost, void(SchedulerDriver*,
+ const ExecutorID&,
+ const SlaveID&,
+ int));
+ MOCK_METHOD2(error, void(SchedulerDriver*, const std::string&));
+};
+
+// For use with a MockScheduler, for example:
+// EXPECT_CALL(sched, resourceOffers(_, _))
+// .WillOnce(LaunchTasks(TASKS, CPUS, MEM));
+// Launches up to TASKS no-op tasks, if possible,
+// each with CPUS cpus and MEM memory.
+ACTION_P3(LaunchTasks, tasks, cpus, mem)
+{
+ SchedulerDriver* driver = arg0;
+ std::vector<Offer> offers = arg1;
+ int numTasks = tasks;
+
+ int launched = 0;
+ for (size_t i = 0; i < offers.size(); i++) {
+ const Offer& offer = offers[i];
+ double offeredCpus = 0;
+ double offeredMem = 0;
+
+ for (int j = 0; j < offer.resources_size(); j++) {
+ const Resource& resource = offer.resources(j);
+ if (resource.name() == "cpus" &&
+ resource.type() == Value::SCALAR) {
+ offeredCpus = resource.scalar().value();
+ } else if (resource.name() == "mem" &&
+ resource.type() == Value::SCALAR) {
+ offeredMem = resource.scalar().value();
+ }
+ }
+
+ int nextTaskId = 0;
+ std::vector<TaskInfo> tasks;
+
+ while (offeredCpus >= cpus && offeredMem >= mem && launched < numTasks) {
+ TaskInfo task;
+ task.set_name("TestTask");
+ task.mutable_task_id()->set_value(stringify(nextTaskId++));
+ task.mutable_slave_id()->MergeFrom(offer.slave_id());
+
+ ExecutorInfo executor;
+ executor.mutable_executor_id()->set_value("default");
+ executor.mutable_command()->set_value(":");
+ task.mutable_executor()->MergeFrom(executor);
+
+ Resource* resource;
+ resource = task.add_resources();
+ resource->set_name("cpus");
+ resource->set_type(Value::SCALAR);
+ resource->mutable_scalar()->set_value(cpus);
+
+ resource = task.add_resources();
+ resource->set_name("mem");
+ resource->set_type(Value::SCALAR);
+ resource->mutable_scalar()->set_value(mem);
+
+ tasks.push_back(task);
+ launched++;
+ offeredCpus -= cpus;
+ offeredMem -= mem;
+ }
+
+ driver->launchTasks(offer.id(), tasks);
+ }
+}
+
+
+// Like LaunchTasks, but decline the entire offer and
+// don't launch any tasks.
+ACTION(DeclineOffers)
+{
+ SchedulerDriver* driver = arg0;
+ std::vector<Offer> offers = arg1;
+
+ for (size_t i = 0; i < offers.size(); i++) {
+ driver->declineOffer(offers[i].id());
+ }
+}
+
+
+// Definition of a mock Executor to be used in tests with gmock.
+class MockExecutor : public Executor
+{
+public:
+ MockExecutor(const ExecutorID& _id) : id(_id) {}
+
+ MOCK_METHOD4(registered, void(ExecutorDriver*,
+ const ExecutorInfo&,
+ const FrameworkInfo&,
+ const SlaveInfo&));
+ MOCK_METHOD2(reregistered, void(ExecutorDriver*, const SlaveInfo&));
+ MOCK_METHOD1(disconnected, void(ExecutorDriver*));
+ MOCK_METHOD2(launchTask, void(ExecutorDriver*, const TaskInfo&));
+ MOCK_METHOD2(killTask, void(ExecutorDriver*, const TaskID&));
+ MOCK_METHOD2(frameworkMessage, void(ExecutorDriver*, const std::string&));
+ MOCK_METHOD1(shutdown, void(ExecutorDriver*));
+ MOCK_METHOD2(error, void(ExecutorDriver*, const std::string&));
+
+ const ExecutorID id;
+};
+
+
+template <typename T = master::AllocatorProcess>
+class MockAllocatorProcess : public master::AllocatorProcess
+{
+public:
+ MockAllocatorProcess()
+ {
+ // Spawn the underlying allocator process.
+ process::spawn(real);
+
+ using ::testing::_;
+
+ ON_CALL(*this, initialize(_, _))
+ .WillByDefault(InvokeInitialize(this));
+
+ ON_CALL(*this, frameworkAdded(_, _, _))
+ .WillByDefault(InvokeFrameworkAdded(this));
+
+ ON_CALL(*this, frameworkRemoved(_))
+ .WillByDefault(InvokeFrameworkRemoved(this));
+
+ ON_CALL(*this, frameworkActivated(_, _))
+ .WillByDefault(InvokeFrameworkActivated(this));
+
+ ON_CALL(*this, frameworkDeactivated(_))
+ .WillByDefault(InvokeFrameworkDeactivated(this));
+
+ ON_CALL(*this, slaveAdded(_, _, _))
+ .WillByDefault(InvokeSlaveAdded(this));
+
+ ON_CALL(*this, slaveRemoved(_))
+ .WillByDefault(InvokeSlaveRemoved(this));
+
+ ON_CALL(*this, updateWhitelist(_))
+ .WillByDefault(InvokeUpdateWhitelist(this));
+
+ ON_CALL(*this, resourcesRequested(_, _))
+ .WillByDefault(InvokeResourcesRequested(this));
+
+ ON_CALL(*this, resourcesUnused(_, _, _, _))
+ .WillByDefault(InvokeResourcesUnused(this));
+
+ ON_CALL(*this, resourcesRecovered(_, _, _))
+ .WillByDefault(InvokeResourcesRecovered(this));
+
+ ON_CALL(*this, offersRevived(_))
+ .WillByDefault(InvokeOffersRevived(this));
+ }
+
+ ~MockAllocatorProcess()
+ {
+ process::terminate(real);
+ process::wait(real);
+ }
+
+ MOCK_METHOD2(initialize, void(const master::Flags&,
+ const process::PID<master::Master>&));
+ MOCK_METHOD3(frameworkAdded, void(const FrameworkID&,
+ const FrameworkInfo&,
+ const Resources&));
+ MOCK_METHOD1(frameworkRemoved, void(const FrameworkID&));
+ MOCK_METHOD2(frameworkActivated, void(const FrameworkID&,
+ const FrameworkInfo&));
+ MOCK_METHOD1(frameworkDeactivated, void(const FrameworkID&));
+ MOCK_METHOD3(slaveAdded, void(const SlaveID&,
+ const SlaveInfo&,
+ const hashmap<FrameworkID, Resources>&));
+ MOCK_METHOD1(slaveRemoved, void(const SlaveID&));
+ MOCK_METHOD1(updateWhitelist, void(const Option<hashset<std::string> >&));
+ MOCK_METHOD2(resourcesRequested, void(const FrameworkID&,
+ const std::vector<Request>&));
+ MOCK_METHOD4(resourcesUnused, void(const FrameworkID&,
+ const SlaveID&,
+ const Resources&,
+ const Option<Filters>& filters));
+ MOCK_METHOD3(resourcesRecovered, void(const FrameworkID&,
+ const SlaveID&,
+ const Resources&));
+ MOCK_METHOD1(offersRevived, void(const FrameworkID&));
+
+ T real;
+};
+
+
+typedef ::testing::Types<master::HierarchicalDRFAllocatorProcess>
+AllocatorTypes;
+
+
+// The following actions make up for the fact that DoDefault
+// cannot be used inside a DoAll, for example:
+// EXPECT_CALL(allocator, frameworkAdded(_, _, _))
+// .WillOnce(DoAll(InvokeFrameworkAdded(&allocator),
+// FutureSatisfy(&frameworkAdded)));
+
+ACTION_P(InvokeInitialize, allocator)
+{
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::initialize,
+ arg0,
+ arg1);
+}
+
+
+ACTION_P(InvokeFrameworkAdded, allocator)
+{
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::frameworkAdded,
+ arg0,
+ arg1,
+ arg2);
+}
+
+
+ACTION_P(InvokeFrameworkRemoved, allocator)
+{
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::frameworkRemoved, arg0);
+}
+
+
+ACTION_P(InvokeFrameworkActivated, allocator)
+{
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::frameworkActivated,
+ arg0,
+ arg1);
+}
+
+
+ACTION_P(InvokeFrameworkDeactivated, allocator)
+{
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::frameworkDeactivated,
+ arg0);
+}
+
+
+ACTION_P(InvokeSlaveAdded, allocator)
+{
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::slaveAdded,
+ arg0,
+ arg1,
+ arg2);
+}
+
+
+ACTION_P(InvokeSlaveRemoved, allocator)
+{
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::slaveRemoved,
+ arg0);
+}
+
+
+ACTION_P(InvokeUpdateWhitelist, allocator)
+{
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::updateWhitelist,
+ arg0);
+}
+
+
+ACTION_P(InvokeResourcesRequested, allocator)
+{
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::resourcesRequested,
+ arg0,
+ arg1);
+}
+
+
+
+ACTION_P(InvokeResourcesUnused, allocator)
+{
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::resourcesUnused,
+ arg0,
+ arg1,
+ arg2,
+ arg3);
+}
+
+
+ACTION_P2(InvokeUnusedWithFilters, allocator, timeout)
+{
+ Filters filters;
+ filters.set_refuse_seconds(timeout);
+
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::resourcesUnused,
+ arg0,
+ arg1,
+ arg2,
+ filters);
+}
+
+
+ACTION_P(InvokeResourcesRecovered, allocator)
+{
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::resourcesRecovered,
+ arg0,
+ arg1,
+ arg2);
+}
+
+
+ACTION_P(InvokeOffersRevived, allocator)
+{
+ process::dispatch(
+ allocator->real,
+ &master::AllocatorProcess::offersRevived,
+ arg0);
+}
+
+
+class OfferEqMatcher
+ : public ::testing::MatcherInterface<const std::vector<Offer>& >
+{
+public:
+ OfferEqMatcher(int _cpus, int _mem)
+ : cpus(_cpus), mem(_mem) {}
+
+ virtual bool MatchAndExplain(const std::vector<Offer>& offers,
+ ::testing::MatchResultListener* listener) const
+ {
+ double totalCpus = 0;
+ double totalMem = 0;
+
+ foreach (const Offer& offer, offers) {
+ foreach (const Resource& resource, offer.resources()) {
+ if (resource.name() == "cpus") {
+ totalCpus += resource.scalar().value();
+ } else if (resource.name() == "mem") {
+ totalMem += resource.scalar().value();
+ }
+ }
+ }
+
+ bool matches = totalCpus == cpus && totalMem == mem;
+
+ if (!matches) {
+ *listener << totalCpus << " cpus and " << totalMem << "mem";
+ }
+
+ return matches;
+ }
+
+ virtual void DescribeTo(::std::ostream* os) const
+ {
+ *os << "contains " << cpus << " cpus and " << mem << " mem";
+ }
+
+ virtual void DescribeNegationTo(::std::ostream* os) const
+ {
+ *os << "does not contain " << cpus << " cpus and " << mem << " mem";
+ }
+
+private:
+ int cpus;
+ int mem;
+};
+
+
+inline const ::testing::Matcher<const std::vector<Offer>& > OfferEq(int cpus, int mem)
+{
+ return MakeMatcher(new OfferEqMatcher(cpus, mem));
+}
+
+
+// Definition of the SendStatusUpdateFromTask action to be used with gmock.
+ACTION_P(SendStatusUpdateFromTask, state)
+{
+ TaskStatus status;
+ status.mutable_task_id()->MergeFrom(arg1.task_id());
+ status.set_state(state);
+ arg0->sendStatusUpdate(status);
+}
+
+
+// Definition of the SendStatusUpdateFromTaskID action to be used with gmock.
+ACTION_P(SendStatusUpdateFromTaskID, state)
+{
+ TaskStatus status;
+ status.mutable_task_id()->MergeFrom(arg1);
+ status.set_state(state);
+ arg0->sendStatusUpdate(status);
+}
+
+
+#define FUTURE_PROTOBUF(message, from, to) \
+ FutureProtobuf(message, from, to)
+
+
+#define DROP_PROTOBUF(message, from, to) \
+ FutureProtobuf(message, from, to, true)
+
+
+#define DROP_PROTOBUFS(message, from, to) \
+ DropProtobufs(message, from, to)
+
+
+// Forward declaration.
+template <typename T>
+T _FutureProtobuf(const process::Message& message);
+
+
+template <typename T, typename From, typename To>
+process::Future<T> FutureProtobuf(T t, From from, To to, bool drop = false)
+{
+ // Help debugging by adding some "type constraints".
+ { google::protobuf::Message* m = &t; (void) m; }
+
+ return process::FutureMessage(testing::Eq(t.GetTypeName()), from, to, drop)
+ .then(lambda::bind(&_FutureProtobuf<T>, lambda::_1));
+}
+
+
+template <typename T>
+T _FutureProtobuf(const process::Message& message)
+{
+ T t;
+ t.ParseFromString(message.body);
+ return t;
+}
+
+
+template <typename T, typename From, typename To>
+void DropProtobufs(T t, From from, To to)
+{
+ // Help debugging by adding some "type constraints".
+ { google::protobuf::Message* m = &t; (void) m; }
+
+ process::DropMessages(testing::Eq(t.GetTypeName()), from, to);
+}
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __TESTS_MESOS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/monitor_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/monitor_tests.cpp b/src/tests/monitor_tests.cpp
index 6a7be76..5681af2 100644
--- a/src/tests/monitor_tests.cpp
+++ b/src/tests/monitor_tests.cpp
@@ -20,22 +20,19 @@
#include <gmock/gmock.h>
-#include <mesos/executor.hpp>
#include <mesos/mesos.hpp>
#include <process/clock.hpp>
#include <process/future.hpp>
-#include <process/gmock.hpp>
+#include <process/gtest.hpp>
#include <process/http.hpp>
#include <process/pid.hpp>
#include <process/process.hpp>
-#include <stout/duration.hpp>
-
#include "slave/constants.hpp"
#include "slave/monitor.hpp"
-#include "tests/utils.hpp"
+#include "tests/isolator.hpp"
using namespace mesos;
using namespace mesos::internal;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/paths_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/paths_tests.cpp b/src/tests/paths_tests.cpp
index 84ad9b3..655e9ce 100644
--- a/src/tests/paths_tests.cpp
+++ b/src/tests/paths_tests.cpp
@@ -29,8 +29,6 @@
#include "slave/paths.hpp"
#include "slave/state.hpp"
-#include "tests/utils.hpp"
-
namespace mesos {
namespace internal {
namespace slave {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/protobuf_io_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/protobuf_io_tests.cpp b/src/tests/protobuf_io_tests.cpp
index b6478b3..5f80c04 100644
--- a/src/tests/protobuf_io_tests.cpp
+++ b/src/tests/protobuf_io_tests.cpp
@@ -20,6 +20,7 @@
#include <gmock/gmock.h>
+#include <stout/gtest.hpp>
#include <stout/none.hpp>
#include <stout/os.hpp>
#include <stout/protobuf.hpp>
@@ -29,8 +30,6 @@
#include "messages/messages.hpp"
-#include "tests/utils.hpp"
-
using namespace mesos;
using namespace mesos::internal;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/reaper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/reaper_tests.cpp b/src/tests/reaper_tests.cpp
index c1fc1c3..fbb6066 100644
--- a/src/tests/reaper_tests.cpp
+++ b/src/tests/reaper_tests.cpp
@@ -21,26 +21,31 @@
#include <gtest/gtest.h>
+#include <process/clock.hpp>
#include <process/dispatch.hpp>
#include <process/gmock.hpp>
-
-#include <stout/exit.hpp>
+#include <process/gtest.hpp>
#include "slave/reaper.hpp"
-#include "tests/utils.hpp"
-
using namespace mesos;
using namespace mesos::internal;
using namespace mesos::internal::slave;
-using namespace mesos::internal::tests;
+using process::Clock;
using process::Future;
using testing::_;
using testing::DoDefault;
+class MockProcessListener : public ProcessExitedListener
+{
+public:
+ MOCK_METHOD2(processExited, void(pid_t, int));
+};
+
+
// This test checks that the Reaper can monitor a non-child process.
TEST(ReaperTest, NonChildProcess)
{
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/resource_offers_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/resource_offers_tests.cpp b/src/tests/resource_offers_tests.cpp
index 0be5497..28ec4bc 100644
--- a/src/tests/resource_offers_tests.cpp
+++ b/src/tests/resource_offers_tests.cpp
@@ -30,7 +30,7 @@
#include "slave/slave.hpp"
-#include "tests/utils.hpp"
+#include "tests/mesos.hpp"
using namespace mesos;
using namespace mesos::internal;
@@ -409,16 +409,18 @@ TEST(ResourceOffersTest, ResourcesGetReofferedAfterTaskInfoError)
// unique task IDs and aggregate resource usage.
-TEST(ResourceOffersTest, Request)
-{
- Cluster cluster;
+// TODO(benh): Eliminate this class once we replace tests above to use
+// MesosTest/Cluster instead of local::launch.
+class ResourceOffersMesosTest : public MesosTest {};
+TEST_F(ResourceOffersMesosTest, Request)
+{
MockAllocatorProcess<HierarchicalDRFAllocatorProcess> allocator;
EXPECT_CALL(allocator, initialize(_, _))
.Times(1);
- Try<PID<Master> > master = cluster.masters.start(&allocator);
+ Try<PID<Master> > master = StartMaster(&allocator);
ASSERT_SOME(master);
MockScheduler sched;
@@ -460,21 +462,21 @@ TEST(ResourceOffersTest, Request)
driver.stop();
driver.join();
- cluster.shutdown();
+ Shutdown();
}
-class MultipleExecutorsTest : public MesosClusterTest {};
+class MultipleExecutorsTest : public MesosTest {};
TEST_F(MultipleExecutorsTest, TasksExecutorInfoDiffers)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- Try<PID<Slave> > slave = cluster.slaves.start(DEFAULT_EXECUTOR_ID, &exec);
+ Try<PID<Slave> > slave = StartSlave(&exec);
ASSERT_SOME(master);
MockScheduler sched;
@@ -551,5 +553,5 @@ TEST_F(MultipleExecutorsTest, TasksExecutorInfoDiffers)
AWAIT_READY(shutdown); // To ensure can deallocate MockExecutor.
- cluster.shutdown();
+ Shutdown();
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/script.cpp
----------------------------------------------------------------------
diff --git a/src/tests/script.cpp b/src/tests/script.cpp
index e2b4efa..74ce91a 100644
--- a/src/tests/script.cpp
+++ b/src/tests/script.cpp
@@ -28,9 +28,11 @@
#include <stout/path.hpp>
#include <stout/strings.hpp>
+#include "logging/logging.hpp"
+
#include "tests/environment.hpp"
+#include "tests/flags.hpp"
#include "tests/script.hpp"
-#include "tests/utils.hpp"
using std::string;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/slave_recovery_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/slave_recovery_tests.cpp b/src/tests/slave_recovery_tests.cpp
index fd6b9ac..65f50ed 100644
--- a/src/tests/slave_recovery_tests.cpp
+++ b/src/tests/slave_recovery_tests.cpp
@@ -44,8 +44,6 @@
#include "linux/cgroups.hpp"
#endif
-#include "master/allocator.hpp"
-#include "master/hierarchical_allocator_process.hpp"
#include "master/master.hpp"
#ifdef __linux__
@@ -59,6 +57,7 @@
#include "messages/messages.hpp"
+#include "tests/mesos.hpp"
#include "tests/utils.hpp"
using namespace mesos;
@@ -69,8 +68,6 @@ using namespace mesos::internal::utils::process;
using namespace process;
-using mesos::internal::master::Allocator;
-using mesos::internal::master::HierarchicalDRFAllocatorProcess;
using mesos::internal::master::Master;
#ifdef __linux__
@@ -83,7 +80,6 @@ using std::string;
using std::vector;
using testing::_;
-using testing::DoAll;
using testing::Eq;
using testing::Return;
using testing::SaveArg;
@@ -123,80 +119,17 @@ template <typename T>
class SlaveRecoveryTest : public IsolatorTest<T>
{
public:
- static void SetUpTestCase()
+ virtual slave::Flags CreateSlaveFlags()
{
- IsolatorTest<T>::SetUpTestCase();
- }
-
- virtual void SetUp()
- {
- IsolatorTest<T>::SetUp();
+ slave::Flags flags = IsolatorTest<T>::CreateSlaveFlags();
- a = new Allocator(&allocator);
- m = new Master(a, &files);
- master = process::spawn(m);
+ // Setup recovery slave flags.
+ flags.checkpoint = true;
+ flags.recover = "reconnect";
+ flags.safe = false;
- // Reset recovery slaveFlags.
- this->slaveFlags.checkpoint = true;
- this->slaveFlags.recover = "reconnect";
- this->slaveFlags.safe = false;
-
- startSlave();
+ return flags;
}
-
- virtual void TearDown()
- {
- stopSlave(true);
-
- process::terminate(master);
- process::wait(master);
- delete m;
- delete a;
-
- IsolatorTest<T>::TearDown();
- }
-
-protected:
- void startSlave()
- {
- isolator = new T();
- s = new Slave(this->slaveFlags, true, isolator, &files);
- slave = process::spawn(s);
- detector = new BasicMasterDetector(master, slave, true);
-
- running = true;
- }
-
- void stopSlave(bool shutdown = false)
- {
- if (!running) {
- return;
- }
-
- delete detector;
-
- if (shutdown) {
- process::dispatch(slave, &Slave::shutdown);
- } else {
- process::terminate(slave);
- }
- process::wait(slave);
- delete s;
- delete isolator;
-
- running = false;
- }
-
- HierarchicalDRFAllocatorProcess allocator;
- Allocator *a;
- Master* m;
- Isolator* isolator;
- Slave* s;
- Files files;
- BasicMasterDetector* detector;
- PID<Master> master;
- PID<Slave> slave;
- bool running; // Is the slave running?
};
@@ -206,13 +139,22 @@ typedef ::testing::Types<ProcessIsolator, CgroupsIsolator> IsolatorTypes;
typedef ::testing::Types<ProcessIsolator> IsolatorTypes;
#endif
-
TYPED_TEST_CASE(SlaveRecoveryTest, IsolatorTypes);
// Enable checkpointing on the slave and ensure recovery works.
TYPED_TEST(SlaveRecoveryTest, RecoverSlaveState)
{
+ Try<PID<Master> > master = this->StartMaster();
+ ASSERT_SOME(master);
+
+ TypeParam isolator;
+
+ slave::Flags flags = this->CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = this->StartSlave(&isolator, flags);
+ ASSERT_SOME(slave);
+
// Message expectations.
Future<Message> registerFramework =
FUTURE_MESSAGE(Eq(RegisterFrameworkMessage().GetTypeName()), _, _);
@@ -233,7 +175,7 @@ TYPED_TEST(SlaveRecoveryTest, RecoverSlaveState)
frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
frameworkInfo.set_checkpoint(true);
- MesosSchedulerDriver driver(&sched, frameworkInfo, this->master);
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
driver.start();
@@ -259,7 +201,7 @@ TYPED_TEST(SlaveRecoveryTest, RecoverSlaveState)
FUTURE_MESSAGE(Eq(RegisterExecutorMessage().GetTypeName()), _, _);
Future<StatusUpdateMessage> update =
- FUTURE_PROTOBUF(StatusUpdateMessage(), Eq(this->master), _);
+ FUTURE_PROTOBUF(StatusUpdateMessage(), Eq(master.get()), _);
Future<StatusUpdateAcknowledgementMessage> ack =
FUTURE_PROTOBUF(StatusUpdateAcknowledgementMessage(), _, _);
@@ -284,8 +226,8 @@ TYPED_TEST(SlaveRecoveryTest, RecoverSlaveState)
AWAIT_READY(_ack);
// Recover the state.
- Result<state::SlaveState> recover =
- state::recover(paths::getMetaRootDir(this->slaveFlags.work_dir), true);
+ Result<state::SlaveState> recover = state::recover(
+ paths::getMetaRootDir(flags.work_dir), true);
ASSERT_SOME(recover);
@@ -369,6 +311,8 @@ TYPED_TEST(SlaveRecoveryTest, RecoverSlaveState)
driver.stop();
driver.join();
+
+ this->Shutdown(); // Shutdown before isolator(s) get deallocated.
}
@@ -376,6 +320,16 @@ TYPED_TEST(SlaveRecoveryTest, RecoverSlaveState)
// When the slave comes back up it resends the unacknowledged update.
TYPED_TEST(SlaveRecoveryTest, RecoverStatusUpdateManager)
{
+ Try<PID<Master> > master = this->StartMaster();
+ ASSERT_SOME(master);
+
+ TypeParam isolator1;
+
+ slave::Flags flags = this->CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
+ ASSERT_SOME(slave);
+
// Scheduler expectations.
MockScheduler sched;
@@ -391,7 +345,7 @@ TYPED_TEST(SlaveRecoveryTest, RecoverStatusUpdateManager)
frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
frameworkInfo.set_checkpoint(true);
- MesosSchedulerDriver driver(&sched, frameworkInfo, this->master);
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
driver.start();
@@ -419,15 +373,18 @@ TYPED_TEST(SlaveRecoveryTest, RecoverStatusUpdateManager)
// Wait for the status update drop.
AWAIT_READY(update);
- this->stopSlave();
+ this->Stop(slave.get());
Future<TaskStatus> status;
EXPECT_CALL(sched, statusUpdate(_, _))
.WillOnce(FutureArg<1>(&status))
.WillRepeatedly(Return()); // Ignore subsequent updates.
- // Restart the slave.
- this->startSlave();
+ // Restart the slave (use same flags) with a new isolator.
+ TypeParam isolator2;
+
+ slave = this->StartSlave(&isolator2, flags);
+ ASSERT_SOME(slave);
AWAIT_READY(status);
ASSERT_EQ(TASK_RUNNING, status.get().state());
@@ -437,6 +394,8 @@ TYPED_TEST(SlaveRecoveryTest, RecoverStatusUpdateManager)
driver.stop();
driver.join();
+
+ this->Shutdown(); // Shutdown before isolator(s) get deallocated.
}
@@ -445,6 +404,16 @@ TYPED_TEST(SlaveRecoveryTest, RecoverStatusUpdateManager)
// sure the executor re-registers and the slave properly sends the update.
TYPED_TEST(SlaveRecoveryTest, ReconnectExecutor)
{
+ Try<PID<Master> > master = this->StartMaster();
+ ASSERT_SOME(master);
+
+ TypeParam isolator1;
+
+ slave::Flags flags = this->CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
+ ASSERT_SOME(slave);
+
// Scheduler expectations.
MockScheduler sched;
EXPECT_CALL(sched, registered(_, _, _));
@@ -459,7 +428,7 @@ TYPED_TEST(SlaveRecoveryTest, ReconnectExecutor)
frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
frameworkInfo.set_checkpoint(true);
- MesosSchedulerDriver driver(&sched, frameworkInfo, this->master);
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
driver.start();
@@ -479,7 +448,7 @@ TYPED_TEST(SlaveRecoveryTest, ReconnectExecutor)
// Stop the slave before the status update is received.
AWAIT_READY(statusUpdate);
- this->stopSlave();
+ this->Stop(slave.get());
Future<Message> reregisterExecutorMessage =
FUTURE_MESSAGE(Eq(ReregisterExecutorMessage().GetTypeName()), _, _);
@@ -489,8 +458,11 @@ TYPED_TEST(SlaveRecoveryTest, ReconnectExecutor)
.WillOnce(FutureArg<1>(&status))
.WillRepeatedly(Return()); // Ignore subsequent updates.
- // Restart the slave.
- this->startSlave();
+ // Restart the slave (use same flags) with a new isolator.
+ TypeParam isolator2;
+
+ slave = this->StartSlave(&isolator2, flags);
+ ASSERT_SOME(slave);
// Ensure the executor re-registers.
AWAIT_READY(reregisterExecutorMessage);
@@ -514,6 +486,8 @@ TYPED_TEST(SlaveRecoveryTest, ReconnectExecutor)
driver.stop();
driver.join();
+
+ this->Shutdown(); // Shutdown before isolator(s) get deallocated.
}
@@ -522,6 +496,16 @@ TYPED_TEST(SlaveRecoveryTest, ReconnectExecutor)
// executor is killed and the task is transitioned to FAILED.
TYPED_TEST(SlaveRecoveryTest, RecoverUnregisteredExecutor)
{
+ Try<PID<Master> > master = this->StartMaster();
+ ASSERT_SOME(master);
+
+ TypeParam isolator1;
+
+ slave::Flags flags = this->CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
+ ASSERT_SOME(slave);
+
// Scheduler expectations.
MockScheduler sched;
EXPECT_CALL(sched, registered(_, _, _));
@@ -536,7 +520,7 @@ TYPED_TEST(SlaveRecoveryTest, RecoverUnregisteredExecutor)
frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
frameworkInfo.set_checkpoint(true);
- MesosSchedulerDriver driver(&sched, frameworkInfo, this->master);
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
driver.start();
@@ -557,7 +541,7 @@ TYPED_TEST(SlaveRecoveryTest, RecoverUnregisteredExecutor)
AWAIT_READY(registerExecutor);
UPID executorPid = registerExecutor.get().from;
- this->stopSlave();
+ this->Stop(slave.get());
Future<TaskStatus> status;
EXPECT_CALL(sched, statusUpdate(_, _))
@@ -566,8 +550,11 @@ TYPED_TEST(SlaveRecoveryTest, RecoverUnregisteredExecutor)
Future<Nothing> recover = FUTURE_DISPATCH(_, &Slave::_recover);
- // Restart the slave.
- this->startSlave();
+ // Restart the slave (use same flags) with a new isolator.
+ TypeParam isolator2;
+
+ slave = this->StartSlave(&isolator2, flags);
+ ASSERT_SOME(slave);
Clock::pause();
@@ -591,6 +578,8 @@ TYPED_TEST(SlaveRecoveryTest, RecoverUnregisteredExecutor)
driver.stop();
driver.join();
+
+ this->Shutdown(); // Shutdown before isolator(s) get deallocated.
}
@@ -600,6 +589,16 @@ TYPED_TEST(SlaveRecoveryTest, RecoverUnregisteredExecutor)
// sure the task is properly transitioned to FAILED.
TYPED_TEST(SlaveRecoveryTest, RecoverTerminatedExecutor)
{
+ Try<PID<Master> > master = this->StartMaster();
+ ASSERT_SOME(master);
+
+ TypeParam isolator1;
+
+ slave::Flags flags = this->CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
+ ASSERT_SOME(slave);
+
// Scheduler expectations.
MockScheduler sched;
EXPECT_CALL(sched, registered(_, _, _));
@@ -614,7 +613,7 @@ TYPED_TEST(SlaveRecoveryTest, RecoverTerminatedExecutor)
frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
frameworkInfo.set_checkpoint(true);
- MesosSchedulerDriver driver(&sched, frameworkInfo, this->master);
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
driver.start();
@@ -642,7 +641,7 @@ TYPED_TEST(SlaveRecoveryTest, RecoverTerminatedExecutor)
// Wait for the ACK to be checkpointed.
AWAIT_READY(ack);
- this->stopSlave();
+ this->Stop(slave.get());
Future<TaskStatus> status;
EXPECT_CALL(sched, statusUpdate(_, _))
@@ -653,8 +652,11 @@ TYPED_TEST(SlaveRecoveryTest, RecoverTerminatedExecutor)
Future<Nothing> recover = FUTURE_DISPATCH(_, &Slave::_recover);
- // Restart the slave.
- this->startSlave();
+ // Restart the slave (use same flags) with a new isolator.
+ TypeParam isolator2;
+
+ slave = this->StartSlave(&isolator2, flags);
+ ASSERT_SOME(slave);
Clock::pause();
@@ -676,6 +678,8 @@ TYPED_TEST(SlaveRecoveryTest, RecoverTerminatedExecutor)
driver.stop();
driver.join();
+
+ this->Shutdown(); // Shutdown before isolator(s) get deallocated.
}
@@ -684,6 +688,16 @@ TYPED_TEST(SlaveRecoveryTest, RecoverTerminatedExecutor)
// executor, and transitions the task to FAILED.
TYPED_TEST(SlaveRecoveryTest, CleanupExecutor)
{
+ Try<PID<Master> > master = this->StartMaster();
+ ASSERT_SOME(master);
+
+ TypeParam isolator1;
+
+ slave::Flags flags = this->CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
+ ASSERT_SOME(slave);
+
// Scheduler expectations.
MockScheduler sched;
EXPECT_CALL(sched, registered(_, _, _));
@@ -698,7 +712,7 @@ TYPED_TEST(SlaveRecoveryTest, CleanupExecutor)
frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
frameworkInfo.set_checkpoint(true);
- MesosSchedulerDriver driver(&sched, frameworkInfo, this->master);
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
driver.start();
@@ -719,15 +733,19 @@ TYPED_TEST(SlaveRecoveryTest, CleanupExecutor)
// Wait for the ACK to be checkpointed.
AWAIT_READY(ack);
- this->stopSlave();
+ this->Stop(slave.get());
Future<TaskStatus> status;
EXPECT_CALL(sched, statusUpdate(_, _))
.WillOnce(FutureArg<1>(&status));
- // Restart the slave in 'cleanup' recovery mode.
- this->slaveFlags.recover = "cleanup";
- this->startSlave();
+ // Restart the slave in 'cleanup' recovery mode with a new isolator.
+ TypeParam isolator2;
+
+ flags.recover = "cleanup";
+
+ slave = this->StartSlave(&isolator2, flags);
+ ASSERT_SOME(slave);
Clock::pause();
@@ -745,6 +763,8 @@ TYPED_TEST(SlaveRecoveryTest, CleanupExecutor)
driver.stop();
driver.join();
+
+ this->Shutdown(); // Shutdown before isolator(s) get deallocated.
}
@@ -752,6 +772,14 @@ TYPED_TEST(SlaveRecoveryTest, CleanupExecutor)
// properly removed, when a checkpointing slave is disconnected.
TYPED_TEST(SlaveRecoveryTest, RemoveNonCheckpointingFramework)
{
+ Try<PID<Master> > master = this->StartMaster();
+ ASSERT_SOME(master);
+
+ TypeParam isolator;
+
+ Try<PID<Slave> > slave = this->StartSlave(&isolator);
+ ASSERT_SOME(slave);
+
// Scheduler expectations.
MockScheduler sched;
EXPECT_CALL(sched, registered(_, _, _));
@@ -766,7 +794,7 @@ TYPED_TEST(SlaveRecoveryTest, RemoveNonCheckpointingFramework)
frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
frameworkInfo.set_checkpoint(false);
- MesosSchedulerDriver driver(&sched, frameworkInfo, this->master);
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
driver.start();
@@ -790,7 +818,7 @@ TYPED_TEST(SlaveRecoveryTest, RemoveNonCheckpointingFramework)
EXPECT_CALL(sched, statusUpdate(_, _))
.WillOnce(FutureArg<1>(&status));
- this->stopSlave();
+ this->Stop(slave.get());
// Scheduler should receive the TASK_LOST update.
AWAIT_READY(status);
@@ -798,6 +826,8 @@ TYPED_TEST(SlaveRecoveryTest, RemoveNonCheckpointingFramework)
driver.stop();
driver.join();
+
+ this->Shutdown(); // Shutdown before isolator(s) get deallocated.
}
@@ -805,6 +835,16 @@ TYPED_TEST(SlaveRecoveryTest, RemoveNonCheckpointingFramework)
// framework that has disabled checkpointing.
TYPED_TEST(SlaveRecoveryTest, NonCheckpointingFramework)
{
+ Try<PID<Master> > master = this->StartMaster();
+ ASSERT_SOME(master);
+
+ TypeParam isolator;
+
+ slave::Flags flags = this->CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = this->StartSlave(&isolator, flags);
+ ASSERT_SOME(slave);
+
// Scheduler expectations.
MockScheduler sched;
FrameworkID frameworkId;
@@ -821,7 +861,7 @@ TYPED_TEST(SlaveRecoveryTest, NonCheckpointingFramework)
frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
frameworkInfo.set_checkpoint(false);
- MesosSchedulerDriver driver(&sched, frameworkInfo, this->master);
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
driver.start();
@@ -844,11 +884,12 @@ TYPED_TEST(SlaveRecoveryTest, NonCheckpointingFramework)
Clock::pause();
- Future<Nothing> updateFramework = FUTURE_DISPATCH(_, &Slave::updateFramework);
+ Future<Nothing> updateFramework =
+ FUTURE_DISPATCH(_, &Slave::updateFramework);
// Simulate a 'UpdateFrameworkMessage' to ensure framework pid is
// not being checkpointed.
- process::dispatch(this->slave, &Slave::updateFramework, frameworkId, "");
+ process::dispatch(slave.get(), &Slave::updateFramework, frameworkId, "");
AWAIT_READY(updateFramework);
@@ -856,7 +897,7 @@ TYPED_TEST(SlaveRecoveryTest, NonCheckpointingFramework)
// Ensure that the framework info is not being checkpointed.
const string& path = paths::getFrameworkPath(
- paths::getMetaRootDir(this->slaveFlags.work_dir),
+ paths::getMetaRootDir(flags.work_dir),
task.slave_id(),
frameworkId);
@@ -866,6 +907,8 @@ TYPED_TEST(SlaveRecoveryTest, NonCheckpointingFramework)
driver.stop();
driver.join();
+
+ this->Shutdown(); // Shutdown before isolator(s) get deallocated.
}
@@ -875,6 +918,16 @@ TYPED_TEST(SlaveRecoveryTest, NonCheckpointingFramework)
// (scheduler, master, executor).
TYPED_TEST(SlaveRecoveryTest, KillTask)
{
+ Try<PID<Master> > master = this->StartMaster();
+ ASSERT_SOME(master);
+
+ TypeParam isolator1;
+
+ slave::Flags flags = this->CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
+ ASSERT_SOME(slave);
+
// Scheduler expectations.
MockScheduler sched;
EXPECT_CALL(sched, registered(_, _, _));
@@ -888,7 +941,7 @@ TYPED_TEST(SlaveRecoveryTest, KillTask)
frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
frameworkInfo.set_checkpoint(true);
- MesosSchedulerDriver driver(&sched, frameworkInfo, this->master);
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
driver.start();
@@ -909,15 +962,18 @@ TYPED_TEST(SlaveRecoveryTest, KillTask)
// Wait for the ACK to be checkpointed.
AWAIT_READY(ack);
- // Restart the slave.
- this->stopSlave();
+ this->Stop(slave.get());
Future<Nothing> recover = FUTURE_DISPATCH(_, &Slave::_recover);
Future<ReregisterSlaveMessage> reregisterSlave =
FUTURE_PROTOBUF(ReregisterSlaveMessage(), _, _);
- this->startSlave();
+ // Restart the slave (use same flags) with a new isolator.
+ TypeParam isolator2;
+
+ slave = this->StartSlave(&isolator2, flags);
+ ASSERT_SOME(slave);
Clock::pause();
@@ -963,6 +1019,8 @@ TYPED_TEST(SlaveRecoveryTest, KillTask)
driver.stop();
driver.join();
+
+ this->Shutdown(); // Shutdown before isolator(s) get deallocated.
}
@@ -971,6 +1029,16 @@ TYPED_TEST(SlaveRecoveryTest, KillTask)
// cannot recover the executor and hence schedules it for gc.
TYPED_TEST(SlaveRecoveryTest, GCExecutor)
{
+ Try<PID<Master> > master = this->StartMaster();
+ ASSERT_SOME(master);
+
+ TypeParam isolator1;
+
+ slave::Flags flags = this->CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
+ ASSERT_SOME(slave);
+
// Scheduler expectations.
MockScheduler sched;
EXPECT_CALL(sched, registered(_, _, _));
@@ -985,7 +1053,7 @@ TYPED_TEST(SlaveRecoveryTest, GCExecutor)
frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
frameworkInfo.set_checkpoint(true);
- MesosSchedulerDriver driver(&sched, frameworkInfo, this->master);
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
driver.start();
@@ -1020,7 +1088,7 @@ TYPED_TEST(SlaveRecoveryTest, GCExecutor)
// Wait for TASK_RUNNING update.
AWAIT_READY(status);
- this->stopSlave();
+ this->Stop(slave.get());
// Now shut down the executor, when the slave is down.
process::post(executorPid, ShutdownExecutorMessage());
@@ -1028,7 +1096,7 @@ TYPED_TEST(SlaveRecoveryTest, GCExecutor)
// Remove the symlink "latest" in the executor directory
// to simulate a non-recoverable executor.
ASSERT_SOME(os::rm(paths::getExecutorLatestRunPath(
- paths::getMetaRootDir(this->slaveFlags.work_dir),
+ paths::getMetaRootDir(flags.work_dir),
slaveId,
frameworkId,
executorId)));
@@ -1038,8 +1106,11 @@ TYPED_TEST(SlaveRecoveryTest, GCExecutor)
Future<ReregisterSlaveMessage> reregisterSlave =
FUTURE_PROTOBUF(ReregisterSlaveMessage(), _, _);
- // Restart the slave.
- this->startSlave();
+ // Restart the slave (use same flags) with a new isolator.
+ TypeParam isolator2;
+
+ slave = this->StartSlave(&isolator2, flags);
+ ASSERT_SOME(slave);
Clock::pause();
@@ -1053,16 +1124,16 @@ TYPED_TEST(SlaveRecoveryTest, GCExecutor)
AWAIT_READY(reregisterSlave);
- Clock::advance(this->slaveFlags.gc_delay);
+ Clock::advance(flags.gc_delay);
Clock::settle();
// Executor's work and meta directories should be gc'ed by now.
ASSERT_FALSE(os::exists(paths::getExecutorPath(
- this->slaveFlags.work_dir, slaveId, frameworkId, executorId)));
+ flags.work_dir, slaveId, frameworkId, executorId)));
ASSERT_FALSE(os::exists(paths::getExecutorPath(
- paths::getMetaRootDir(this->slaveFlags.work_dir),
+ paths::getMetaRootDir(flags.work_dir),
slaveId,
frameworkId,
executorId)));
@@ -1071,6 +1142,8 @@ TYPED_TEST(SlaveRecoveryTest, GCExecutor)
driver.stop();
driver.join();
+
+ this->Shutdown(); // Shutdown before isolator(s) get deallocated.
}
@@ -1078,6 +1151,16 @@ TYPED_TEST(SlaveRecoveryTest, GCExecutor)
// register as a new slave.
TYPED_TEST(SlaveRecoveryTest, ShutdownSlave)
{
+ Try<PID<Master> > master = this->StartMaster();
+ ASSERT_SOME(master);
+
+ TypeParam isolator1;
+
+ slave::Flags flags = this->CreateSlaveFlags();
+
+ Try<PID<Slave> > slave = this->StartSlave(&isolator1, flags);
+ ASSERT_SOME(slave);
+
// Scheduler expectations.
MockScheduler sched;
EXPECT_CALL(sched, registered(_, _, _));
@@ -1092,7 +1175,7 @@ TYPED_TEST(SlaveRecoveryTest, ShutdownSlave)
frameworkInfo.CopyFrom(DEFAULT_FRAMEWORK_INFO);
frameworkInfo.set_checkpoint(true);
- MesosSchedulerDriver driver(&sched, frameworkInfo, this->master);
+ MesosSchedulerDriver driver(&sched, frameworkInfo, master.get());
driver.start();
@@ -1139,16 +1222,18 @@ TYPED_TEST(SlaveRecoveryTest, ShutdownSlave)
Clock::resume();
- // Shut down the slave.
- this->stopSlave(true);
+ this->Stop(slave.get(), true); // Send a "shut down".
Future<vector<Offer> > offers2;
EXPECT_CALL(sched, resourceOffers(_, _))
.WillOnce(FutureArg<1>(&offers2))
.WillRepeatedly(Return()); // Ignore subsequent offers.
- // Now restart the slave.
- this->startSlave();
+ // Now restart the slave (use same flags) with a new isolator.
+ TypeParam isolator2;
+
+ slave = this->StartSlave(&isolator2, flags);
+ ASSERT_SOME(slave);
// Ensure that the slave registered with a new id.
AWAIT_READY(offers2);
@@ -1161,4 +1246,6 @@ TYPED_TEST(SlaveRecoveryTest, ShutdownSlave)
driver.stop();
driver.join();
+
+ this->Shutdown(); // Shutdown before isolator(s) get deallocated.
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/state_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/state_tests.cpp b/src/tests/state_tests.cpp
index 9066025..2e75673 100644
--- a/src/tests/state_tests.cpp
+++ b/src/tests/state_tests.cpp
@@ -25,8 +25,10 @@
#include <mesos/mesos.hpp>
#include <process/future.hpp>
+#include <process/gtest.hpp>
#include <process/protobuf.hpp>
+#include <stout/gtest.hpp>
#include <stout/option.hpp>
#include <stout/os.hpp>
@@ -39,7 +41,6 @@
#include "state/state.hpp"
#include "state/zookeeper.hpp"
-#include "tests/utils.hpp"
#ifdef MESOS_HAS_JAVA
#include "tests/zookeeper.hpp"
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/status_update_manager_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/status_update_manager_tests.cpp b/src/tests/status_update_manager_tests.cpp
index 042201a..892a3f1 100644
--- a/src/tests/status_update_manager_tests.cpp
+++ b/src/tests/status_update_manager_tests.cpp
@@ -44,7 +44,7 @@
#include "messages/messages.hpp"
-#include "tests/utils.hpp"
+#include "tests/mesos.hpp"
using namespace mesos;
using namespace mesos::internal;
@@ -85,20 +85,20 @@ vector<TaskInfo> createTasks(const Offer& offer)
}
-class StatusUpdateManagerTest: public MesosClusterTest {};
+class StatusUpdateManagerTest: public MesosTest {};
TEST_F(StatusUpdateManagerTest, CheckpointStatusUpdate)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- slave::Flags flags = cluster.slaves.flags;
+ slave::Flags flags = CreateSlaveFlags();
flags.checkpoint = true;
- Try<PID<Slave> > slave = cluster.slaves.start(
- flags, DEFAULT_EXECUTOR_ID, &exec);
+
+ Try<PID<Slave> > slave = StartSlave(&exec, flags);
ASSERT_SOME(slave);
FrameworkInfo frameworkInfo; // Bug in gcc 4.1.*, must assign on next line.
@@ -185,21 +185,21 @@ TEST_F(StatusUpdateManagerTest, CheckpointStatusUpdate)
AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
- cluster.shutdown();
+ Shutdown();
}
TEST_F(StatusUpdateManagerTest, RetryStatusUpdate)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- slave::Flags flags = cluster.slaves.flags;
+ slave::Flags flags = CreateSlaveFlags();
flags.checkpoint = true;
- Try<PID<Slave> > slave = cluster.slaves.start(
- flags, DEFAULT_EXECUTOR_ID, &exec);
+
+ Try<PID<Slave> > slave = StartSlave(&exec, flags);
ASSERT_SOME(slave);
FrameworkInfo frameworkInfo; // Bug in gcc 4.1.*, must assign on next line.
@@ -258,7 +258,7 @@ TEST_F(StatusUpdateManagerTest, RetryStatusUpdate)
AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
- cluster.shutdown();
+ Shutdown();
}
@@ -268,15 +268,15 @@ TEST_F(StatusUpdateManagerTest, RetryStatusUpdate)
// duplicate ACK is for a retried update.
TEST_F(StatusUpdateManagerTest, IgnoreDuplicateStatusUpdateAck)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- slave::Flags flags = cluster.slaves.flags;
+ slave::Flags flags = CreateSlaveFlags();
flags.checkpoint = true;
- Try<PID<Slave> > slave = cluster.slaves.start(
- flags, DEFAULT_EXECUTOR_ID, &exec);
+
+ Try<PID<Slave> > slave = StartSlave(&exec, flags);
ASSERT_SOME(slave);
FrameworkInfo frameworkInfo; // Bug in gcc 4.1.*, must assign on next line.
@@ -378,7 +378,7 @@ TEST_F(StatusUpdateManagerTest, IgnoreDuplicateStatusUpdateAck)
AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
- cluster.shutdown();
+ Shutdown();
}
@@ -388,15 +388,15 @@ TEST_F(StatusUpdateManagerTest, IgnoreDuplicateStatusUpdateAck)
// for the original update and sending a random ACK to the slave.
TEST_F(StatusUpdateManagerTest, IgnoreUnexpectedStatusUpdateAck)
{
- Try<PID<Master> > master = cluster.masters.start();
+ Try<PID<Master> > master = StartMaster();
ASSERT_SOME(master);
- MockExecutor exec;
+ MockExecutor exec(DEFAULT_EXECUTOR_ID);
- slave::Flags flags = cluster.slaves.flags;
+ slave::Flags flags = CreateSlaveFlags();
flags.checkpoint = true;
- Try<PID<Slave> > slave = cluster.slaves.start(
- flags, DEFAULT_EXECUTOR_ID, &exec);
+
+ Try<PID<Slave> > slave = StartSlave(&exec, flags);
ASSERT_SOME(slave);
FrameworkInfo frameworkInfo; // Bug in gcc 4.1.*, must assign on next line.
@@ -473,5 +473,5 @@ TEST_F(StatusUpdateManagerTest, IgnoreUnexpectedStatusUpdateAck)
AWAIT_READY(shutdown); // Ensures MockExecutor can be deallocated.
- cluster.shutdown();
+ Shutdown();
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6b1b8208/src/tests/utils.cpp
----------------------------------------------------------------------
diff --git a/src/tests/utils.cpp b/src/tests/utils.cpp
index 9a83053..05ef305 100644
--- a/src/tests/utils.cpp
+++ b/src/tests/utils.cpp
@@ -22,6 +22,7 @@
#include <gtest/gtest.h>
+#include <stout/gtest.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/strings.hpp>
[04/28] git commit: Removed unused variables in
AllocatorZooKeeperTest.
Posted by be...@apache.org.
Removed unused variables in AllocatorZooKeeperTest.
Review: https://reviews.apache.org/r/11271
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/1d71e42b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/1d71e42b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/1d71e42b
Branch: refs/heads/master
Commit: 1d71e42b543c247a2e2bd060d9d5c90f136a8fd6
Parents: 233edea
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sun May 5 16:23:43 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Fri May 24 22:05:05 2013 -0700
----------------------------------------------------------------------
src/tests/allocator_zookeeper_tests.cpp | 19 -------------------
1 files changed, 0 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1d71e42b/src/tests/allocator_zookeeper_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/allocator_zookeeper_tests.cpp b/src/tests/allocator_zookeeper_tests.cpp
index bb7f84d..962e876 100644
--- a/src/tests/allocator_zookeeper_tests.cpp
+++ b/src/tests/allocator_zookeeper_tests.cpp
@@ -61,28 +61,9 @@ using testing::SaveArg;
template <typename T = AllocatorProcess>
class AllocatorZooKeeperTest : public ZooKeeperTest
{
-public:
- virtual void SetUp()
- {
- ZooKeeperTest::SetUp();
-
- a1 = new Allocator(&allocator1);
- a2 = new Allocator(&allocator2);
- }
-
- virtual void TearDown()
- {
- ZooKeeperTest::TearDown();
-
- delete a1;
- delete a2;
- }
-
protected:
T allocator1;
MockAllocatorProcess<T> allocator2;
- Allocator* a1;
- Allocator* a2;
};
[09/28] git commit: Improved library for using JVM/JNI and updated
uses (in tests).
Posted by be...@apache.org.
Improved library for using JVM/JNI and updated uses (in tests).
Review: https://reviews.apache.org/r/11270
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/233edea2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/233edea2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/233edea2
Branch: refs/heads/master
Commit: 233edea23871302be582ddba340cfc6c7c68ef30
Parents: 07c44ce
Author: Benjamin Hindman <be...@twitter.com>
Authored: Thu May 2 09:29:32 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Fri May 24 22:05:05 2013 -0700
----------------------------------------------------------------------
src/Makefile.am | 18 +-
src/jvm/java/io.hpp | 36 ++
src/jvm/java/lang.hpp | 31 ++
src/jvm/java/net.hpp | 26 +
src/jvm/jvm.cpp | 767 ++++++++++++++++++------------
src/jvm/jvm.hpp | 367 ++++++++++-----
src/jvm/org/apache/log4j.cpp | 16 +
src/jvm/org/apache/log4j.hpp | 69 +++
src/jvm/org/apache/zookeeper.hpp | 168 +++++++
src/tests/zookeeper_test.cpp | 72 +--
src/tests/zookeeper_test.hpp | 12 +-
src/tests/zookeeper_test_server.cpp | 201 ++------
src/tests/zookeeper_test_server.hpp | 55 +--
13 files changed, 1131 insertions(+), 707 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 5ed3423..fe31707 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -552,14 +552,24 @@ CLEANFILES += $(MESOS_SOURCES_JAR)
# main libmesos.so.
noinst_LTLIBRARIES += libjava.la
-libjava_la_SOURCES = java/jni/convert.cpp java/jni/construct.cpp \
+libjava_la_SOURCES = \
+ java/jni/convert.cpp \
+ java/jni/convert.hpp \
+ java/jni/construct.cpp \
+ java/jni/construct.hpp \
java/jni/org_apache_mesos_Log.cpp \
java/jni/org_apache_mesos_MesosSchedulerDriver.cpp \
java/jni/org_apache_mesos_MesosExecutorDriver.cpp \
java/jni/org_apache_mesos_state_Variable.cpp \
- java/jni/org_apache_mesos_state_ZooKeeperState.cpp jvm/jvm.cpp
-
-libjava_la_SOURCES += java/jni/convert.hpp java/jni/construct.hpp jvm/jvm.hpp
+ java/jni/org_apache_mesos_state_ZooKeeperState.cpp \
+ jvm/jvm.cpp \
+ jvm/jvm.hpp \
+ jvm/java/io.hpp \
+ jvm/java/lang.hpp \
+ jvm/java/net.hpp \
+ jvm/org/apache/log4j.cpp \
+ jvm/org/apache/log4j.hpp \
+ jvm/org/apache/zookeeper.hpp
libjava_la_CPPFLAGS = $(MESOS_CPPFLAGS)
libjava_la_CPPFLAGS += $(JAVA_CPPFLAGS)
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/jvm/java/io.hpp
----------------------------------------------------------------------
diff --git a/src/jvm/java/io.hpp b/src/jvm/java/io.hpp
new file mode 100644
index 0000000..fa0c60c
--- /dev/null
+++ b/src/jvm/java/io.hpp
@@ -0,0 +1,36 @@
+#ifndef __JAVA_IO_HPP__
+#define __JAVA_IO_HPP__
+
+#include <jvm/jvm.hpp>
+
+namespace java {
+namespace io {
+
+class File : public Jvm::Object
+{
+public:
+ File(const std::string& pathname)
+ {
+ static Jvm::Constructor constructor = Jvm::get()->findConstructor(
+ Jvm::Class::named("java/io/File")
+ .constructor()
+ .parameter(Jvm::get()->stringClass));
+
+ object = Jvm::get()->invoke(constructor, Jvm::get()->string(pathname));
+ }
+
+ void deleteOnExit()
+ {
+ static Jvm::Method method = Jvm::get()->findMethod(
+ Jvm::Class::named("java/io/File")
+ .method("deleteOnExit")
+ .returns(Jvm::get()->voidClass));
+
+ Jvm::get()->invoke<void>(object, method);
+ }
+};
+
+} // namespace io {
+} // namespace java {
+
+#endif // __JAVA_IO_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/jvm/java/lang.hpp
----------------------------------------------------------------------
diff --git a/src/jvm/java/lang.hpp b/src/jvm/java/lang.hpp
new file mode 100644
index 0000000..5eb365d
--- /dev/null
+++ b/src/jvm/java/lang.hpp
@@ -0,0 +1,31 @@
+#ifndef __JAVA_LANG_HPP__
+#define __JAVA_LANG_HPP__
+
+#include <jvm/jvm.hpp>
+
+namespace java {
+namespace lang {
+
+class Throwable : public Jvm::Object
+{
+public:
+ Throwable(const std::string& message)
+ {
+ static Jvm::Constructor constructor = Jvm::get()->findConstructor(
+ Jvm::Class::named("java/lang/Throwable")
+ .constructor()
+ .parameter(Jvm::get()->stringClass));
+
+ object = Jvm::get()->invoke(constructor, Jvm::get()->string(message));
+ }
+
+private:
+ friend void Jvm::check(JNIEnv* env); // For constructing default instances.
+
+ Throwable() {}
+};
+
+} // namespace lang {
+} // namespace java {
+
+#endif // __JAVA_LANG_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/jvm/java/net.hpp
----------------------------------------------------------------------
diff --git a/src/jvm/java/net.hpp b/src/jvm/java/net.hpp
new file mode 100644
index 0000000..7816251
--- /dev/null
+++ b/src/jvm/java/net.hpp
@@ -0,0 +1,26 @@
+#ifndef __JAVA_NET_HPP__
+#define __JAVA_NET_HPP__
+
+#include <jvm/jvm.hpp>
+
+namespace java {
+namespace net {
+
+class InetSocketAddress : public Jvm::Object // TODO(benh): Extends SocketAddress.
+{
+public:
+ InetSocketAddress(int port)
+ {
+ static Jvm::Constructor constructor = Jvm::get()->findConstructor(
+ Jvm::Class::named("java/net/InetSocketAddress")
+ .constructor()
+ .parameter(Jvm::get()->intClass));
+
+ object = Jvm::get()->invoke(constructor, port);
+ }
+};
+
+} // namespace net {
+} // namespace java {
+
+#endif // __JAVA_NET_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/jvm/jvm.cpp
----------------------------------------------------------------------
diff --git a/src/jvm/jvm.cpp b/src/jvm/jvm.cpp
index a4fb791..d053f59 100644
--- a/src/jvm/jvm.cpp
+++ b/src/jvm/jvm.cpp
@@ -8,571 +8,714 @@
#include <sstream>
#include <vector>
-#include <stout/hashmap.hpp>
+#include <stout/exit.hpp>
#include <stout/foreach.hpp>
#include "jvm/jvm.hpp"
+#include "jvm/java/lang.hpp"
-namespace mesos {
-namespace internal {
-jmethodID Jvm::findMethod(const Jvm::JClass& clazz,
- const std::string& name,
- const Jvm::JClass& returnType,
- const std::vector<Jvm::JClass> argTypes,
- bool isStatic)
+// Static storage and initialization.
+Jvm* Jvm::instance = NULL;
+
+
+Try<Jvm*> Jvm::create(
+ const std::vector<std::string>& options,
+ JNI::Version version,
+ bool exceptions)
{
- std::ostringstream signature;
- signature << "(";
- std::vector<Jvm::JClass>::iterator args;
- foreach (Jvm::JClass type, argTypes) {
- signature << type.signature();
+ // TODO(benh): Make this thread-safe.
+ if (instance != NULL) {
+ return Error("Java Virtual Machine already created");
}
- signature << ")" << returnType.signature();
- LOG(INFO) << "looking up" << (isStatic ? " static " : " ") << "method "
- << name << signature.str();
-
- jmethodID id = NULL;
- if (isStatic) {
- id = env->GetStaticMethodID(findClass(clazz),
- name.c_str(),
- signature.str().c_str());
- } else {
- id = env->GetMethodID(findClass(clazz),
- name.c_str(),
- signature.str().c_str());
+ JavaVMInitArgs vmArgs;
+ vmArgs.version = version;
+ vmArgs.ignoreUnrecognized = false;
+
+ JavaVMOption* opts = new JavaVMOption[options.size()];
+ for (size_t i = 0; i < options.size(); i++) {
+ opts[i].optionString = const_cast<char*>(options[i].c_str());
}
+ vmArgs.nOptions = options.size();
+ vmArgs.options = opts;
- // TODO(John Sirois): consider CHECK -> return Option if re-purposing this
- // code outside of tests.
- CHECK(id != NULL);
- return id;
-}
+ JavaVM* jvm = NULL;
+ JNIEnv* env = NULL;
+ int result = JNI_CreateJavaVM(&jvm, JNIENV_CAST(&env), &vmArgs);
-Jvm::ConstructorFinder::ConstructorFinder(
- const Jvm::JClass& _type)
- : type(_type),
- parameters() {}
+ if (result == JNI_ERR) {
+ return Error("Failed to create JVM!");
+ }
+ delete[] opts;
-Jvm::ConstructorFinder&
-Jvm::ConstructorFinder::parameter(const Jvm::JClass& type)
-{
- parameters.push_back(type);
- return *this;
+ return instance = new Jvm(jvm, version, exceptions);
}
-Jvm::JConstructor Jvm::findConstructor(const ConstructorFinder& signature)
+bool Jvm::created()
{
- jmethodID id =
- findMethod(signature.type,
- "<init>",
- voidClass,
- signature.parameters,
- false);
- return Jvm::JConstructor(signature.type, id);
+ return instance != NULL;
}
-Jvm::JConstructor::JConstructor(const JConstructor& other) : clazz(other.clazz),
- id(other.id) {}
+Jvm* Jvm::get()
+{
+ if (instance == NULL) {
+ create();
+ }
+ return CHECK_NOTNULL(instance);
+}
-Jvm::JConstructor::JConstructor(const JClass& _clazz,
- const jmethodID _id) : clazz(_clazz),
- id(_id) {}
+Jvm::ConstructorFinder::ConstructorFinder(const Jvm::Class& _clazz)
+ : clazz(_clazz), parameters() {}
-jobject Jvm::invoke(const JConstructor& ctor, ...)
+Jvm::ConstructorFinder& Jvm::ConstructorFinder::parameter(
+ const Jvm::Class& clazz)
{
- va_list args;
- va_start(args, ctor);
- jobject result = env->NewObjectV(findClass(ctor.clazz), ctor.id, args);
- va_end(args);
- CHECK(result != NULL);
- return result;
+ parameters.push_back(clazz);
+ return *this;
}
+Jvm::Constructor::Constructor(const Constructor& that)
+ : clazz(that.clazz), id(that.id) {}
+
+
+Jvm::Constructor::Constructor(const Class& _clazz, const jmethodID _id)
+ : clazz(_clazz), id(_id) {}
+
+
Jvm::MethodFinder::MethodFinder(
- const Jvm::JClass& _clazz,
+ const Jvm::Class& _clazz,
const std::string& _name)
- : clazz(_clazz),
- name(_name),
- parameters() {}
+ : clazz(_clazz),
+ name(_name),
+ parameters() {}
-Jvm::MethodFinder& Jvm::MethodFinder::parameter(const JClass& type)
+Jvm::MethodFinder& Jvm::MethodFinder::parameter(const Class& type)
{
parameters.push_back(type);
return *this;
}
-Jvm::MethodSignature Jvm::MethodFinder::returns(const JClass& returnType) const
+Jvm::MethodSignature Jvm::MethodFinder::returns(const Class& returnType) const
{
return Jvm::MethodSignature(clazz, name, returnType, parameters);
}
-Jvm::JMethod Jvm::findMethod(const MethodSignature& signature)
-{
- jmethodID id = findMethod(signature.clazz,
- signature.name,
- signature.returnType,
- signature.parameters,
- false);
- return Jvm::JMethod(signature.clazz, id);
-}
-
-
-Jvm::JMethod Jvm::findStaticMethod(const MethodSignature& signature)
-{
- jmethodID id = findMethod(signature.clazz,
- signature.name,
- signature.returnType,
- signature.parameters,
- true);
- return Jvm::JMethod(signature.clazz, id);
-}
+Jvm::MethodSignature::MethodSignature(const MethodSignature& that)
+ : clazz(that.clazz),
+ name(that.name),
+ returnType(that.returnType),
+ parameters(that.parameters) {}
-Jvm::MethodSignature::MethodSignature(const MethodSignature& other) :
- clazz(other.clazz),
- name(other.name),
- returnType(other.returnType),
- parameters(other.parameters) {}
-
-
-Jvm::MethodSignature::MethodSignature(const JClass& _clazz,
- const std::string& _name,
- const JClass& _returnType,
- const std::vector<JClass>& _parameters) :
- clazz(_clazz),
+Jvm::MethodSignature::MethodSignature(
+ const Class& _clazz,
+ const std::string& _name,
+ const Class& _returnType,
+ const std::vector<Class>& _parameters)
+ : clazz(_clazz),
name(_name),
returnType(_returnType),
parameters(_parameters) {}
-Jvm::JMethod::JMethod(const JMethod& other)
- : clazz(other.clazz), id(other.id) {}
+Jvm::Method::Method(const Method& that)
+ : clazz(that.clazz), id(that.id) {}
-Jvm::JMethod::JMethod(const JClass& _clazz, const jmethodID _id)
+Jvm::Method::Method(const Class& _clazz, const jmethodID _id)
: clazz(_clazz), id(_id) {}
-template <>
-jobject Jvm::invokeV<jobject>(const jobject receiver,
- const jmethodID id,
- va_list args)
+const Jvm::Class Jvm::Class::named(const std::string& name)
{
- jobject result = env->CallObjectMethodV(receiver, id, args);
- CHECK(result != NULL);
- return result;
+ return Jvm::Class(name, false /* NOT a native type. */);
}
-template<>
-void Jvm::invokeV<void>(const jobject receiver,
- const jmethodID id,
- va_list args)
+Jvm::Class::Class(const Class& that)
+ : name(that.name), native(that.native) {}
+
+
+Jvm::Class::Class(const std::string& _name, bool _native)
+ : name(_name), native(_native) {}
+
+
+const Jvm::Class Jvm::Class::arrayOf() const
{
- env->CallVoidMethodV(receiver, id, args);
+ return Jvm::Class("[" + name, native);
}
-template <>
-bool Jvm::invokeV<bool>(const jobject receiver,
- const jmethodID id,
- va_list args)
+Jvm::ConstructorFinder Jvm::Class::constructor() const
{
- return env->CallBooleanMethodV(receiver, id, args);
+ return Jvm::ConstructorFinder(*this);
}
-template <>
-char Jvm::invokeV<char>(const jobject receiver,
- const jmethodID id,
- va_list args)
+Jvm::MethodFinder Jvm::Class::method(const std::string& name) const
{
- return env->CallCharMethodV(receiver, id, args);
+ return Jvm::MethodFinder(*this, name);
}
-template <>
-short Jvm::invokeV<short>(const jobject receiver,
- const jmethodID id,
- va_list args)
+std::string Jvm::Class::signature() const
{
- return env->CallShortMethodV(receiver, id, args);
+ return native ? name : "L" + name + ";";
}
-template <>
-int Jvm::invokeV<int>(const jobject receiver,
- const jmethodID id,
- va_list args)
+Jvm::Field::Field(const Field& that)
+ : clazz(that.clazz), id(that.id) {}
+
+
+Jvm::Field::Field(const Class& _clazz, const jfieldID _id)
+ : clazz(_clazz), id(_id) {}
+
+
+Jvm::Env::Env(bool daemon)
+ : env(NULL), detach(false)
{
- return env->CallIntMethodV(receiver, id, args);
-}
+ JavaVM* jvm = Jvm::get()->jvm;
+ // First check if we are already attached.
+ int result = jvm->GetEnv(JNIENV_CAST(&env), Jvm::get()->version);
-template <>
-long Jvm::invokeV<long>(const jobject receiver,
- const jmethodID id,
- va_list args)
+ // If we're not attached, attach now.
+ if (result == JNI_EDETACHED) {
+ if (daemon) {
+ jvm->AttachCurrentThreadAsDaemon(JNIENV_CAST(&env), NULL);
+ } else {
+ jvm->AttachCurrentThread(JNIENV_CAST(&env), NULL);
+ }
+ detach = true;
+ }
+}
+
+Jvm::Env::~Env()
{
- return env->CallLongMethodV(receiver, id, args);
+ if (detach) {
+ Jvm::get()->jvm->DetachCurrentThread();
+ }
}
-template <>
-float Jvm::invokeV<float>(const jobject receiver,
- const jmethodID id,
- va_list args)
+jstring Jvm::string(const std::string& s)
{
- return env->CallFloatMethodV(receiver, id, args);
+ Env env;
+ return env->NewStringUTF(s.c_str());
}
-template <>
-double Jvm::invokeV<double>(const jobject receiver,
- const jmethodID id,
- va_list args)
+Jvm::Constructor Jvm::findConstructor(const ConstructorFinder& finder)
{
- return env->CallDoubleMethodV(receiver, id, args);
+ jmethodID id = findMethod(
+ finder.clazz,
+ "<init>",
+ voidClass,
+ finder.parameters,
+ false);
+
+ return Jvm::Constructor(finder.clazz, id);
}
-template <>
-void Jvm::invoke<void>(const jobject receiver, const JMethod& method, ...)
+Jvm::Method Jvm::findMethod(const MethodSignature& signature)
{
- va_list args;
- va_start(args, method);
- invokeV<void>(receiver, method.id, args);
- va_end(args);
+ jmethodID id = findMethod(
+ signature.clazz,
+ signature.name,
+ signature.returnType,
+ signature.parameters,
+ false);
+
+ return Jvm::Method(signature.clazz, id);
}
-template <>
-jobject Jvm::invokeStaticV<jobject>(const JClass& receiver,
- const jmethodID id,
- va_list args)
+Jvm::Method Jvm::findStaticMethod(const MethodSignature& signature)
{
- jobject result = env->CallStaticObjectMethodV(findClass(receiver), id, args);
- CHECK(result != NULL);
- return result;
+ jmethodID id = findMethod(
+ signature.clazz,
+ signature.name,
+ signature.returnType,
+ signature.parameters,
+ true);
+
+ return Jvm::Method(signature.clazz, id);
}
-template<>
-void Jvm::invokeStaticV<void>(const JClass& receiver,
- const jmethodID id,
- va_list args)
+Jvm::Field Jvm::findStaticField(const Class& clazz, const std::string& name)
{
- env->CallStaticVoidMethodV(findClass(receiver), id, args);
+ Env env;
+
+ jfieldID id = env->GetStaticFieldID(
+ findClass(clazz),
+ name.c_str(),
+ clazz.signature().c_str());
+
+ check(env);
+
+ return Jvm::Field(clazz, id);
}
-template <>
-bool Jvm::invokeStaticV<bool>(const JClass& receiver,
- const jmethodID id,
- va_list args)
+jobject Jvm::invoke(const Constructor& ctor, ...)
{
- return env->CallStaticBooleanMethodV(findClass(receiver), id, args);
+ Env env;
+ va_list args;
+ va_start(args, ctor);
+ jobject o = env->NewObjectV(findClass(ctor.clazz), ctor.id, args);
+ va_end(args);
+ check(env);
+ return o;
}
template <>
-char Jvm::invokeStaticV<char>(const JClass& receiver,
- const jmethodID id,
- va_list args)
+jobject Jvm::getStaticField<jobject>(const Field& field)
{
- return env->CallStaticCharMethodV(findClass(receiver), id, args);
+ Env env;
+ jobject o = env->GetStaticObjectField(findClass(field.clazz), field.id);
+ check(env);
+ return o;
}
template <>
-short Jvm::invokeStaticV<short>(const JClass& receiver,
- const jmethodID id,
- va_list args)
+bool Jvm::getStaticField<bool>(const Field& field)
{
- return env->CallStaticShortMethodV(findClass(receiver), id, args);
+ Env env;
+ bool b = env->GetStaticBooleanField(findClass(field.clazz), field.id);
+ check(env);
+ return b;
}
template <>
-int Jvm::invokeStaticV<int>(const JClass& receiver,
- const jmethodID id,
- va_list args)
+char Jvm::getStaticField<char>(const Field& field)
{
- return env->CallStaticIntMethodV(findClass(receiver), id, args);
+ Env env;
+ char c = env->GetStaticCharField(findClass(field.clazz), field.id);
+ check(env);
+ return c;
}
template <>
-long Jvm::invokeStaticV<long>(const JClass& receiver,
- const jmethodID id,
- va_list args)
+short Jvm::getStaticField<short>(const Field& field)
{
- return env->CallStaticLongMethodV(findClass(receiver), id, args);
+ Env env;
+ short s = env->GetStaticShortField(findClass(field.clazz), field.id);
+ check(env);
+ return s;
}
template <>
-float Jvm::invokeStaticV<float>(const JClass& receiver,
- const jmethodID id,
- va_list args)
+int Jvm::getStaticField<int>(const Field& field)
{
- return env->CallStaticFloatMethodV(findClass(receiver), id, args);
+ Env env;
+ int i = env->GetStaticIntField(findClass(field.clazz), field.id);
+ check(env);
+ return i;
}
template <>
-double Jvm::invokeStaticV<double>(const JClass& receiver,
- const jmethodID id,
- va_list args)
+long Jvm::getStaticField<long>(const Field& field)
{
- return env->CallStaticDoubleMethodV(findClass(receiver), id, args);
+ Env env;
+ long l = env->GetStaticLongField(findClass(field.clazz), field.id);
+ check(env);
+ return l;
}
template <>
-void Jvm::invokeStatic<void>(const JMethod& method, ...)
+float Jvm::getStaticField<float>(const Field& field)
{
- va_list args;
- va_start(args, method);
- invokeStaticV<void>(method.clazz, method.id, args);
- va_end(args);
+ Env env;
+ float f = env->GetStaticFloatField(findClass(field.clazz), field.id);
+ check(env);
+ return f;
}
-const Jvm::JClass Jvm::JClass::forName(const std::string& nativeName)
+template <>
+double Jvm::getStaticField<double>(const Field& field)
{
- return Jvm::JClass(nativeName, false /* not a native type */);
+ Env env;
+ double d = env->GetStaticDoubleField(findClass(field.clazz), field.id);
+ check(env);
+ return d;
}
-Jvm::JClass::JClass(const JClass& other) : nativeName(other.nativeName),
- isNative(other.isNative) {}
-
-
-Jvm::JClass::JClass(const std::string& _nativeName,
- bool _isNative) : nativeName(_nativeName),
- isNative(_isNative) {}
+Jvm::Jvm(JavaVM* _jvm, JNI::Version _version, bool _exceptions)
+ : voidClass("V"),
+ booleanClass("Z"),
+ byteClass("B"),
+ charClass("C"),
+ shortClass("S"),
+ intClass("I"),
+ longClass("J"),
+ floatClass("F"),
+ doubleClass("D"),
+ stringClass(Class::named("java/lang/String")),
+ jvm(_jvm),
+ version(_version),
+ exceptions(_exceptions) {}
-const Jvm::JClass Jvm::JClass::arrayOf() const
+Jvm::~Jvm()
{
- return Jvm::JClass("[" + nativeName, isNative);
+ LOG(FATAL) << "Destroying the JVM is not supported";
}
-Jvm::ConstructorFinder Jvm::JClass::constructor() const
+jobject Jvm::newGlobalRef(const jobject object)
{
- return Jvm::ConstructorFinder(*this);
+ Env env;
+ return env->NewGlobalRef(object);
}
-Jvm::MethodFinder Jvm::JClass::method(const std::string& name) const
+void Jvm::deleteGlobalRef(const jobject object)
{
- return Jvm::MethodFinder(*this, name);
+ Env env;
+ if (object != NULL) {
+ env->DeleteGlobalRef(object);
+ }
}
-std::string Jvm::JClass::signature() const
+jclass Jvm::findClass(const Class& clazz)
{
- return isNative ? nativeName : "L" + nativeName + ";";
+ Env env;
+
+ // TODO(John Sirois): Consider CHECK_NOTNULL -> return Option if
+ // re-purposing this code outside of tests.
+ return CHECK_NOTNULL(env->FindClass(clazz.name.c_str()));
}
-Jvm::JField::JField(const JField& other) : clazz(other.clazz), id(other.id) {}
+jmethodID Jvm::findMethod(
+ const Jvm::Class& clazz,
+ const std::string& name,
+ const Jvm::Class& returnType,
+ const std::vector<Jvm::Class>& argTypes,
+ bool isStatic)
+{
+ Env env;
+ std::ostringstream signature;
+ signature << "(";
+ std::vector<Jvm::Class>::iterator args;
+ foreach (const Jvm::Class& type, argTypes) {
+ signature << type.signature();
+ }
+ signature << ")" << returnType.signature();
-Jvm::JField::JField(const JClass& _clazz, const jfieldID _id)
- : clazz(_clazz), id(_id) {}
+ LOG(INFO) << "Looking up" << (isStatic ? " static " : " ")
+ << "method " << name << signature.str();
+ jmethodID id = isStatic
+ ? env->GetStaticMethodID(
+ findClass(clazz),
+ name.c_str(),
+ signature.str().c_str())
+ : env->GetMethodID(
+ findClass(clazz),
+ name.c_str(),
+ signature.str().c_str());
-Jvm::JField Jvm::findStaticField(const JClass& clazz, const std::string& name)
-{
- jfieldID id =
- env->GetStaticFieldID(findClass(clazz),
- name.c_str(),
- clazz.signature().c_str());
- return Jvm::JField(clazz, id);
+ // TODO(John Sirois): Consider CHECK_NOTNULL -> return Option if
+ // re-purposing this code outside of tests.
+ return CHECK_NOTNULL(id);
}
-template <>
-jobject Jvm::getStaticField<jobject>(const JField& field)
+template<>
+void Jvm::invokeV<void>(
+ const jobject receiver,
+ const jmethodID id,
+ va_list args)
{
- jobject result = env->GetStaticObjectField(findClass(field.clazz), field.id);
- CHECK(result != NULL);
- return result;
+ Env env;
+ env->CallVoidMethodV(receiver, id, args);
+ check(env);
}
template <>
-bool Jvm::getStaticField<bool>(const JField& field)
+jobject Jvm::invokeV<jobject>(
+ const jobject receiver,
+ const jmethodID id,
+ va_list args)
{
- return env->GetStaticBooleanField(findClass(field.clazz), field.id);
+ Env env;
+ jobject o = env->CallObjectMethodV(receiver, id, args);
+ check(env);
+ return o;
}
template <>
-char Jvm::getStaticField<char>(const JField& field)
+bool Jvm::invokeV<bool>(
+ const jobject receiver,
+ const jmethodID id,
+ va_list args)
{
- return env->GetStaticCharField(findClass(field.clazz), field.id);
+ Env env;
+ bool b = env->CallBooleanMethodV(receiver, id, args);
+ check(env);
+ return b;
}
template <>
-short Jvm::getStaticField<short>(const JField& field)
+char Jvm::invokeV<char>(
+ const jobject receiver,
+ const jmethodID id,
+ va_list args)
{
- return env->GetStaticShortField(findClass(field.clazz), field.id);
+ Env env;
+ char c = env->CallCharMethodV(receiver, id, args);
+ check(env);
+ return c;
}
template <>
-int Jvm::getStaticField<int>(const JField& field)
+short Jvm::invokeV<short>(
+ const jobject receiver,
+ const jmethodID id,
+ va_list args)
{
- return env->GetStaticIntField(findClass(field.clazz), field.id);
+ Env env;
+ short s = env->CallShortMethodV(receiver, id, args);
+ check(env);
+ return s;
}
template <>
-long Jvm::getStaticField<long>(const JField& field)
+int Jvm::invokeV<int>(
+ const jobject receiver,
+ const jmethodID id,
+ va_list args)
{
- return env->GetStaticLongField(findClass(field.clazz), field.id);
+ Env env;
+ int i = env->CallIntMethodV(receiver, id, args);
+ check(env);
+ return i;
}
template <>
-float Jvm::getStaticField<float>(const JField& field)
+long Jvm::invokeV<long>(
+ const jobject receiver,
+ const jmethodID id,
+ va_list args)
{
- return env->GetStaticFloatField(findClass(field.clazz), field.id);
+ Env env;
+ long l = env->CallLongMethodV(receiver, id, args);
+ check(env);
+ return l;
}
template <>
-double Jvm::getStaticField<double>(const JField& field)
+float Jvm::invokeV<float>(
+ const jobject receiver,
+ const jmethodID id,
+ va_list args)
{
- return env->GetStaticDoubleField(findClass(field.clazz), field.id);
+ Env env;
+ float f = env->CallFloatMethodV(receiver, id, args);
+ check(env);
+ return f;
}
-Jvm::Jvm(const std::vector<std::string>& options, JNIVersion jniVersion)
- : voidClass("V"),
- booleanClass("Z"),
- byteClass("B"),
- charClass("C"),
- shortClass("S"),
- intClass("I"),
- longClass("J"),
- floatClass("F"),
- doubleClass("D"),
- stringClass(JClass::forName("java/lang/String")),
- jvm(NULL),
- env(NULL)
+template <>
+double Jvm::invokeV<double>(
+ const jobject receiver,
+ const jmethodID id,
+ va_list args)
{
- JavaVMInitArgs vmArgs;
- vmArgs.version = jniVersion;
- vmArgs.ignoreUnrecognized = false;
-
- JavaVMOption* opts = new JavaVMOption[options.size()];
- for (size_t i = 0; i < options.size(); i++) {
- opts[i].optionString = const_cast<char*>(options[i].c_str());
- }
- vmArgs.nOptions = options.size();
- vmArgs.options = opts;
-
- int result = JNI_CreateJavaVM(&jvm, JNIENV_CAST(&env), &vmArgs);
- CHECK(result != JNI_ERR) << "Failed to create JVM!";
-
- delete[] opts;
+ Env env;
+ double d = env->CallDoubleMethodV(receiver, id, args);
+ check(env);
+ return d;
}
-Jvm::~Jvm()
+template<>
+void Jvm::invokeStaticV<void>(
+ const Class& receiver,
+ const jmethodID id,
+ va_list args)
{
- CHECK(0 == jvm->DestroyJavaVM()) << "Failed to destroy JVM";
+ Env env;
+ env->CallStaticVoidMethodV(findClass(receiver), id, args);
+ check(env);
}
-void Jvm::attachDaemon()
+template <>
+jobject Jvm::invokeStaticV<jobject>(
+ const Class& receiver,
+ const jmethodID id,
+ va_list args)
{
- jvm->AttachCurrentThreadAsDaemon(JNIENV_CAST(&env), NULL);
+ Env env;
+ jobject o = env->CallStaticObjectMethodV(findClass(receiver), id, args);
+ check(env);
+ return o;
}
-void Jvm::attach()
+template <>
+bool Jvm::invokeStaticV<bool>(
+ const Class& receiver,
+ const jmethodID id,
+ va_list args)
{
- jvm->AttachCurrentThread(JNIENV_CAST(&env), NULL);
+ Env env;
+ bool b = env->CallStaticBooleanMethodV(findClass(receiver), id, args);
+ check(env);
+ return b;
}
-void Jvm::detach()
+template <>
+char Jvm::invokeStaticV<char>(
+ const Class& receiver,
+ const jmethodID id,
+ va_list args)
{
- jvm->DetachCurrentThread();
+ Env env;
+ char c = env->CallStaticCharMethodV(findClass(receiver), id, args);
+ check(env);
+ return c;
}
-jclass Jvm::findClass(const JClass& clazz)
+template <>
+short Jvm::invokeStaticV<short>(
+ const Class& receiver,
+ const jmethodID id,
+ va_list args)
{
- jclass cls = env->FindClass(clazz.nativeName.c_str());
- // TODO(John Sirois): consider CHECK -> return Option if re-purposing this
- // code outside of tests.
- CHECK(cls != NULL);
- return cls;
+ Env env;
+ short s = env->CallStaticShortMethodV(findClass(receiver), id, args);
+ check(env);
+ return s;
}
-jobject Jvm::string(const std::string& str)
+template <>
+int Jvm::invokeStaticV<int>(
+ const Class& receiver,
+ const jmethodID id,
+ va_list args)
{
- return env->NewStringUTF(str.c_str());
+ Env env;
+ int i = env->CallStaticIntMethodV(findClass(receiver), id, args);
+ check(env);
+ return i;
}
-jobject Jvm::newGlobalRef(const jobject object)
+template <>
+long Jvm::invokeStaticV<long>(
+ const Class& receiver,
+ const jmethodID id,
+ va_list args)
{
- return env->NewGlobalRef(object);
+ Env env;
+ long l = env->CallStaticLongMethodV(findClass(receiver), id, args);
+ check(env);
+ return l;
}
-void Jvm::deleteGlobalRef(const jobject object)
+template <>
+float Jvm::invokeStaticV<float>(
+ const Class& receiver,
+ const jmethodID id,
+ va_list args)
{
- env->DeleteGlobalRef(object);
+ Env env;
+ float f = env->CallStaticFloatMethodV(findClass(receiver), id, args);
+ check(env);
+ return f;
}
-void Jvm::deleteGlobalRefSafe(const jobject object)
-{
- if (object != NULL) {
- deleteGlobalRef(object);
+template <>
+double Jvm::invokeStaticV<double>(
+ const Class& receiver,
+ const jmethodID id,
+ va_list args)
+{
+ Env env;
+ double d = env->CallStaticDoubleMethodV(findClass(receiver), id, args);
+ check(env);
+ return d;
+}
+
+
+void Jvm::check(JNIEnv* env)
+{
+ if (env->ExceptionCheck() == JNI_TRUE) {
+ if (!exceptions) {
+ env->ExceptionDescribe();
+ EXIT(1) << "Caught a JVM exception, not propagating";
+ } else {
+ java::lang::Throwable throwable;
+ Object* object = &throwable;
+ object->object = env->ExceptionOccurred();
+ env->ExceptionClear();
+ throw throwable;
+ }
}
}
-Jvm::Attach::Attach(Jvm* jvm, bool daemon) : _jvm(jvm)
+
+// N.B. Both Jvm::invoke<void> and Jvm::invokeStatic<void> template
+// instantiations need to be defined AFTER template instantions that
+// they use (i.e., Jvm::invokeV<void>, Jvm::invokeStaticV<void>).
+
+template <>
+void Jvm::invoke<void>(const jobject receiver, const Method& method, ...)
{
- if (daemon) {
- _jvm->attachDaemon();
- } else {
- _jvm->attach();
- }
+ va_list args;
+ va_start(args, method);
+ invokeV<void>(receiver, method.id, args);
+ va_end(args);
}
-Jvm::Attach::~Attach()
+template <>
+void Jvm::invokeStatic<void>(const Method& method, ...)
{
- // TODO(John Sirois): this detaches too early under nested use, attach by a
- // given thread should incr, this should decr and only detach on 0
- _jvm->detach();
+ va_list args;
+ va_start(args, method);
+ invokeStaticV<void>(method.clazz, method.id, args);
+ va_end(args);
}
-
-} // namespace internal
-} // namespace mesos
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/jvm/jvm.hpp
----------------------------------------------------------------------
diff --git a/src/jvm/jvm.hpp b/src/jvm/jvm.hpp
index 6a31bd8..a3ea86a 100644
--- a/src/jvm/jvm.hpp
+++ b/src/jvm/jvm.hpp
@@ -3,10 +3,13 @@
#include <jni.h>
-#include <glog/logging.h>
-
+#include <string>
#include <vector>
+#include <stout/error.hpp>
+#include <stout/try.hpp>
+
+
// Some compilers give us warnings about 'dereferencing type-punned
// pointer will break strict-aliasing rules' when we cast our JNIEnv**
// to void**. We use this function to do the magic for us.
@@ -16,118 +19,149 @@ inline void** JNIENV_CAST(JNIEnv** env)
}
-namespace mesos {
-namespace internal {
+struct JNI
+{
+ enum Version
+ {
+ v_1_1 = JNI_VERSION_1_1,
+ v_1_2 = JNI_VERSION_1_2,
+ v_1_4 = JNI_VERSION_1_4,
+ v_1_6 = JNI_VERSION_1_6
+ };
+};
-// Facilitates embedding a jvm and calling into it.
-//
-// TODO(John Sirois): Fix variadic methods. Possibly a way to do this with
-// typelists, type concatenation and unwinding builder inheritance.
-//
-// TODO(John Sirois): Support finding static methods.
+// Facilitates embedding a JVM and calling into it.
class Jvm
{
public:
// Forward declarations.
class ConstructorFinder;
class MethodFinder;
- class JConstructor;
+ class Constructor;
class MethodSignature;
- class JMethod;
-
- // An opaque class descriptor that can be used to find constructors, methods
- // and fields.
- class JClass
+ class Method;
+
+ // Starts a new embedded JVM with the given -D options. Each option
+ // supplied should be of the standard form: '-Dproperty=value'.
+ // Returns the singleton Jvm instance or an error if the JVM had
+ // already been created. Note that you can only create one JVM
+ // instance per process since destructing a JVM has issues, see:
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4712793. In
+ // addition, most JVM's use signals and couldn't possibly play
+ // nicely with one another.
+ // TODO(benh): Add a 'create' which just takes an already
+ // constructed JavaVM. This will be useful for when a JVM is calling
+ // into native code versus native code embedding a JVM.
+ // TODO(John Sirois): Consider elevating classpath as a top-level
+ // JVM configuration parameter since it will likely always need to
+ // be specified. Ditto for and non '-X' options.
+ static Try<Jvm*> create(
+ const std::vector<std::string>& options = std::vector<std::string>(),
+ JNI::Version version = JNI::v_1_6,
+ bool exceptions = false);
+
+ // Returns true if the JVM has already been created.
+ static bool created();
+
+ // Returns the singleton JVM instance, creating it with no options
+ // and a default version if necessary.
+ static Jvm* get();
+
+ // An opaque class descriptor that can be used to find constructors,
+ // methods and fields.
+ class Class
{
public:
- // A factory for new java reference type class descriptors given the native
- // name. To obtain class descriptors for native types, use the fields in
- // Jvm.
- static const JClass forName(const std::string& nativeName);
+ // A factory for new Java reference type class descriptors given
+ // the fully-qualified class name (e.g., 'java/io/File'). To
+ // obtain class descriptors for native types (int, short, etc),
+ // use the fields in Jvm.
+ static const Class named(const std::string& name);
- JClass(const JClass& other);
+ Class(const Class& that);
// Returns the class of an array of the current class.
- const JClass arrayOf() const;
+ const Class arrayOf() const;
- // Creates a builder that can be used to locate a constructor of this
- // class with Jvm::findConstructor.
+ // Creates a builder that can be used to locate a constructor of
+ // this class with Jvm::findConstructor.
ConstructorFinder constructor() const;
- // Creates a builder that can be used to locate an instance method of this
- // class with Jvm::findMethod.
+ // Creates a builder that can be used to locate an instance method
+ // of this class with Jvm::findMethod.
MethodFinder method(const std::string& name) const;
private:
friend class Jvm;
- JClass(const std::string& nativeName,
- bool isNative = true);
+ Class(const std::string& name, bool native = true);
std::string signature() const;
- std::string nativeName;
- bool isNative;
+ std::string name;
+ bool native;
};
- // A builder that is used to specify a constructor by specifying its parameter
- // list with zero or more calls to ConstructorFinder::parameter.
+ // A builder that is used to specify a constructor by specifying its
+ // parameter list with zero or more calls to
+ // ConstructorFinder::parameter.
class ConstructorFinder
{
public:
// Adds a parameter to the constructor parameter list.
- ConstructorFinder& parameter(const JClass& type);
+ ConstructorFinder& parameter(const Class& clazz);
private:
- friend class JClass;
+ friend class Class;
friend class Jvm;
- ConstructorFinder(const JClass& type);
+ ConstructorFinder(const Class& clazz);
- const JClass type;
- std::vector<JClass> parameters;
+ const Class clazz;
+ std::vector<Class> parameters;
};
- // An opaque constructor descriptor that can be used to create new instances
- // of a class using Jvm::invokeConstructor.
- class JConstructor
+ // An opaque constructor descriptor that can be used to create new
+ // instances of a class using Jvm::invokeConstructor.
+ class Constructor
{
public:
- JConstructor(const JConstructor& other);
+ Constructor(const Constructor& that);
private:
friend class Jvm;
- JConstructor(const JClass& clazz, const jmethodID id);
+ Constructor(const Class& clazz, const jmethodID id);
- const JClass clazz;
+ const Class clazz;
const jmethodID id;
};
- // A builder that is used to specify an instance method by specifying its
- // parameter list with zero or more calls to MethodFinder::parameter and a
- // final call to MethodFinder::returns to get an opaque specification of the
- // method for use with Jvm::findMethod.
+ // A builder that is used to specify an instance method by
+ // specifying its parameter list with zero or more calls to
+ // MethodFinder::parameter and a final call to MethodFinder::returns
+ // to get an opaque specification of the method for use with
+ // Jvm::findMethod.
class MethodFinder
{
public:
// Adds a parameter to the method parameter list.
- MethodFinder& parameter(const JClass& type);
+ MethodFinder& parameter(const Class& type);
// Terminates description of a method by specifying its return type.
- MethodSignature returns(const JClass& type) const;
+ MethodSignature returns(const Class& type) const;
private:
- friend class JClass;
+ friend class Class;
- MethodFinder(const JClass& clazz, const std::string& name);
+ MethodFinder(const Class& clazz, const std::string& name);
- const JClass clazz;
+ const Class clazz;
const std::string name;
- std::vector<JClass> parameters;
+ std::vector<Class> parameters;
};
@@ -135,153 +169,237 @@ public:
class MethodSignature
{
public:
- MethodSignature(const MethodSignature& other);
+ MethodSignature(const MethodSignature& that);
private:
friend class Jvm;
friend class MethodFinder;
- MethodSignature(const JClass& clazz,
+ MethodSignature(const Class& clazz,
const std::string& name,
- const JClass& returnType,
- const std::vector<JClass>& parameters);
+ const Class& returnType,
+ const std::vector<Class>& parameters);
- const JClass clazz;
+ const Class clazz;
const std::string name;
- const JClass returnType;
- std::vector<JClass> parameters;
+ const Class returnType;
+ std::vector<Class> parameters;
};
// An opaque method descriptor that can be used to invoke instance methods
// using Jvm::invokeMethod.
- class JMethod
+ class Method
{
public:
- JMethod(const JMethod& other);
+ Method(const Method& that);
private:
friend class Jvm;
friend class MethodSignature;
- JMethod(const JClass& clazz, const jmethodID id);
+ Method(const Class& clazz, const jmethodID id);
- const JClass clazz;
+ const Class clazz;
const jmethodID id;
};
// An opaque field descriptor that can be used to access fields using
// methods like Jvm::getStaticField.
- class JField
+ class Field
{
public:
- JField(const JField& other);
+ Field(const Field& that);
private:
friend class Jvm;
- JField(const JClass& clazz, const jfieldID id);
+ Field(const Class& clazz, const jfieldID id);
- const JClass clazz;
+ const Class clazz;
const jfieldID id;
};
- // RAII container for c++/jvm thread binding management.
- class Attach
+ // Base class for all JVM objects. This object "stores" the
+ // underlying global reference and performs the appropriate
+ // operations across copies and assignments.
+ class Object
{
public:
- Attach(Jvm* jvm, bool daemon = true);
- ~Attach();
+ Object() : object(NULL) {}
+
+ Object(jobject _object)
+ : object(Jvm::get()->newGlobalRef(_object)) {}
+
+ Object(const Object& that)
+ {
+ object = Jvm::get()->newGlobalRef(that.object);
+ }
+
+ ~Object()
+ {
+ if (object != NULL) {
+ Jvm::get()->deleteGlobalRef(object);
+ }
+ }
+
+ Object& operator = (const Object& that)
+ {
+ if (object != NULL) {
+ Jvm::get()->deleteGlobalRef(object);
+ }
+ object = Jvm::get()->newGlobalRef(that.object);
+ return *this;
+ }
+
+ operator jobject () const
+ {
+ return object;
+ }
+
+ protected:
+ friend class Jvm; // For manipulating object.
+
+ jobject object;
+ };
+
+ // Helper for providing access to static variables in a class. You
+ // can use this to delay the variable lookup until it's actually
+ // accessed in order to keep the JVM from getting constructed too
+ // early. See Level in jvm/org/apache/log4j.hpp for an example.
+ // TODO(benh): Make this work for instance variables too (i.e.,
+ // StaticVariable -> Variable).
+ // TODO(benh): Provide template specialization for primitive
+ // types (e.g., StaticVariable<int>, StaticVariable<short>,
+ // StaticVariable<std::string>).
+ template <typename T, const char* name>
+ class StaticVariable
+ {
+ public:
+ StaticVariable(const Class& _clazz)
+ : clazz(_clazz)
+ {
+ // Check that T extends Object.
+ { T* t = NULL; Object* o = t; (void) o; }
+ }
+
+ operator T () const
+ {
+ // Note that we actually look up the field lazily (upon first
+ // invocation operator) so that we don't possibly create the JVM
+ // too early.
+ static Field field = Jvm::get()->findStaticField(clazz, name);
+ T t;
+ t.object = Jvm::get()->getStaticField<jobject>(field);
+ return t;
+ }
private:
- Jvm* _jvm;
+ const Class clazz;
};
- friend class Attach;
-
- enum JNIVersion
+ // Each thread that wants to interact with the JVM needs a JNI
+ // environment which must be obtained by "attaching" to the JVM. We
+ // use the following RAII class to provide the environment and also
+ // make sure a thread is attached and properly detached. Note that
+ // nested constructions are no-ops and use the same environment (and
+ // without detaching too early).
+ // TODO(benh): Support putting a 'Jvm::Env' into a thread-local
+ // variable so we can "attach" to the JVM once.
+ class Env
{
- v_1_1 = JNI_VERSION_1_1,
- v_1_2 = JNI_VERSION_1_2,
- v_1_4 = JNI_VERSION_1_4,
- v_1_6 = JNI_VERSION_1_6
+ public:
+ Env(bool daemon = true);
+ ~Env();
+
+ JNIEnv* operator -> () const { return env; }
+
+ operator JNIEnv* () const { return env; }
+
+ private:
+ JNIEnv* env;
+ bool detach; // A nested use of Env should not detach the thread.
};
- // Starts a new embedded jvm with the given -D options. Each option supplied
- // should be of the standard form: '-Dproperty=value'.
- //
- // TODO(John Sirois): Consider elevating classpath as a top level jvm
- // configuration parameter since it will likely always need to be specified.
- // Ditto for and non -X java option.
- Jvm(const std::vector<std::string>& options,
- JNIVersion jniVersion = Jvm::v_1_6);
- ~Jvm();
+ friend class Env;
- const JClass voidClass;
- const JClass booleanClass;
- const JClass byteClass;
- const JClass charClass;
- const JClass shortClass;
- const JClass intClass;
- const JClass longClass;
- const JClass floatClass;
- const JClass doubleClass;
- const JClass stringClass;
+ const Class voidClass;
+ const Class booleanClass;
+ const Class byteClass;
+ const Class charClass;
+ const Class shortClass;
+ const Class intClass;
+ const Class longClass;
+ const Class floatClass;
+ const Class doubleClass;
+ const Class stringClass;
- jobject string(const std::string& str);
+ jstring string(const std::string& s);
- JConstructor findConstructor(const ConstructorFinder& constructor);
- JMethod findMethod(const MethodSignature& signature);
- JMethod findStaticMethod(const MethodSignature& signature);
- JField findStaticField(const JClass& clazz, const std::string& name);
+ Constructor findConstructor(const ConstructorFinder& finder);
+ Method findMethod(const MethodSignature& signature);
+ Method findStaticMethod(const MethodSignature& signature);
+ Field findStaticField(const Class& clazz, const std::string& name);
- jobject invoke(const JConstructor& ctor, ...);
+ // TODO(John Sirois): Add "type checking" to variadic method
+ // calls. Possibly a way to do this with typelists, type
+ // concatenation and unwinding builder inheritance.
+
+ jobject invoke(const Constructor& ctor, ...);
template <typename T>
- T invoke(const jobject receiver, const JMethod& method, ...);
+ T invoke(const jobject receiver, const Method& method, ...);
template <typename T>
- T invokeStatic(const JMethod& method, ...);
+ T invokeStatic(const Method& method, ...);
template <typename T>
- T getStaticField(const JField& field);
+ T getStaticField(const Field& field);
+
+ // Checks the exception state of an environment.
+ void check(JNIEnv* env);
+private:
+ friend class Object; // For creating global references.
+
+ Jvm(JavaVM* jvm, JNI::Version version, bool exceptions);
+ ~Jvm();
+
+private:
jobject newGlobalRef(const jobject object);
void deleteGlobalRef(const jobject object);
- void deleteGlobalRefSafe(const jobject object);
-private:
- jclass findClass(const JClass& clazz);
+ jclass findClass(const Class& clazz);
- jmethodID findMethod(const Jvm::JClass& clazz,
+ jmethodID findMethod(const Jvm::Class& clazz,
const std::string& name,
- const Jvm::JClass& returnType,
- const std::vector<Jvm::JClass> argTypes,
+ const Jvm::Class& returnType,
+ const std::vector<Jvm::Class>& argTypes,
bool isStatic);
template <typename T>
T invokeV(const jobject receiver, const jmethodID id, va_list args);
template <typename T>
- T invokeStaticV(const JClass& receiver, const jmethodID id, va_list args);
+ T invokeStaticV(const Class& receiver, const jmethodID id, va_list args);
- void attachDaemon();
- void attach();
- void detach();
+ // Singleton instance.
+ static Jvm* instance;
JavaVM* jvm;
- JNIEnv* env;
+ const JNI::Version version;
+ const bool exceptions;
};
template <>
-void Jvm::invoke<void>(const jobject receiver, const JMethod& method, ...);
+void Jvm::invoke<void>(const jobject receiver, const Method& method, ...);
template <typename T>
-T Jvm::invoke(const jobject receiver, const JMethod& method, ...)
+T Jvm::invoke(const jobject receiver, const Method& method, ...)
{
va_list args;
va_start(args, method);
@@ -292,11 +410,11 @@ T Jvm::invoke(const jobject receiver, const JMethod& method, ...)
template <>
-void Jvm::invokeStatic<void>(const JMethod& method, ...);
+void Jvm::invokeStatic<void>(const Method& method, ...);
template <typename T>
-T Jvm::invokeStatic(const JMethod& method, ...)
+T Jvm::invokeStatic(const Method& method, ...)
{
va_list args;
va_start(args, method);
@@ -305,7 +423,4 @@ T Jvm::invokeStatic(const JMethod& method, ...)
return result;
}
-} // namespace internal
-} // namespace mesos
-
#endif // __JVM_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/jvm/org/apache/log4j.cpp
----------------------------------------------------------------------
diff --git a/src/jvm/org/apache/log4j.cpp b/src/jvm/org/apache/log4j.cpp
new file mode 100644
index 0000000..b73df8c
--- /dev/null
+++ b/src/jvm/org/apache/log4j.cpp
@@ -0,0 +1,16 @@
+#include <jvm/org/apache/log4j.hpp>
+
+namespace org {
+namespace apache {
+namespace log4j {
+
+// Static storage and initialization.
+const char LEVEL_OFF[] = "OFF";
+
+Jvm::StaticVariable<Level, LEVEL_OFF> Level::OFF =
+ Jvm::StaticVariable<Level, LEVEL_OFF>(
+ Jvm::Class::named("org/apache/log4j/Level"));
+
+} // namespace log4j {
+} // namespace apache {
+} // namespace org {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/jvm/org/apache/log4j.hpp
----------------------------------------------------------------------
diff --git a/src/jvm/org/apache/log4j.hpp b/src/jvm/org/apache/log4j.hpp
new file mode 100644
index 0000000..6b5ba4b
--- /dev/null
+++ b/src/jvm/org/apache/log4j.hpp
@@ -0,0 +1,69 @@
+#ifndef __ORG_APACHE_LOG4J_HPP__
+#define __ORG_APACHE_LOG4J_HPP__
+
+#include <jvm/jvm.hpp>
+
+namespace org {
+namespace apache {
+namespace log4j {
+
+// Forward declaration.
+extern const char LEVEL_OFF[];
+
+
+class Level : public Jvm::Object // TODO(benh): Extends Priority.
+{
+public:
+ friend class Jvm::StaticVariable<Level, LEVEL_OFF>;
+
+ static Jvm::StaticVariable<Level, LEVEL_OFF> OFF;
+
+ Level() {} // No default constuctors.
+};
+
+
+class Category : public Jvm::Object
+{
+public:
+ void setLevel(const Level& level)
+ {
+ static Jvm::Method method = Jvm::get()->findMethod(
+ Jvm::Class::named("org/apache/log4j/Category")
+ .method("setLevel")
+ .parameter(Jvm::Class::named("org/apache/log4j/Level"))
+ .returns(Jvm::get()->voidClass));
+
+ Jvm::get()->invoke<void>(object, method, (jobject) level);
+ }
+
+protected:
+ Category() {} // No default constructors.
+};
+
+
+class Logger : public Category
+{
+public:
+ static Logger getRootLogger()
+ {
+ static Jvm::Method method = Jvm::get()->findStaticMethod(
+ Jvm::Class::named("org/apache/log4j/Logger")
+ .method("getRootLogger")
+ .returns(Jvm::Class::named("org/apache/log4j/Logger")));
+
+ Logger logger;
+ logger.object = Jvm::get()->invokeStatic<jobject>(method);
+
+ return logger;
+ }
+
+protected:
+ Logger() {} // No default constructors.
+};
+
+
+} // namespace log4j {
+} // namespace apache {
+} // namespace org {
+
+#endif // __ORG_APACHE_LOG4J_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/jvm/org/apache/zookeeper.hpp
----------------------------------------------------------------------
diff --git a/src/jvm/org/apache/zookeeper.hpp b/src/jvm/org/apache/zookeeper.hpp
new file mode 100644
index 0000000..dac1456
--- /dev/null
+++ b/src/jvm/org/apache/zookeeper.hpp
@@ -0,0 +1,168 @@
+#ifndef __ORG_APACHE_ZOOKEEPER_HPP__
+#define __ORG_APACHE_ZOOKEEPER_HPP__
+
+#include <jvm/jvm.hpp>
+
+#include <jvm/java/io.hpp>
+#include <jvm/java/net.hpp>
+
+// Package 'org.apache.zookeeper.persistence'.
+
+namespace org {
+namespace apache {
+namespace zookeeper {
+namespace persistence {
+
+class FileTxnSnapLog : public Jvm::Object
+{
+public:
+ FileTxnSnapLog(const java::io::File& dataDir,
+ const java::io::File& snapDir)
+ {
+ static Jvm::Constructor constructor = Jvm::get()->findConstructor(
+ Jvm::Class::named(
+ "org/apache/zookeeper/server/persistence/FileTxnSnapLog")
+ .constructor()
+ .parameter(Jvm::Class::named("java/io/File"))
+ .parameter(Jvm::Class::named("java/io/File")));
+
+ object = Jvm::get()->invoke(
+ constructor, (jobject) dataDir, (jobject) snapDir);
+ }
+};
+
+} // namespace persistence {
+} // namespace zookeeper {
+} // namespace apache {
+} // namespace org {
+
+
+// Package 'org.apache.zookeeper.server'.
+
+namespace org {
+namespace apache {
+namespace zookeeper {
+namespace server {
+
+class ZooKeeperServer : public Jvm::Object
+{
+public:
+ class DataTreeBuilder : public Jvm::Object {};
+
+ class BasicDataTreeBuilder : public DataTreeBuilder
+ {
+ public:
+ BasicDataTreeBuilder()
+ {
+ static Jvm::Constructor constructor = Jvm::get()->findConstructor(
+ Jvm::Class::named(
+ "org/apache/zookeeper/server/ZooKeeperServer$BasicDataTreeBuilder")
+ .constructor());
+
+ object = Jvm::get()->invoke(constructor);
+ }
+ };
+
+ ZooKeeperServer(const persistence::FileTxnSnapLog& txnLogFactory,
+ const DataTreeBuilder& treeBuilder)
+ {
+ static Jvm::Constructor constructor = Jvm::get()->findConstructor(
+ Jvm::Class::named("org/apache/zookeeper/server/ZooKeeperServer")
+ .constructor()
+ .parameter(
+ Jvm::Class::named(
+ "org/apache/zookeeper/server/persistence/FileTxnSnapLog"))
+ .parameter(
+ Jvm::Class::named(
+ "org/apache/zookeeper/server/ZooKeeperServer$DataTreeBuilder")));
+
+ object = Jvm::get()->invoke(
+ constructor, (jobject) txnLogFactory, (jobject) treeBuilder);
+ }
+
+ int getClientPort()
+ {
+ static Jvm::Method method = Jvm::get()->findMethod(
+ Jvm::Class::named("org/apache/zookeeper/server/ZooKeeperServer")
+ .method("getClientPort")
+ .returns(Jvm::get()->intClass));
+
+ return Jvm::get()->invoke<int>(object, method);
+ }
+
+ void closeSession(int64_t sessionId)
+ {
+ static Jvm::Method method = Jvm::get()->findMethod(
+ Jvm::Class::named("org/apache/zookeeper/server/ZooKeeperServer")
+ .method("closeSession")
+ .parameter(Jvm::get()->longClass)
+ .returns(Jvm::get()->voidClass));
+
+ Jvm::get()->invoke<void>(object, method, sessionId);
+ }
+};
+
+
+class NIOServerCnxn : public Jvm::Object
+{
+public:
+ class Factory : public Jvm::Object // TODO(benh): Extends Thread.
+ {
+ public:
+ Factory(const java::net::InetSocketAddress& addr)
+ {
+ static Jvm::Constructor constructor = Jvm::get()->findConstructor(
+ Jvm::Class::named(
+ "org/apache/zookeeper/server/NIOServerCnxn$Factory")
+ .constructor()
+ .parameter(Jvm::Class::named("java/net/InetSocketAddress")));
+
+ object = Jvm::get()->invoke(constructor, (jobject) addr);
+ }
+
+ void startup(const ZooKeeperServer& zks)
+ {
+ static Jvm::Method method = Jvm::get()->findMethod(
+ Jvm::Class::named(
+ "org/apache/zookeeper/server/NIOServerCnxn$Factory")
+ .method("startup")
+ .parameter(Jvm::Class::named(
+ "org/apache/zookeeper/server/ZooKeeperServer"))
+ .returns(Jvm::get()->voidClass));
+
+ Jvm::get()->invoke<void>(object, method, (jobject) zks);
+ }
+
+ bool isAlive()
+ {
+ static Jvm::Method method = Jvm::get()->findMethod(
+ Jvm::Class::named(
+ "org/apache/zookeeper/server/NIOServerCnxn$Factory")
+ .method("isAlive")
+ .returns(Jvm::get()->booleanClass));
+
+ return Jvm::get()->invoke<bool>(object, method);
+ }
+
+ void shutdown()
+ {
+ static Jvm::Method method = Jvm::get()->findMethod(
+ Jvm::Class::named(
+ "org/apache/zookeeper/server/NIOServerCnxn$Factory")
+ .method("shutdown")
+ .returns(Jvm::get()->voidClass));
+
+ Jvm::get()->invoke<void>(object, method);
+ }
+ };
+
+private:
+ NIOServerCnxn() {} // No default constructors.
+};
+
+} // namespace server {
+} // namespace zookeeper {
+} // namespace apache {
+} // namespace org {
+
+#endif // __ORG_APACHE_ZOOKEEPER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/tests/zookeeper_test.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_test.cpp b/src/tests/zookeeper_test.cpp
index fb61f2d..90c6aba 100644
--- a/src/tests/zookeeper_test.cpp
+++ b/src/tests/zookeeper_test.cpp
@@ -24,14 +24,17 @@
#include <tr1/functional>
+#include <jvm/jvm.hpp>
+
+#include <jvm/org/apache/log4j.hpp>
+#include <jvm/org/apache/log4j.hpp>
+
#include <stout/lambda.hpp>
#include "common/lock.hpp"
#include "logging/logging.hpp"
-#include "jvm/jvm.hpp"
-
#include "tests/utils.hpp"
#include "tests/zookeeper_test.hpp"
#include "tests/zookeeper_test_server.hpp"
@@ -40,45 +43,12 @@ namespace mesos {
namespace internal {
namespace tests {
-const Milliseconds ZooKeeperTest::NO_TIMEOUT(5000);
-
-// Note that we NEVER delete the Jvm instance because you can only
-// create one JVM since destructing a JVM has issues (see:
-// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4712793).
-Jvm* ZooKeeperTest::jvm = NULL;
-
-
-static void silenceServerLogs(Jvm* jvm)
-{
- Jvm::Attach attach(jvm);
-
- Jvm::JClass loggerClass = Jvm::JClass::forName("org/apache/log4j/Logger");
- jobject rootLogger =jvm->invokeStatic<jobject>(
- jvm->findStaticMethod(loggerClass
- .method("getRootLogger")
- .returns(loggerClass)));
-
- Jvm::JClass levelClass = Jvm::JClass::forName("org/apache/log4j/Level");
- jvm->invoke<void>(
- rootLogger,
- jvm->findMethod(loggerClass
- .method("setLevel")
- .parameter(levelClass)
- .returns(jvm->voidClass)),
- jvm->getStaticField<jobject>(jvm->findStaticField(levelClass, "OFF")));
-}
-
-
-static void silenceClientLogs()
-{
- // TODO(jsirois): Put this in the C++ API.
- zoo_set_debug_level(ZOO_LOG_LEVEL_ERROR);
-}
+const Duration ZooKeeperTest::NO_TIMEOUT = Milliseconds(5000);
void ZooKeeperTest::SetUpTestCase()
{
- if (jvm == NULL) {
+ if (!Jvm::created()) {
std::string zkHome = flags.build_dir +
"/third_party/zookeeper-" ZOOKEEPER_VERSION;
@@ -88,13 +58,19 @@ void ZooKeeperTest::SetUpTestCase()
LOG(INFO) << "Using classpath setup: " << classpath << std::endl;
- std::vector<std::string> opts;
- opts.push_back(classpath);
- jvm = new Jvm(opts);
+ std::vector<std::string> options;
+ options.push_back(classpath);
+ Try<Jvm*> jvm = Jvm::create(options);
+ CHECK_SOME(jvm);
if (!flags.verbose) {
- silenceServerLogs(jvm);
- silenceClientLogs();
+ // Silence server logs.
+ org::apache::log4j::Logger::getRootLogger()
+ .setLevel(org::apache::log4j::Level::OFF);
+
+ // Silence client logs.
+ // TODO(jsirois): Create C++ ZooKeeper::setLevel.
+ zoo_set_debug_level(ZOO_LOG_LEVEL_ERROR);
}
}
}
@@ -102,18 +78,8 @@ void ZooKeeperTest::SetUpTestCase()
void ZooKeeperTest::SetUp()
{
- MesosTest::SetUp();
- server = new ZooKeeperTestServer(jvm);
server->startNetwork();
-};
-
-
-void ZooKeeperTest::TearDown()
-{
- delete server;
- server = NULL;
- MesosTest::TearDown();
-};
+}
ZooKeeperTest::TestWatcher::TestWatcher()
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/tests/zookeeper_test.hpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_test.hpp b/src/tests/zookeeper_test.hpp
index 61a3d25..7bd396b 100644
--- a/src/tests/zookeeper_test.hpp
+++ b/src/tests/zookeeper_test.hpp
@@ -29,8 +29,6 @@
#include <stout/duration.hpp>
-#include "jvm/jvm.hpp"
-
#include "tests/utils.hpp"
#include "tests/zookeeper_test_server.hpp"
@@ -82,7 +80,6 @@ public:
class TestWatcher : public Watcher
{
public:
-
// Encapsulates all the state of a ZooKeeper watcher event.
struct Event {
Event(int _type, int _state, const std::string& _path)
@@ -119,21 +116,18 @@ public:
pthread_cond_t cond;
};
- ZooKeeperTest() : server(NULL) {}
+ ZooKeeperTest() : server(new ZooKeeperTestServer()) {}
+ virtual ~ZooKeeperTest() { delete server; }
static void SetUpTestCase();
protected:
virtual void SetUp();
- virtual void TearDown();
// A very long session timeout that simulates no timeout for test cases.
- static const Milliseconds NO_TIMEOUT;
+ static const Duration NO_TIMEOUT;
ZooKeeperTestServer* server;
-
-private:
- static Jvm* jvm;
};
} // namespace tests {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/tests/zookeeper_test_server.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_test_server.cpp b/src/tests/zookeeper_test_server.cpp
index 5c82a1e..8051b4d 100644
--- a/src/tests/zookeeper_test_server.cpp
+++ b/src/tests/zookeeper_test_server.cpp
@@ -16,130 +16,48 @@
* limitations under the License.
*/
-#include <jni.h>
-#include <stdarg.h>
+#include <jvm/jvm.hpp>
-#include <glog/logging.h>
+#include <jvm/java/io.hpp>
+#include <jvm/java/net.hpp>
-#include <sstream>
-#include <vector>
+#include <jvm/org/apache/zookeeper.hpp>
-#include <stout/uuid.hpp>
+#include <stout/os.hpp>
-#include "jvm/jvm.hpp"
+#include "logging/logging.hpp"
#include "tests/zookeeper_test_server.hpp"
+using org::apache::zookeeper::persistence::FileTxnSnapLog;
+
+using org::apache::zookeeper::server::NIOServerCnxn;
+using org::apache::zookeeper::server::ZooKeeperServer;
+
namespace mesos {
namespace internal {
namespace tests {
-ZooKeeperTestServer::ZooKeeperTestServer(Jvm* _jvm)
- : jvm(_jvm),
+ZooKeeperTestServer::ZooKeeperTestServer()
+ : zooKeeperServer(NULL),
+ connectionFactory(NULL),
port(0),
started(false)
{
- Jvm::Attach attach(jvm);
-
- Jvm::JClass fileClass = Jvm::JClass::forName("java/io/File");
- fileConstructor = new Jvm::JConstructor(
- jvm->findConstructor(
- fileClass
- .constructor()
- .parameter(jvm->stringClass)));
-
- Jvm::JClass inetSocketAddressClass =
- Jvm::JClass::forName("java/net/InetSocketAddress");
- inetSocketAddressConstructor = new Jvm::JConstructor(
- jvm->findConstructor(
- inetSocketAddressClass
- .constructor()
- .parameter(jvm->intClass)));
-
- Jvm::JClass cnxnFactoryClass =
- Jvm::JClass::forName("org/apache/zookeeper/server/NIOServerCnxn$Factory");
- cnxnFactoryConstructor = new Jvm::JConstructor(
- jvm->findConstructor(
- cnxnFactoryClass
- .constructor()
- .parameter(inetSocketAddressClass)));
-
- Jvm::JClass zkServerClass =
- Jvm::JClass::forName("org/apache/zookeeper/server/ZooKeeperServer");
- startup = new Jvm::JMethod(
- jvm->findMethod(
- cnxnFactoryClass
- .method("startup")
- .parameter(zkServerClass)
- .returns(jvm->voidClass)));
-
- isAlive = new Jvm::JMethod(
- jvm->findMethod(
- cnxnFactoryClass
- .method("isAlive")
- .returns(jvm->booleanClass)));
-
- shutdown = new Jvm::JMethod(
- jvm->findMethod(
- cnxnFactoryClass
- .method("shutdown")
- .returns(jvm->voidClass)));
-
- dataDir = createTempDir();
- snapDir = createTempDir();
- Jvm::JClass snapLogClass =
- Jvm::JClass::forName(
- "org/apache/zookeeper/server/"
- "persistence/FileTxnSnapLog");
-
- snapLog = jvm->newGlobalRef(
- jvm->invoke(
- jvm->findConstructor(snapLogClass
- .constructor()
- .parameter(fileClass)
- .parameter(fileClass)),
- dataDir->file,
- snapDir->file));
-
- dataTreeBuilder = jvm->newGlobalRef(
- jvm->invoke(
- jvm->findConstructor(
- Jvm::JClass::forName(
- "org/apache/zookeeper/server/"
- "ZooKeeperServer$BasicDataTreeBuilder").constructor())));
-
- Jvm::JClass dataTreeBuilderClass(
- Jvm::JClass::forName("org/apache/zookeeper/server/"
- "ZooKeeperServer$DataTreeBuilder"));
-
- zooKeeperServer = jvm->newGlobalRef(
- jvm->invoke(
- jvm->findConstructor(zkServerClass
- .constructor()
- .parameter(snapLogClass)
- .parameter(dataTreeBuilderClass)),
- snapLog,
- dataTreeBuilder));
-
- getClientPort = new Jvm::JMethod(
- jvm->findMethod(zkServerClass
- .method("getClientPort")
- .returns(jvm->intClass)));
-
- closeSession = new Jvm::JMethod(
- jvm->findMethod(zkServerClass
- .method("closeSession")
- .parameter(jvm->longClass)
- .returns(jvm->voidClass)));
-}
-
-
-const ZooKeeperTestServer::TemporaryDirectory* ZooKeeperTestServer::createTempDir()
-{
- std::string tmpdir = "/tmp/zks-" + UUID::random().toString();
- jobject file =
- jvm->newGlobalRef(jvm->invoke(*fileConstructor, jvm->string(tmpdir)));
- return new TemporaryDirectory(jvm, tmpdir, file);
+ // Create temporary directories for the FileTxnSnapLog.
+ Try<std::string> directory = os::mkdtemp();
+ CHECK_SOME(directory);
+ java::io::File dataDir(directory.get());
+ dataDir.deleteOnExit();
+
+ directory = os::mkdtemp();
+ CHECK_SOME(directory);
+ java::io::File snapDir(directory.get());
+ snapDir.deleteOnExit();
+
+ zooKeeperServer = new ZooKeeperServer(
+ FileTxnSnapLog(dataDir, snapDir),
+ ZooKeeperServer::BasicDataTreeBuilder());
}
@@ -147,51 +65,30 @@ ZooKeeperTestServer::~ZooKeeperTestServer()
{
shutdownNetwork();
- Jvm::Attach attach(jvm);
-
- jvm->deleteGlobalRefSafe(inetSocketAddress);
- jvm->deleteGlobalRefSafe(connectionFactory);
- jvm->deleteGlobalRefSafe(snapLog);
- jvm->deleteGlobalRefSafe(dataTreeBuilder);
- jvm->deleteGlobalRefSafe(zooKeeperServer);
-
- delete fileConstructor;
- delete getClientPort;
- delete closeSession;
-
- delete inetSocketAddressConstructor;
- delete cnxnFactoryConstructor;
-
- delete startup;
- delete isAlive;
- delete shutdown;
-
- delete dataDir;
- delete snapDir;
+ delete zooKeeperServer;
+ delete connectionFactory;
}
void ZooKeeperTestServer::expireSession(int64_t sessionId)
{
- Jvm::Attach attach(jvm);
-
- jvm->invoke<void>(zooKeeperServer, *closeSession, sessionId);
+ zooKeeperServer->closeSession(sessionId);
}
std::string ZooKeeperTestServer::connectString() const
{
- checkStarted();
+ CHECK(port > 0) << "Illegal state, must call startNetwork first!";
return "127.0.0.1:" + stringify(port);
}
void ZooKeeperTestServer::shutdownNetwork()
{
- Jvm::Attach attach(jvm);
-
- if (started && jvm->invoke<bool>(connectionFactory, *isAlive)) {
- jvm->invoke<void>(connectionFactory, *shutdown);
+ if (started && connectionFactory->isAlive()) {
+ connectionFactory->shutdown();
+ delete connectionFactory;
+ connectionFactory = NULL;
LOG(INFO) << "Shutdown ZooKeeperTestServer on port " << port << std::endl;
}
}
@@ -199,28 +96,24 @@ void ZooKeeperTestServer::shutdownNetwork()
int ZooKeeperTestServer::startNetwork()
{
- Jvm::Attach attach(jvm);
+ connectionFactory = new NIOServerCnxn::Factory(
+ java::net::InetSocketAddress(port));
- inetSocketAddress =
- jvm->newGlobalRef(jvm->invoke(*inetSocketAddressConstructor, port));
- connectionFactory =
- jvm->newGlobalRef(
- jvm->invoke(*cnxnFactoryConstructor, inetSocketAddress));
+ connectionFactory->startup(*zooKeeperServer);
+
+ if (port == 0) {
+ // We save the ephemeral port so if/when we restart the network
+ // the clients will reconnect to the same server. Note that this
+ // might not actually be kosher because it's possible that another
+ // process could bind to our ephemeral port after we unbind.
+ port = zooKeeperServer->getClientPort();
+ }
- jvm->invoke<void>(connectionFactory, *startup, zooKeeperServer);
- port = jvm->invoke<int>(zooKeeperServer, *getClientPort);
LOG(INFO) << "Started ZooKeeperTestServer on port " << port;
started = true;
return port;
}
-
-void ZooKeeperTestServer::checkStarted() const
-{
- CHECK(port > 0) << "Illegal state, must call startNetwork first!";
-}
-
} // namespace tests {
} // namespace internal {
} // namespace mesos {
-
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/233edea2/src/tests/zookeeper_test_server.hpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_test_server.hpp b/src/tests/zookeeper_test_server.hpp
index bfa841c..97a8524 100644
--- a/src/tests/zookeeper_test_server.hpp
+++ b/src/tests/zookeeper_test_server.hpp
@@ -19,13 +19,13 @@
#ifndef __ZOOKEEPER_TEST_SERVER_HPP__
#define __ZOOKEEPER_TEST_SERVER_HPP__
-#include <jni.h>
+#include <string>
#include <glog/logging.h>
-#include <stout/os.hpp>
+#include <jvm/org/apache/zookeeper.hpp>
-#include "jvm/jvm.hpp"
+#include <stout/os.hpp>
#include "zookeeper/zookeeper.hpp"
@@ -40,7 +40,7 @@ namespace tests {
class ZooKeeperTestServer
{
public:
- ZooKeeperTestServer(Jvm* jvm);
+ ZooKeeperTestServer();
~ZooKeeperTestServer();
// Gets a connection string that can be used to attach a ZooKeeper client to
@@ -67,54 +67,11 @@ public:
void expireSession(int64_t sessionId);
private:
- // TODO(John Sirois): factor out TemporaryDirectory + createTempDir() to utils
- struct TemporaryDirectory
- {
- Jvm* jvm;
- const std::string path;
- const jobject file;
-
- TemporaryDirectory(Jvm* _jvm,
- const std::string& _path,
- const jobject _file) : jvm(_jvm),
- path(_path),
- file(_file) {}
-
- ~TemporaryDirectory()
- {
- jvm->deleteGlobalRef(file);
- Try<Nothing> rmdir = os::rmdir(path);
- if (rmdir.isError()) {
- LOG(WARNING) << "Failed to delete temp dir '"
- << path << "': " << rmdir.error();
- }
- }
- };
-
- Jvm* jvm;
-
- Jvm::JConstructor* fileConstructor;
- jobject snapLog;
- jobject dataTreeBuilder;
- jobject zooKeeperServer;
- Jvm::JMethod* getClientPort;
- Jvm::JMethod* closeSession;
-
- Jvm::JConstructor* inetSocketAddressConstructor;
- jobject inetSocketAddress;
- Jvm::JConstructor* cnxnFactoryConstructor;
- jobject connectionFactory;
- Jvm::JMethod* startup;
- Jvm::JMethod* isAlive;
- Jvm::JMethod* shutdown;
+ org::apache::zookeeper::server::ZooKeeperServer* zooKeeperServer;
+ org::apache::zookeeper::server::NIOServerCnxn::Factory* connectionFactory;
int port;
bool started;
- const TemporaryDirectory* dataDir;
- const TemporaryDirectory* snapDir;
-
- const TemporaryDirectory* createTempDir();
- void checkStarted() const;
};
} // namespace tests {