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:36 UTC
[11/28] Refactored MesosTest/MesosClusterTest into a generic fixture
for launching in-memory Mesos clusters and updated all tests appropriately.
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>