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/04/04 22:57:59 UTC
svn commit: r1464756 - in /incubator/mesos/trunk/src: Makefile.am
tests/cluster.hpp tests/isolator.hpp tests/master_tests.cpp
tests/state_tests.cpp tests/utils.hpp
Author: benh
Date: Thu Apr 4 20:57:58 2013
New Revision: 1464756
URL: http://svn.apache.org/r1464756
Log:
Added and used new Cluster abstraction for testing.
Review: https://reviews.apache.org/r/10264
Added:
incubator/mesos/trunk/src/tests/cluster.hpp
incubator/mesos/trunk/src/tests/isolator.hpp
Modified:
incubator/mesos/trunk/src/Makefile.am
incubator/mesos/trunk/src/tests/master_tests.cpp
incubator/mesos/trunk/src/tests/state_tests.cpp
incubator/mesos/trunk/src/tests/utils.hpp
Modified: incubator/mesos/trunk/src/Makefile.am
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/Makefile.am?rev=1464756&r1=1464755&r2=1464756&view=diff
==============================================================================
--- incubator/mesos/trunk/src/Makefile.am (original)
+++ incubator/mesos/trunk/src/Makefile.am Thu Apr 4 20:57:58 2013
@@ -234,6 +234,8 @@ libmesos_no_third_party_la_SOURCES += co
slave/slave.hpp \
tests/environment.hpp tests/script.hpp \
tests/zookeeper_test.hpp tests/flags.hpp tests/utils.hpp \
+ tests/cluster.hpp \
+ tests/isolator.hpp \
tests/zookeeper_test_server.hpp zookeeper/authentication.hpp \
zookeeper/group.hpp zookeeper/watcher.hpp \
zookeeper/zookeeper.hpp zookeeper/url.hpp
Added: incubator/mesos/trunk/src/tests/cluster.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/cluster.hpp?rev=1464756&view=auto
==============================================================================
--- incubator/mesos/trunk/src/tests/cluster.hpp (added)
+++ incubator/mesos/trunk/src/tests/cluster.hpp Thu Apr 4 20:57:58 2013
@@ -0,0 +1,476 @@
+/**
+ * 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_CLUSTER_HPP__
+#define __TESTS_CLUSTER_HPP__
+
+#include <map>
+
+#include <process/pid.hpp>
+#include <process/process.hpp>
+
+#include <stout/error.hpp>
+#include <stout/foreach.hpp>
+#include <stout/none.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/owned.hpp>
+#include <stout/try.hpp>
+
+#include "detector/detector.hpp"
+
+#include "files/files.hpp"
+
+#include "master/allocator.hpp"
+#include "master/hierarchical_allocator_process.hpp"
+#include "master/flags.hpp"
+#include "master/master.hpp"
+
+#include "slave/flags.hpp"
+#include "slave/isolator.hpp"
+#include "slave/slave.hpp"
+
+#include "tests/isolator.hpp" // For TestingIsolator.
+
+#include "zookeeper/url.hpp"
+
+namespace mesos {
+namespace internal {
+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) {}
+
+ // Abstracts the masters of a cluster.
+ class Masters
+ {
+ public:
+ Masters(Cluster* _cluster, const Option<zookeeper::URL>& _url);
+ ~Masters();
+
+ void shutdown();
+
+ // Start and manage a new master.
+ Try<process::PID<master::Master> > start();
+ Try<process::PID<master::Master> > start(const master::Flags& flags);
+
+ // Stops and cleans up a master at the specified PID.
+ Try<Nothing> stop(const process::PID<master::Master>& pid);
+
+ // 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;
+
+ private:
+ // Not copyable, not assignable.
+ Masters(const Masters&);
+ Masters& operator = (const Masters&);
+
+ Cluster* cluster; // Enclosing class.
+ Option<zookeeper::URL> url;
+
+ struct Master
+ {
+ Master()
+ : master(NULL),
+ allocator(NULL),
+ allocatorProcess(NULL),
+ detector(NULL) {}
+
+ master::Master* master;
+ master::Allocator* allocator;
+ master::AllocatorProcess* allocatorProcess;
+ MasterDetector* detector;
+ };
+
+ std::map<process::PID<master::Master>, Master> masters;
+ };
+
+ // Abstracts the slaves of a cluster.
+ class Slaves
+ {
+ public:
+ Slaves(Cluster* _cluster, Masters* _masters);
+ ~Slaves();
+
+ // Stop and clean up all slaves.
+ void shutdown();
+
+ // Start and manage a new slave.
+ Try<process::PID<slave::Slave> > start();
+ Try<process::PID<slave::Slave> > start(const slave::Flags& flags);
+ Try<process::PID<slave::Slave> > start(
+ const ExecutorID& executorId,
+ Executor* executor);
+ Try<process::PID<slave::Slave> > start(slave::Isolator* isolator);
+ Try<process::PID<slave::Slave> > start(
+ const slave::Flags& flags,
+ slave::Isolator* isolator);
+
+ // 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;
+
+ private:
+ // Not copyable, not assignable.
+ Slaves(const Slaves&);
+ Slaves& operator = (const Slaves&);
+
+ Cluster* cluster; // Enclosing class.
+ Masters* masters; // Used to create MasterDetector instances.
+
+ struct Slave
+ {
+ Slave()
+ : slave(NULL),
+ isolator(NULL),
+ detector(NULL) {}
+
+ slave::Slave* slave;
+ slave::Isolator* isolator;
+ Owned<MasterDetector> detector;
+ };
+
+ std::map<process::PID<slave::Slave>, Slave> slaves;
+ };
+
+ // Shuts down all masters and slaves.
+ void shutdown()
+ {
+ masters.shutdown();
+ slaves.shutdown();
+ }
+
+ // Cluster wide shared abstractions.
+ Files files;
+
+ Masters masters;
+ Slaves slaves;
+
+private:
+ // Not copyable, not assignable.
+ Cluster(const Cluster&);
+ Cluster& operator = (const Cluster&);
+};
+
+
+inline Cluster::Masters::Masters(
+ Cluster* _cluster,
+ const Option<zookeeper::URL>& _url)
+ : cluster(_cluster),
+ url(_url) {}
+
+
+inline Cluster::Masters::~Masters()
+{
+ shutdown();
+}
+
+
+inline void Cluster::Masters::shutdown()
+{
+ // TODO(benh): Use utils::copy from stout once namespaced.
+ std::map<process::PID<master::Master>, Master> copy(masters);
+ foreachkey (const process::PID<master::Master>& pid, copy) {
+ stop(pid);
+ }
+ masters.clear();
+}
+
+
+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)
+{
+ // 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<Nothing> Cluster::Masters::stop(
+ const process::PID<master::Master>& pid)
+{
+ if (masters.count(pid) == 0) {
+ return Error("No master found to stop");
+ }
+
+ Master master = masters[pid];
+
+ process::terminate(master.master);
+ process::wait(master.master);
+ delete master.master;
+
+ delete master.allocator; // Terminates and waits for the allocator process.
+ delete master.allocatorProcess;
+
+ delete master.detector;
+
+ masters.erase(pid);
+
+ return Nothing();
+}
+
+
+inline Owned<MasterDetector> Cluster::Masters::detector(
+ const process::PID<slave::Slave>& pid,
+ bool quiet)
+{
+ if (url.isSome()) {
+ return new ZooKeeperMasterDetector(url.get(), pid, false, quiet);
+ }
+
+ CHECK(masters.size() == 1);
+ return new BasicMasterDetector(masters.begin()->first, pid);
+}
+
+
+inline Cluster::Slaves::Slaves(Cluster* _cluster, Masters* _masters)
+ : cluster(_cluster), masters(_masters) {}
+
+
+inline Cluster::Slaves::~Slaves()
+{
+ shutdown();
+}
+
+
+inline void Cluster::Slaves::shutdown()
+{
+ // TODO(benh): Use utils::copy from stout once namespaced.
+ std::map<process::PID<slave::Slave>, Slave> copy(slaves);
+ foreachkey (const process::PID<slave::Slave>& pid, copy) {
+ stop(pid);
+ }
+ slaves.clear();
+}
+
+
+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).
+
+ 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 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)
+{
+ // 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<Nothing> Cluster::Slaves::stop(
+ const process::PID<slave::Slave>& pid)
+{
+ if (slaves.count(pid) == 0) {
+ return Error("No slave found to stop");
+ }
+
+ Slave slave = slaves[pid];
+
+ 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;
+ }
+
+ slaves.erase(pid);
+
+ return Nothing();
+}
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __TESTS_CLUSTER_HPP__
Added: incubator/mesos/trunk/src/tests/isolator.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/isolator.hpp?rev=1464756&view=auto
==============================================================================
--- incubator/mesos/trunk/src/tests/isolator.hpp (added)
+++ incubator/mesos/trunk/src/tests/isolator.hpp Thu Apr 4 20:57:58 2013
@@ -0,0 +1,180 @@
+/**
+ * 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_ISOLATOR_HPP__
+#define __TESTS_ISOLATOR_HPP__
+
+#include <map>
+#include <string>
+
+#include <process/dispatch.hpp>
+#include <process/future.hpp>
+#include <process/pid.hpp>
+
+#include <stout/try.hpp>
+#include <stout/uuid.hpp>
+
+#include "slave/isolator.hpp"
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+class TestingIsolator : public slave::Isolator
+{
+public:
+ TestingIsolator()
+ {
+ setup();
+ }
+
+ TestingIsolator(const std::map<ExecutorID, Executor*>& _executors)
+ : executors(_executors)
+ {
+ setup();
+ }
+
+ TestingIsolator(const ExecutorID& executorId, Executor* executor)
+ {
+ executors[executorId] = executor;
+ setup();
+ }
+
+ virtual ~TestingIsolator() {}
+
+ virtual void initialize(
+ const slave::Flags& flags,
+ const Resources& resources,
+ bool local,
+ const process::PID<slave::Slave>& _slave)
+ {
+ slave = _slave;
+ }
+
+ virtual void launchExecutor(
+ const SlaveID& slaveId,
+ const FrameworkID& frameworkId,
+ const FrameworkInfo& frameworkInfo,
+ const ExecutorInfo& executorInfo,
+ const UUID& uuid,
+ const std::string& directory,
+ const Resources& resources,
+ const Option<std::string>& path)
+ {
+ if (executors.count(executorInfo.executor_id()) > 0) {
+ Executor* executor = executors[executorInfo.executor_id()];
+ MesosExecutorDriver* driver = new MesosExecutorDriver(executor);
+ drivers[executorInfo.executor_id()] = driver;
+
+ directories[executorInfo.executor_id()] = directory;
+
+ os::setenv("MESOS_LOCAL", "1");
+ os::setenv("MESOS_DIRECTORY", directory);
+ os::setenv("MESOS_SLAVE_PID", slave);
+ os::setenv("MESOS_SLAVE_ID", slaveId.value());
+ os::setenv("MESOS_FRAMEWORK_ID", frameworkId.value());
+ os::setenv("MESOS_EXECUTOR_ID", executorInfo.executor_id().value());
+ os::setenv("MESOS_CHECKPOINT", frameworkInfo.checkpoint() ? "1" : "0");
+
+ driver->start();
+
+ os::unsetenv("MESOS_LOCAL");
+ os::unsetenv("MESOS_DIRECTORY");
+ os::unsetenv("MESOS_SLAVE_PID");
+ os::unsetenv("MESOS_SLAVE_ID");
+ os::unsetenv("MESOS_FRAMEWORK_ID");
+ os::unsetenv("MESOS_EXECUTOR_ID");
+ os::unsetenv("MESOS_CHECKPOINT");
+
+ process::dispatch(
+ slave,
+ &slave::Slave::executorStarted,
+ frameworkId,
+ executorInfo.executor_id(),
+ -1);
+
+ } else {
+ FAIL() << "Cannot launch executor";
+ }
+ }
+
+ virtual void killExecutor(
+ const FrameworkID& frameworkId,
+ const ExecutorID& executorId)
+ {
+ if (drivers.count(executorId) > 0) {
+ MesosExecutorDriver* driver = drivers[executorId];
+ driver->stop();
+ driver->join();
+ delete driver;
+ drivers.erase(executorId);
+
+ process::dispatch(
+ slave,
+ &slave::Slave::executorTerminated,
+ frameworkId,
+ executorId,
+ 0,
+ false,
+ "Killed executor");
+ } else {
+ FAIL() << "Cannot kill executor";
+ }
+ }
+
+ // Mocked so tests can check that the resources reflect all started tasks.
+ MOCK_METHOD3(resourcesChanged, void(const FrameworkID&,
+ const ExecutorID&,
+ const Resources&));
+
+ MOCK_METHOD2(
+ usage,
+ process::Future<ResourceStatistics>(
+ const FrameworkID&,
+ const ExecutorID&));
+
+ MOCK_METHOD1(
+ recover,
+ process::Future<Nothing>(const Option<slave::state::SlaveState>&));
+
+ std::map<ExecutorID, std::string> directories;
+
+private:
+ // Helper to setup default expectations.
+ void setup()
+ {
+ EXPECT_CALL(*this, resourcesChanged(testing::_, testing::_, testing::_))
+ .Times(testing::AnyNumber());
+
+ EXPECT_CALL(*this, usage(testing::_, testing::_))
+ .WillRepeatedly(testing::Return(ResourceStatistics()));
+
+ EXPECT_CALL(*this, recover(testing::_))
+ .WillRepeatedly(testing::Return(Nothing()));
+ }
+
+ std::map<ExecutorID, Executor*> executors;
+ std::map<ExecutorID, MesosExecutorDriver*> drivers;
+ process::PID<slave::Slave> slave;
+};
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __TESTS_ISOLATOR_HPP__
Modified: incubator/mesos/trunk/src/tests/master_tests.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/master_tests.cpp?rev=1464756&r1=1464755&r2=1464756&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/master_tests.cpp (original)
+++ incubator/mesos/trunk/src/tests/master_tests.cpp Thu Apr 4 20:57:58 2013
@@ -38,23 +38,20 @@
#include "flags/flags.hpp"
-#include "master/allocator.hpp"
#include "master/flags.hpp"
-#include "master/hierarchical_allocator_process.hpp"
#include "master/master.hpp"
#include "slave/constants.hpp"
#include "slave/process_isolator.hpp"
#include "slave/slave.hpp"
+#include "tests/cluster.hpp"
#include "tests/utils.hpp"
using namespace mesos;
using namespace mesos::internal;
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;
@@ -76,30 +73,25 @@ using testing::Eq;
using testing::Return;
-class MasterTest : public MesosTest {};
+class MasterTest : public MesosClusterTest {};
TEST_F(MasterTest, TaskRunning)
{
ASSERT_TRUE(GTEST_IS_THREADSAFE);
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
+ Try<PID<Master> > master = cluster.masters.start();
+ ASSERT_SOME(master);
MockExecutor exec;
TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
-
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = cluster.slaves.start(&isolator);
+ 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);
@@ -155,11 +147,7 @@ TEST_F(MasterTest, TaskRunning)
AWAIT_UNTIL(shutdown); // Ensures MockExecutor can be deallocated.
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
@@ -167,24 +155,20 @@ TEST_F(MasterTest, ShutdownFrameworkWhil
{
ASSERT_TRUE(GTEST_IS_THREADSAFE);
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
+ Try<PID<Master> > master = cluster.masters.start();
+ ASSERT_SOME(master);
MockExecutor exec;
TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- slaveFlags.executor_shutdown_grace_period = Seconds(0.0);
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
-
- BasicMasterDetector detector(master, slave, true);
+ slave::Flags flags = cluster.slaves.flags;
+ flags.executor_shutdown_grace_period = Seconds(0);
+ Try<PID<Slave> > slave = cluster.slaves.start(flags, &isolator);
+ 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);
@@ -240,11 +224,7 @@ TEST_F(MasterTest, ShutdownFrameworkWhil
AWAIT_UNTIL(shutdown); // Ensures MockExecutor can be deallocated.
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
@@ -252,23 +232,16 @@ TEST_F(MasterTest, KillTask)
{
ASSERT_TRUE(GTEST_IS_THREADSAFE);
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
+ Try<PID<Master> > master = cluster.masters.start();
+ ASSERT_SOME(master);
MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
-
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
-
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = cluster.slaves.start(DEFAULT_EXECUTOR_ID, &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, _, _))
.Times(1);
@@ -331,11 +304,7 @@ TEST_F(MasterTest, KillTask)
AWAIT_UNTIL(shutdown); // To ensure can deallocate MockExecutor.
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ cluster.shutdown();
}
@@ -343,23 +312,16 @@ TEST_F(MasterTest, StatusUpdateAck)
{
ASSERT_TRUE(GTEST_IS_THREADSAFE);
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
+ Try<PID<Master> > master = cluster.masters.start();
+ ASSERT_SOME(master);
MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
-
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
-
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = cluster.slaves.start(DEFAULT_EXECUTOR_ID, &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, _, _))
.Times(1);
@@ -393,7 +355,7 @@ TEST_F(MasterTest, StatusUpdateAck)
Future<Nothing> acknowledgement;
EXPECT_MESSAGE(Eq(StatusUpdateAcknowledgementMessage().GetTypeName()),
_,
- Eq(slave))
+ Eq(slave.get()))
.WillOnce(DoAll(FutureSatisfy(&acknowledgement),
Return(false)));
@@ -418,11 +380,7 @@ TEST_F(MasterTest, StatusUpdateAck)
AWAIT_UNTIL(shutdown); // Ensures MockExecutor can be deallocated.
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ cluster.shutdown();
}
@@ -430,25 +388,21 @@ TEST_F(MasterTest, RecoverResources)
{
ASSERT_TRUE(GTEST_IS_THREADSAFE);
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
+ Try<PID<Master> > master = cluster.masters.start();
+ ASSERT_SOME(master);
MockExecutor exec;
TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
- setSlaveResources("cpus:2;mem:1024;disk:1024;ports:[1-10, 20-30]");
-
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
-
- BasicMasterDetector detector(master, slave, true);
+ 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);
+ 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);
@@ -538,8 +492,7 @@ TEST_F(MasterTest, RecoverResources)
AWAIT_UNTIL(offers);
EXPECT_NE(0u, offers.get().size());
-
- Resources slaveResources = Resources::parse(slaveFlags.resources.get());
+ Resources slaveResources = Resources::parse(flags.resources.get());
EXPECT_EQ(slaveResources, offers.get()[0].resources());
driver.stop();
@@ -550,11 +503,7 @@ TEST_F(MasterTest, RecoverResources)
EXPECT_CALL(exec, shutdown(_))
.Times(AtMost(1));
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
@@ -562,26 +511,16 @@ TEST_F(MasterTest, FrameworkMessage)
{
ASSERT_TRUE(GTEST_IS_THREADSAFE);
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
+ Try<PID<Master> > master = cluster.masters.start();
+ ASSERT_SOME(master);
MockExecutor exec;
- TestingIsolator isolator(DEFAULT_EXECUTOR_ID, &exec);
-
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
-
- BasicMasterDetector detector(master, slave, true);
-
- // Launch the first (i.e., failing) scheduler and wait until the
- // first status update message is sent to it (drop the message).
+ Try<PID<Slave> > slave = cluster.slaves.start(DEFAULT_EXECUTOR_ID, &exec);
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver schedDriver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver schedDriver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
EXPECT_CALL(sched, registered(&schedDriver, _, _))
.Times(1);
@@ -650,11 +589,7 @@ TEST_F(MasterTest, FrameworkMessage)
AWAIT_UNTIL(shutdown); // To ensure can deallocate MockExecutor.
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ cluster.shutdown();
}
@@ -662,11 +597,8 @@ TEST_F(MasterTest, MultipleExecutors)
{
ASSERT_TRUE(GTEST_IS_THREADSAFE);
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
+ Try<PID<Master> > master = cluster.masters.start();
+ ASSERT_SOME(master);
ExecutorID executorId1;
executorId1.set_value("executor-1");
@@ -683,13 +615,11 @@ TEST_F(MasterTest, MultipleExecutors)
TestingIsolator isolator(execs);
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
-
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = cluster.slaves.start(&isolator);
+ 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);
@@ -777,11 +707,7 @@ TEST_F(MasterTest, MultipleExecutors)
AWAIT_UNTIL(shutdown1); // To ensure can deallocate MockExecutor.
AWAIT_UNTIL(shutdown2); // To ensure can deallocate MockExecutor.
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
@@ -789,21 +715,16 @@ TEST_F(MasterTest, ShutdownUnregisteredE
{
ASSERT_TRUE(GTEST_IS_THREADSAFE);
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
+ Try<PID<Master> > master = cluster.masters.start();
+ ASSERT_SOME(master);
ProcessIsolator isolator;
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
-
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = cluster.slaves.start(&isolator);
+ 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);
@@ -856,7 +777,7 @@ TEST_F(MasterTest, ShutdownUnregisteredE
Return(false)))
.WillRepeatedly(Return(false)); // TODO(benh): Why is this needed?
- Clock::advance(slaveFlags.executor_registration_timeout.secs());
+ Clock::advance(cluster.slaves.flags.executor_registration_timeout.secs());
AWAIT_UNTIL(killExecutor);
@@ -876,11 +797,7 @@ TEST_F(MasterTest, ShutdownUnregisteredE
driver.stop();
driver.join();
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ cluster.shutdown(); // Must shutdown before 'isolator' gets deallocated.
}
@@ -888,21 +805,14 @@ TEST_F(MasterTest, MasterInfo)
{
ASSERT_TRUE(GTEST_IS_THREADSAFE);
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
-
- TestingIsolator isolator;
+ Try<PID<Master> > master = cluster.masters.start();
+ ASSERT_SOME(master);
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
-
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = cluster.slaves.start();
+ ASSERT_SOME(slave);
MockScheduler sched;
- MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master);
+ MesosSchedulerDriver driver(&sched, DEFAULT_FRAMEWORK_INFO, master.get());
Future<MasterInfo> masterInfo;
EXPECT_CALL(sched, registered(&driver, _, _))
@@ -914,17 +824,13 @@ TEST_F(MasterTest, MasterInfo)
driver.start();
AWAIT_UNTIL(masterInfo);
- EXPECT_EQ(master.port, masterInfo.get().port());
- EXPECT_EQ(master.ip, masterInfo.get().ip());
+ EXPECT_EQ(master.get().port, masterInfo.get().port());
+ EXPECT_EQ(master.get().ip, masterInfo.get().ip());
driver.stop();
driver.join();
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ cluster.shutdown();
}
@@ -932,21 +838,14 @@ TEST_F(MasterTest, MasterInfoOnReElectio
{
ASSERT_TRUE(GTEST_IS_THREADSAFE);
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
+ Try<PID<Master> > master = cluster.masters.start();
+ ASSERT_SOME(master);
- TestingIsolator isolator;
-
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
-
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = cluster.slaves.start();
+ 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);
@@ -966,7 +865,7 @@ TEST_F(MasterTest, MasterInfoOnReElectio
// 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());
Future<MasterInfo> masterInfo;
EXPECT_CALL(sched, reregistered(&driver, _))
@@ -975,17 +874,13 @@ TEST_F(MasterTest, MasterInfoOnReElectio
process::post(message.get().to, newMasterDetectedMsg);
AWAIT_UNTIL(masterInfo);
- EXPECT_EQ(master.port, masterInfo.get().port());
- EXPECT_EQ(master.ip, masterInfo.get().ip());
+ EXPECT_EQ(master.get().port, masterInfo.get().port());
+ EXPECT_EQ(master.get().ip, masterInfo.get().ip());
driver.stop();
driver.join();
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ cluster.shutdown();
}
@@ -1014,23 +909,16 @@ TEST_F(WhitelistTest, WhitelistSlave)
string hosts = hostname.get() + "\n" + "dummy-slave";
ASSERT_SOME(os::write(path, hosts)) << "Error writing whitelist";
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- master::Flags masterFlags;
- masterFlags.whitelist = "file://" + path;
- Master m(&a, &files, masterFlags);
- PID<Master> master = process::spawn(&m);
-
- TestingIsolator isolator;
-
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
+ master::Flags flags = cluster.masters.flags;
+ flags.whitelist = "file://" + path;
+ Try<PID<Master> > master = cluster.masters.start(flags);
+ ASSERT_SOME(master);
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = cluster.slaves.start();
+ 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);
@@ -1046,11 +934,7 @@ TEST_F(WhitelistTest, WhitelistSlave)
driver.stop();
driver.join();
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ cluster.shutdown();
}
@@ -1058,21 +942,14 @@ TEST_F(MasterTest, MasterLost)
{
ASSERT_TRUE(GTEST_IS_THREADSAFE);
- HierarchicalDRFAllocatorProcess allocator;
- Allocator a(&allocator);
- Files files;
- Master m(&a, &files);
- PID<Master> master = process::spawn(&m);
-
- TestingIsolator isolator;
+ Try<PID<Master> > master = cluster.masters.start();
+ ASSERT_SOME(master);
- Slave s(slaveFlags, true, &isolator, &files);
- PID<Slave> slave = process::spawn(&s);
-
- BasicMasterDetector detector(master, slave, true);
+ Try<PID<Slave> > slave = cluster.slaves.start();
+ 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);
@@ -1094,17 +971,12 @@ TEST_F(MasterTest, MasterLost)
.WillOnce(FutureSatisfy(&disconnected));
// Simulate a spurious noMasterDetected event at the scheduler.
- NoMasterDetectedMessage noMasterDetectedMsg;
- process::post(message.get().to, noMasterDetectedMsg);
+ process::post(message.get().to, NoMasterDetectedMessage());
AWAIT_UNTIL(disconnected);
driver.stop();
driver.join();
- process::terminate(slave);
- process::wait(slave);
-
- process::terminate(master);
- process::wait(master);
+ cluster.shutdown();
}
Modified: incubator/mesos/trunk/src/tests/state_tests.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/state_tests.cpp?rev=1464756&r1=1464755&r2=1464756&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/state_tests.cpp (original)
+++ incubator/mesos/trunk/src/tests/state_tests.cpp Thu Apr 4 20:57:58 2013
@@ -47,7 +47,6 @@
using namespace mesos;
using namespace mesos::internal;
using namespace mesos::internal::state;
-using namespace mesos::internal::tests;
using namespace process;
@@ -261,7 +260,7 @@ TEST_F(LevelDBStateTest, Names)
#ifdef MESOS_HAS_JAVA
-class ZooKeeperStateTest : public ZooKeeperTest
+class ZooKeeperStateTest : public tests::ZooKeeperTest
{
public:
ZooKeeperStateTest()
Modified: incubator/mesos/trunk/src/tests/utils.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/utils.hpp?rev=1464756&r1=1464755&r2=1464756&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/utils.hpp (original)
+++ incubator/mesos/trunk/src/tests/utils.hpp Thu Apr 4 20:57:58 2013
@@ -69,7 +69,9 @@
#include "slave/slave.hpp"
#include "slave/state.hpp"
+#include "tests/cluster.hpp"
#include "tests/flags.hpp"
+#include "tests/isolator.hpp"
namespace mesos {
namespace internal {
@@ -148,6 +150,40 @@ protected:
};
+class MesosClusterTest : public ::testing::Test
+{
+protected:
+ virtual void SetUp()
+ {
+ // Create a temporary directory for the test.
+ Try<std::string> directory = 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
{};
@@ -763,145 +799,6 @@ ACTION_P(SendStatusUpdateFromTaskID, sta
#define AWAIT_UNTIL(future) \
AWAIT_FOR(future, Seconds(2))
-
-class TestingIsolator : public slave::Isolator
-{
-public:
- TestingIsolator()
- {
- setup();
- }
-
- TestingIsolator(const std::map<ExecutorID, Executor*>& _executors)
- : executors(_executors)
- {
- setup();
- }
-
- TestingIsolator(const ExecutorID& executorId, Executor* executor)
- {
- executors[executorId] = executor;
- setup();
- }
-
- virtual ~TestingIsolator() {}
-
- virtual void initialize(
- const slave::Flags& flags,
- const Resources& resources,
- bool local,
- const process::PID<slave::Slave>& _slave)
- {
- slave = _slave;
- }
-
- virtual void launchExecutor(
- const SlaveID& slaveId,
- const FrameworkID& frameworkId,
- const FrameworkInfo& frameworkInfo,
- const ExecutorInfo& executorInfo,
- const UUID& uuid,
- const std::string& directory,
- const Resources& resources,
- const Option<std::string>& path)
- {
- if (executors.count(executorInfo.executor_id()) > 0) {
- Executor* executor = executors[executorInfo.executor_id()];
- MesosExecutorDriver* driver = new MesosExecutorDriver(executor);
- drivers[executorInfo.executor_id()] = driver;
-
- directories[executorInfo.executor_id()] = directory;
-
- os::setenv("MESOS_LOCAL", "1");
- os::setenv("MESOS_DIRECTORY", directory);
- os::setenv("MESOS_SLAVE_PID", slave);
- os::setenv("MESOS_SLAVE_ID", slaveId.value());
- os::setenv("MESOS_FRAMEWORK_ID", frameworkId.value());
- os::setenv("MESOS_EXECUTOR_ID", executorInfo.executor_id().value());
- os::setenv("MESOS_CHECKPOINT", frameworkInfo.checkpoint() ? "1" : "0");
-
- driver->start();
-
- os::unsetenv("MESOS_LOCAL");
- os::unsetenv("MESOS_DIRECTORY");
- os::unsetenv("MESOS_SLAVE_PID");
- os::unsetenv("MESOS_SLAVE_ID");
- os::unsetenv("MESOS_FRAMEWORK_ID");
- os::unsetenv("MESOS_EXECUTOR_ID");
- os::unsetenv("MESOS_CHECKPOINT");
-
- process::dispatch(
- slave,
- &slave::Slave::executorStarted,
- frameworkId,
- executorInfo.executor_id(),
- -1);
-
- } else {
- FAIL() << "Cannot launch executor";
- }
- }
-
- virtual void killExecutor(
- const FrameworkID& frameworkId,
- const ExecutorID& executorId)
- {
- if (drivers.count(executorId) > 0) {
- MesosExecutorDriver* driver = drivers[executorId];
- driver->stop();
- driver->join();
- delete driver;
- drivers.erase(executorId);
-
- process::dispatch(
- slave,
- &slave::Slave::executorTerminated,
- frameworkId,
- executorId,
- 0,
- false,
- "Killed executor");
- } else {
- FAIL() << "Cannot kill executor";
- }
- }
-
- // Mocked so tests can check that the resources reflect all started tasks.
- MOCK_METHOD3(resourcesChanged, void(const FrameworkID&,
- const ExecutorID&,
- const Resources&));
-
- MOCK_METHOD2(
- usage,
- process::Future<ResourceStatistics>(
- const FrameworkID&,
- const ExecutorID&));
-
- MOCK_METHOD1(
- recover,
- process::Future<Nothing>(const Option<slave::state::SlaveState>&));
-
- std::map<ExecutorID, std::string> directories;
-
-private:
- // Helper to setup default expectations.
- void setup()
- {
- EXPECT_CALL(*this, resourcesChanged(testing::_, testing::_, testing::_))
- .Times(testing::AnyNumber());
-
- EXPECT_CALL(*this, usage(testing::_, testing::_))
- .WillRepeatedly(testing::Return(ResourceStatistics()));
-
- EXPECT_CALL(*this, recover(testing::_))
- .WillRepeatedly(testing::Return(Nothing()));
- }
-
- std::map<ExecutorID, Executor*> executors;
- std::map<ExecutorID, MesosExecutorDriver*> drivers;
- process::PID<slave::Slave> slave;
-};
-
} // namespace tests {
} // namespace internal {
} // namespace mesos {