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>