You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2015/07/25 01:38:05 UTC

[12/12] mesos git commit: Moved containerizer related tests under src/tests/containerizer.

Moved containerizer related tests under src/tests/containerizer.

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


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

Branch: refs/heads/master
Commit: 963513722ecf121cc9ec8c1d4b63922398fc0658
Parents: 50696fa
Author: Jie Yu <yu...@gmail.com>
Authored: Fri Jul 24 15:42:43 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Jul 24 16:37:23 2015 -0700

----------------------------------------------------------------------
 src/Makefile.am                                 |  174 +-
 src/tests/cgroups_isolator_tests.cpp            |   46 -
 src/tests/cgroups_tests.cpp                     | 1234 --------
 src/tests/composing_containerizer_tests.cpp     |  171 -
 .../containerizer/cgroups_isolator_tests.cpp    |   46 +
 src/tests/containerizer/cgroups_tests.cpp       | 1235 ++++++++
 .../composing_containerizer_tests.cpp           |  171 +
 src/tests/containerizer/containerizer_tests.cpp |  732 +++++
 .../docker_containerizer_tests.cpp              | 2955 ++++++++++++++++++
 src/tests/containerizer/docker_tests.cpp        |  421 +++
 .../external_containerizer_test.cpp             |  267 ++
 src/tests/containerizer/fs_tests.cpp            |  170 +
 src/tests/containerizer/isolator.hpp            |  101 +
 src/tests/containerizer/isolator_tests.cpp      | 1317 ++++++++
 src/tests/containerizer/launch_tests.cpp        |  238 ++
 src/tests/containerizer/launcher.hpp            |  119 +
 .../containerizer/memory_pressure_tests.cpp     |  293 ++
 src/tests/containerizer/memory_test_helper.cpp  |  321 ++
 src/tests/containerizer/memory_test_helper.hpp  |   89 +
 .../containerizer/memory_test_helper_main.cpp   |   32 +
 src/tests/containerizer/ns_tests.cpp            |  302 ++
 src/tests/containerizer/perf_tests.cpp          |  183 ++
 src/tests/containerizer/port_mapping_tests.cpp  | 2296 ++++++++++++++
 src/tests/containerizer/routing_tests.cpp       | 1416 +++++++++
 src/tests/containerizer/sched_tests.cpp         |   96 +
 src/tests/containerizer/setns_test_helper.cpp   |   63 +
 src/tests/containerizer/setns_test_helper.hpp   |   35 +
 .../containerizer/setns_test_helper_main.cpp    |   30 +
 src/tests/containerizer_tests.cpp               |  731 -----
 src/tests/docker_containerizer_tests.cpp        | 2955 ------------------
 src/tests/docker_tests.cpp                      |  421 ---
 src/tests/external_containerizer_test.cpp       |  266 --
 src/tests/fs_tests.cpp                          |  170 -
 src/tests/isolator.hpp                          |  101 -
 src/tests/isolator_tests.cpp                    | 1316 --------
 src/tests/launch_tests.cpp                      |  238 --
 src/tests/launcher.hpp                          |  119 -
 src/tests/memory_pressure_tests.cpp             |  293 --
 src/tests/memory_test_helper.cpp                |  320 --
 src/tests/memory_test_helper.hpp                |   89 -
 src/tests/memory_test_helper_main.cpp           |   32 -
 src/tests/ns_tests.cpp                          |  301 --
 src/tests/perf_tests.cpp                        |  183 --
 src/tests/port_mapping_tests.cpp                | 2296 --------------
 src/tests/routing_tests.cpp                     | 1416 ---------
 src/tests/sched_tests.cpp                       |   96 -
 src/tests/setns_test_helper.cpp                 |   63 -
 src/tests/setns_test_helper.hpp                 |   35 -
 src/tests/setns_test_helper_main.cpp            |   30 -
 49 files changed, 13015 insertions(+), 13009 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/96351372/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 93a6a7a..a7104bb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -658,17 +658,17 @@ libmesos_no_3rdparty_la_SOURCES +=					\
 	tests/containerizer.hpp						\
 	tests/environment.hpp						\
 	tests/flags.hpp							\
-	tests/isolator.hpp						\
-	tests/launcher.hpp						\
 	tests/limiter.hpp						\
-	tests/memory_test_helper.hpp					\
 	tests/mesos.hpp							\
 	tests/module.hpp						\
 	tests/script.hpp						\
-	tests/setns_test_helper.hpp					\
 	tests/utils.hpp							\
 	tests/zookeeper.hpp						\
 	tests/zookeeper_test_server.hpp					\
+	tests/containerizer/isolator.hpp				\
+	tests/containerizer/launcher.hpp				\
+	tests/containerizer/memory_test_helper.hpp			\
+	tests/containerizer/setns_test_helper.hpp			\
 	usage/usage.hpp							\
 	watcher/whitelist_watcher.hpp					\
 	zookeeper/authentication.hpp					\
@@ -1383,8 +1383,8 @@ persistent_volume_framework_LDADD = libmesos.la $(LDADD)
 if OS_LINUX
   check_PROGRAMS += setns-test-helper
   setns_test_helper_SOURCES =					\
-    tests/setns_test_helper_main.cpp				\
-    tests/setns_test_helper.cpp
+    tests/containerizer/setns_test_helper_main.cpp		\
+    tests/containerizer/setns_test_helper.cpp
   setns_test_helper_CPPFLAGS = $(MESOS_CPPFLAGS)
   setns_test_helper_LDADD = libmesos.la $(LDADD)
 
@@ -1393,8 +1393,8 @@ endif
 check_PROGRAMS += memory-test-helper
 memory_test_helper_SOURCES =					\
   tests/flags.cpp						\
-  tests/memory_test_helper_main.cpp				\
-  tests/memory_test_helper.cpp
+  tests/containerizer/memory_test_helper_main.cpp		\
+  tests/containerizer/memory_test_helper.cpp
 memory_test_helper_CPPFLAGS = $(mesos_tests_CPPFLAGS)
 memory_test_helper_LDADD = libmesos.la $(LDADD)
 
@@ -1474,74 +1474,74 @@ libtestqos_controller_la_SOURCES =		\
 libtestqos_controller_la_CPPFLAGS = $(MESOS_CPPFLAGS)
 libtestqos_controller_la_LDFLAGS = $(MESOS_TEST_MODULE_LDFLAGS)
 
-mesos_tests_SOURCES =				\
-  tests/anonymous_tests.cpp			\
-  tests/attributes_tests.cpp			\
-  tests/authentication_tests.cpp		\
-  tests/authorization_tests.cpp		        \
-  tests/common/http_tests.cpp			\
-  tests/composing_containerizer_tests.cpp       \
-  tests/containerizer.cpp			\
-  tests/containerizer_tests.cpp			\
-  tests/cram_md5_authentication_tests.cpp	\
-  tests/credentials_tests.cpp			\
-  tests/disk_quota_tests.cpp			\
-  tests/docker_containerizer_tests.cpp          \
-  tests/docker_tests.cpp			\
-  tests/environment.cpp				\
-  tests/examples_tests.cpp			\
-  tests/exception_tests.cpp			\
-  tests/external_containerizer_test.cpp		\
-  tests/health_check_tests.cpp                  \
-  tests/fault_tolerance_tests.cpp		\
-  tests/fetcher_cache_tests.cpp			\
-  tests/fetcher_tests.cpp                       \
-  tests/files_tests.cpp				\
-  tests/flags.cpp				\
-  tests/gc_tests.cpp				\
-  tests/hierarchical_allocator_tests.cpp	\
-  tests/hook_tests.cpp				\
-  tests/http_api_tests.cpp			\
-  tests/isolator_tests.cpp			\
-  tests/log_tests.cpp				\
-  tests/logging_tests.cpp			\
-  tests/main.cpp				\
-  tests/master_allocator_tests.cpp		\
-  tests/master_authorization_tests.cpp		\
-  tests/master_contender_detector_tests.cpp	\
-  tests/master_slave_reconciliation_tests.cpp	\
-  tests/master_tests.cpp			\
-  tests/master_validation_tests.cpp		\
-  tests/memory_test_helper.cpp			\
-  tests/mesos.cpp				\
-  tests/metrics_tests.cpp			\
-  tests/module.cpp				\
-  tests/module_tests.cpp			\
-  tests/monitor_tests.cpp			\
-  tests/oversubscription_tests.cpp		\
-  tests/partition_tests.cpp			\
-  tests/paths_tests.cpp				\
-  tests/persistent_volume_tests.cpp		\
-  tests/protobuf_io_tests.cpp			\
-  tests/rate_limiting_tests.cpp			\
-  tests/reconciliation_tests.cpp		\
-  tests/registrar_tests.cpp			\
-  tests/repair_tests.cpp			\
-  tests/reservation_tests.cpp			\
-  tests/resource_offers_tests.cpp		\
-  tests/resources_tests.cpp			\
-  tests/scheduler_tests.cpp			\
-  tests/scheduler_event_call_tests.cpp		\
-  tests/script.cpp				\
-  tests/slave_recovery_tests.cpp		\
-  tests/slave_tests.cpp				\
-  tests/sorter_tests.cpp			\
-  tests/state_tests.cpp				\
-  tests/status_update_manager_tests.cpp		\
-  tests/teardown_tests.cpp			\
-  tests/utils.cpp				\
-  tests/values_tests.cpp			\
-  tests/zookeeper_url_tests.cpp
+mesos_tests_SOURCES =						\
+  tests/anonymous_tests.cpp					\
+  tests/attributes_tests.cpp					\
+  tests/authentication_tests.cpp				\
+  tests/authorization_tests.cpp					\
+  tests/containerizer.cpp					\
+  tests/cram_md5_authentication_tests.cpp			\
+  tests/credentials_tests.cpp					\
+  tests/disk_quota_tests.cpp					\
+  tests/environment.cpp						\
+  tests/examples_tests.cpp					\
+  tests/exception_tests.cpp					\
+  tests/health_check_tests.cpp					\
+  tests/fault_tolerance_tests.cpp				\
+  tests/fetcher_cache_tests.cpp					\
+  tests/fetcher_tests.cpp					\
+  tests/files_tests.cpp						\
+  tests/flags.cpp						\
+  tests/gc_tests.cpp						\
+  tests/hierarchical_allocator_tests.cpp			\
+  tests/hook_tests.cpp						\
+  tests/http_api_tests.cpp					\
+  tests/log_tests.cpp						\
+  tests/logging_tests.cpp					\
+  tests/main.cpp						\
+  tests/master_allocator_tests.cpp				\
+  tests/master_authorization_tests.cpp				\
+  tests/master_contender_detector_tests.cpp			\
+  tests/master_slave_reconciliation_tests.cpp			\
+  tests/master_tests.cpp					\
+  tests/master_validation_tests.cpp				\
+  tests/mesos.cpp						\
+  tests/metrics_tests.cpp					\
+  tests/module.cpp						\
+  tests/module_tests.cpp					\
+  tests/monitor_tests.cpp					\
+  tests/oversubscription_tests.cpp				\
+  tests/partition_tests.cpp					\
+  tests/paths_tests.cpp						\
+  tests/persistent_volume_tests.cpp				\
+  tests/protobuf_io_tests.cpp					\
+  tests/rate_limiting_tests.cpp					\
+  tests/reconciliation_tests.cpp				\
+  tests/registrar_tests.cpp					\
+  tests/repair_tests.cpp					\
+  tests/reservation_tests.cpp					\
+  tests/resource_offers_tests.cpp				\
+  tests/resources_tests.cpp					\
+  tests/scheduler_tests.cpp					\
+  tests/scheduler_event_call_tests.cpp				\
+  tests/script.cpp						\
+  tests/slave_recovery_tests.cpp				\
+  tests/slave_tests.cpp						\
+  tests/sorter_tests.cpp					\
+  tests/state_tests.cpp						\
+  tests/status_update_manager_tests.cpp				\
+  tests/teardown_tests.cpp					\
+  tests/utils.cpp						\
+  tests/values_tests.cpp					\
+  tests/zookeeper_url_tests.cpp					\
+  tests/common/http_tests.cpp					\
+  tests/containerizer/composing_containerizer_tests.cpp		\
+  tests/containerizer/containerizer_tests.cpp			\
+  tests/containerizer/docker_containerizer_tests.cpp		\
+  tests/containerizer/docker_tests.cpp				\
+  tests/containerizer/external_containerizer_test.cpp		\
+  tests/containerizer/isolator_tests.cpp			\
+  tests/containerizer/memory_test_helper.cpp
 
 mesos_tests_CPPFLAGS = $(MESOS_CPPFLAGS)
 mesos_tests_CPPFLAGS += -DSOURCE_DIR=\"$(abs_top_srcdir)\"
@@ -1554,20 +1554,20 @@ mesos_tests_LDADD = ../$(LIBPROCESS)/3rdparty/libgmock.la libmesos.la -ldl $(LDA
 mesos_tests_DEPENDENCIES = # Initialized to allow += below.
 
 if OS_LINUX
-  mesos_tests_SOURCES += tests/cgroups_isolator_tests.cpp
-  mesos_tests_SOURCES += tests/cgroups_tests.cpp
-  mesos_tests_SOURCES += tests/fs_tests.cpp
-  mesos_tests_SOURCES += tests/launch_tests.cpp
-  mesos_tests_SOURCES += tests/memory_pressure_tests.cpp
-  mesos_tests_SOURCES += tests/ns_tests.cpp
-  mesos_tests_SOURCES += tests/perf_tests.cpp
-  mesos_tests_SOURCES += tests/sched_tests.cpp
-  mesos_tests_SOURCES += tests/setns_test_helper.cpp
+  mesos_tests_SOURCES += tests/containerizer/cgroups_isolator_tests.cpp
+  mesos_tests_SOURCES += tests/containerizer/cgroups_tests.cpp
+  mesos_tests_SOURCES += tests/containerizer/fs_tests.cpp
+  mesos_tests_SOURCES += tests/containerizer/launch_tests.cpp
+  mesos_tests_SOURCES += tests/containerizer/memory_pressure_tests.cpp
+  mesos_tests_SOURCES += tests/containerizer/ns_tests.cpp
+  mesos_tests_SOURCES += tests/containerizer/perf_tests.cpp
+  mesos_tests_SOURCES += tests/containerizer/sched_tests.cpp
+  mesos_tests_SOURCES += tests/containerizer/setns_test_helper.cpp
 endif
 
 if WITH_NETWORK_ISOLATOR
-  mesos_tests_SOURCES += tests/routing_tests.cpp
-  mesos_tests_SOURCES += tests/port_mapping_tests.cpp
+  mesos_tests_SOURCES += tests/containerizer/routing_tests.cpp
+  mesos_tests_SOURCES += tests/containerizer/port_mapping_tests.cpp
 endif
 
 if HAS_JAVA

http://git-wip-us.apache.org/repos/asf/mesos/blob/96351372/src/tests/cgroups_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/cgroups_isolator_tests.cpp b/src/tests/cgroups_isolator_tests.cpp
deleted file mode 100644
index a4ccc8e..0000000
--- a/src/tests/cgroups_isolator_tests.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <map>
-#include <utility>
-
-#include <gtest/gtest.h>
-
-#include <stout/foreach.hpp>
-#include <stout/proc.hpp>
-#include <stout/stringify.hpp>
-
-#include "slave/containerizer/mesos/containerizer.hpp"
-
-#include "tests/script.hpp"
-
-using std::map;
-
-namespace mesos {
-namespace internal {
-namespace tests {
-
-
-// Run the balloon framework under a mesos containerizer.
-TEST_SCRIPT(ContainerizerTest,
-            ROOT_CGROUPS_BalloonFramework,
-            "balloon_framework_test.sh")
-
-} // namespace tests {
-} // namespace internal {
-} // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/96351372/src/tests/cgroups_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/cgroups_tests.cpp b/src/tests/cgroups_tests.cpp
deleted file mode 100644
index b63d956..0000000
--- a/src/tests/cgroups_tests.cpp
+++ /dev/null
@@ -1,1234 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include <sys/mman.h>
-#include <sys/ptrace.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include <gmock/gmock.h>
-
-#include <process/gtest.hpp>
-#include <process/owned.hpp>
-
-#include <stout/gtest.hpp>
-#include <stout/hashmap.hpp>
-#include <stout/numify.hpp>
-#include <stout/option.hpp>
-#include <stout/os.hpp>
-#include <stout/path.hpp>
-#include <stout/proc.hpp>
-#include <stout/stringify.hpp>
-#include <stout/strings.hpp>
-
-#include "linux/cgroups.hpp"
-#include "linux/perf.hpp"
-
-#include "tests/memory_test_helper.hpp"
-#include "tests/mesos.hpp" // For TEST_CGROUPS_(HIERARCHY|ROOT).
-#include "tests/utils.hpp"
-
-using namespace process;
-
-using cgroups::memory::pressure::Level;
-using cgroups::memory::pressure::Counter;
-
-using std::set;
-
-namespace mesos {
-namespace internal {
-namespace tests {
-
-
-class CgroupsTest : public TemporaryDirectoryTest
-{
-public:
-  static void SetUpTestCase()
-  {
-    // Clean up the testing hierarchy, in case it wasn't cleaned up
-    // properly from previous tests.
-    AWAIT_READY(cgroups::cleanup(TEST_CGROUPS_HIERARCHY));
-  }
-
-  static void TearDownTestCase()
-  {
-    AWAIT_READY(cgroups::cleanup(TEST_CGROUPS_HIERARCHY));
-  }
-};
-
-
-// A fixture which is used to name tests that expect NO hierarchy to
-// exist in order to test the ability to create a hierarchy (since
-// most likely existing hierarchies will have all or most subsystems
-// attached rendering our ability to create a hierarchy fruitless).
-class CgroupsNoHierarchyTest : public CgroupsTest
-{
-public:
-  static void SetUpTestCase()
-  {
-    CgroupsTest::SetUpTestCase();
-
-    Try<std::set<std::string> > hierarchies = cgroups::hierarchies();
-    ASSERT_SOME(hierarchies);
-    ASSERT_TRUE(hierarchies.get().empty())
-      << "-------------------------------------------------------------\n"
-      << "We cannot run any cgroups tests that require mounting\n"
-      << "hierarchies because you have the following hierarchies mounted:\n"
-      << strings::trim(stringify(hierarchies.get()), " {},") << "\n"
-      << "You can either unmount those hierarchies, or disable\n"
-      << "this test case (i.e., --gtest_filter=-CgroupsNoHierarchyTest.*).\n"
-      << "-------------------------------------------------------------";
-  }
-};
-
-
-// A fixture that assumes ANY hierarchy is acceptable for use provided
-// it has the subsystems attached that were specified in the
-// constructor. If no hierarchy could be found that has all the
-// required subsystems then we attempt to create a new hierarchy.
-class CgroupsAnyHierarchyTest : public CgroupsTest
-{
-public:
-  CgroupsAnyHierarchyTest(const std::string& _subsystems = "cpu")
-    : subsystems(_subsystems) {}
-
-protected:
-  virtual void SetUp()
-  {
-    CgroupsTest::SetUp();
-
-    foreach (const std::string& subsystem, strings::tokenize(subsystems, ",")) {
-      // Establish the base hierarchy if this is the first subsystem checked.
-      if (baseHierarchy.empty()) {
-        Result<std::string> hierarchy = cgroups::hierarchy(subsystem);
-        ASSERT_FALSE(hierarchy.isError());
-
-        if (hierarchy.isNone()) {
-          baseHierarchy = TEST_CGROUPS_HIERARCHY;
-        } else {
-          // Strip the subsystem to get the base hierarchy.
-          Try<std::string> baseDirname = Path(hierarchy.get()).dirname();
-          ASSERT_SOME(baseDirname);
-          baseHierarchy = baseDirname.get();
-        }
-      }
-
-      // Mount the subsystem if necessary.
-      std::string hierarchy = path::join(baseHierarchy, subsystem);
-      Try<bool> mounted = cgroups::mounted(hierarchy, subsystem);
-      ASSERT_SOME(mounted);
-      if (!mounted.get()) {
-        ASSERT_SOME(cgroups::mount(hierarchy, subsystem))
-          << "-------------------------------------------------------------\n"
-          << "We cannot run any cgroups tests that require\n"
-          << "a hierarchy with subsystem '" << subsystem << "'\n"
-          << "because we failed to find an existing hierarchy\n"
-          << "or create a new one (tried '" << hierarchy << "').\n"
-          << "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"
-          << "-------------------------------------------------------------";
-      }
-
-      Try<std::vector<std::string> > cgroups = cgroups::get(hierarchy);
-      CHECK_SOME(cgroups);
-
-      foreach (const std::string& cgroup, cgroups.get()) {
-        // Remove any cgroups that start with TEST_CGROUPS_ROOT.
-        if (cgroup == TEST_CGROUPS_ROOT) {
-          AWAIT_READY(cgroups::destroy(hierarchy, cgroup));
-        }
-      }
-    }
-  }
-
-  virtual void TearDown()
-  {
-    // Remove all *our* cgroups.
-    foreach (const std::string& subsystem, strings::tokenize(subsystems, ",")) {
-      std::string hierarchy = path::join(baseHierarchy, subsystem);
-
-      Try<std::vector<std::string> > cgroups = cgroups::get(hierarchy);
-      CHECK_SOME(cgroups);
-
-      foreach (const std::string& cgroup, cgroups.get()) {
-        // Remove any cgroups that start with TEST_CGROUPS_ROOT.
-        if (cgroup == TEST_CGROUPS_ROOT) {
-          AWAIT_READY(cgroups::destroy(hierarchy, cgroup));
-        }
-      }
-    }
-
-    CgroupsTest::TearDown();
-  }
-
-  const std::string subsystems; // Subsystems required to run tests.
-  std::string baseHierarchy; // Path to the hierarchy being used.
-};
-
-
-class CgroupsAnyHierarchyWithCpuMemoryTest
-  : public CgroupsAnyHierarchyTest
-{
-public:
-  CgroupsAnyHierarchyWithCpuMemoryTest()
-    : CgroupsAnyHierarchyTest("cpu,memory") {}
-};
-
-
-class CgroupsAnyHierarchyWithFreezerTest
-  : public CgroupsAnyHierarchyTest
-{
-public:
-  CgroupsAnyHierarchyWithFreezerTest()
-    : CgroupsAnyHierarchyTest("freezer") {}
-};
-
-
-TEST_F(CgroupsAnyHierarchyTest, ROOT_CGROUPS_Enabled)
-{
-  EXPECT_SOME_TRUE(cgroups::enabled(""));
-  EXPECT_SOME_TRUE(cgroups::enabled(","));
-  EXPECT_SOME_TRUE(cgroups::enabled("cpu"));
-  EXPECT_SOME_TRUE(cgroups::enabled(",cpu"));
-  EXPECT_SOME_TRUE(cgroups::enabled("cpu,memory"));
-  EXPECT_SOME_TRUE(cgroups::enabled("cpu,memory,"));
-  EXPECT_ERROR(cgroups::enabled("invalid"));
-  EXPECT_ERROR(cgroups::enabled("cpu,invalid"));
-}
-
-
-TEST_F(CgroupsAnyHierarchyWithCpuMemoryTest, ROOT_CGROUPS_Busy)
-{
-  EXPECT_SOME_FALSE(cgroups::busy(""));
-  EXPECT_SOME_FALSE(cgroups::busy(","));
-  EXPECT_SOME_TRUE(cgroups::busy("cpu"));
-  EXPECT_SOME_TRUE(cgroups::busy(",cpu"));
-  EXPECT_SOME_TRUE(cgroups::busy("cpu,memory"));
-  EXPECT_SOME_TRUE(cgroups::busy("cpu,memory,"));
-  EXPECT_ERROR(cgroups::busy("invalid"));
-  EXPECT_ERROR(cgroups::busy("cpu,invalid"));
-}
-
-
-TEST_F(CgroupsAnyHierarchyTest, ROOT_CGROUPS_Subsystems)
-{
-  Try<std::set<std::string> > names = cgroups::subsystems();
-  ASSERT_SOME(names);
-
-  Option<std::string> cpu;
-  Option<std::string> memory;
-  foreach (const std::string& name, names.get()) {
-    if (name == "cpu") {
-      cpu = name;
-    } else if (name == "memory") {
-      memory = name;
-    }
-  }
-
-  EXPECT_SOME(cpu);
-  EXPECT_SOME(memory);
-}
-
-
-TEST_F(CgroupsAnyHierarchyWithCpuMemoryTest, ROOT_CGROUPS_SubsystemsHierarchy)
-{
-  std::string cpuHierarchy = path::join(baseHierarchy, "cpu");
-
-  Try<std::set<std::string> > names = cgroups::subsystems(cpuHierarchy);
-  ASSERT_SOME(names);
-
-  Option<std::string> cpu;
-  Option<std::string> memory;
-  foreach (const std::string& name, names.get()) {
-    if (name == "cpu") {
-      cpu = name;
-    } else if (name == "memory") {
-      memory = name;
-    }
-  }
-
-  EXPECT_SOME(cpu);
-  EXPECT_NONE(memory);
-
-  std::string memoryHierarchy = path::join(baseHierarchy, "memory");
-  names = cgroups::subsystems(memoryHierarchy);
-  ASSERT_SOME(names);
-
-  cpu = None();
-  memory = None();
-  foreach (const std::string& name, names.get()) {
-    if (name == "cpu") {
-      cpu = name;
-    } else if (name == "memory") {
-      memory = name;
-    }
-  }
-  EXPECT_NONE(cpu);
-  EXPECT_SOME(memory);
-}
-
-
-TEST_F(CgroupsAnyHierarchyWithCpuMemoryTest, ROOT_CGROUPS_FindCgroupSubsystems)
-{
-  pid_t pid = ::getpid();
-  Result<std::string> cpuHierarchy = cgroups::cpu::cgroup(pid);
-  EXPECT_FALSE(cpuHierarchy.isError());
-  EXPECT_SOME(cpuHierarchy);
-
-  Result<std::string> memHierarchy = cgroups::memory::cgroup(pid);
-  EXPECT_FALSE(memHierarchy.isError());
-  EXPECT_SOME(memHierarchy);
-}
-
-
-TEST_F(CgroupsNoHierarchyTest, ROOT_CGROUPS_NOHIERARCHY_MountUnmountHierarchy)
-{
-  EXPECT_ERROR(cgroups::mount("/tmp", "cpu"));
-  EXPECT_ERROR(cgroups::mount(TEST_CGROUPS_HIERARCHY, "invalid"));
-
-  // Try to mount a valid hierarchy, retrying as necessary since the
-  // previous unmount might not have taken effect yet due to a bug in
-  // Ubuntu 12.04.
-  ASSERT_SOME(cgroups::mount(TEST_CGROUPS_HIERARCHY, "cpu,memory", 10));
-  EXPECT_ERROR(cgroups::mount(TEST_CGROUPS_HIERARCHY, "cpuset"));
-  EXPECT_ERROR(cgroups::unmount("/tmp"));
-  ASSERT_SOME(cgroups::unmount(TEST_CGROUPS_HIERARCHY));
-}
-
-
-TEST_F(CgroupsAnyHierarchyTest, ROOT_CGROUPS_Mounted)
-{
-  EXPECT_SOME_FALSE(cgroups::mounted("/tmp-nonexist"));
-  EXPECT_SOME_FALSE(cgroups::mounted("/tmp"));
-  EXPECT_SOME_FALSE(cgroups::mounted(baseHierarchy + "/not_expected"));
-  EXPECT_SOME_TRUE(cgroups::mounted(baseHierarchy + "/cpu"));
-}
-
-
-TEST_F(CgroupsAnyHierarchyWithCpuMemoryTest, ROOT_CGROUPS_MountedSubsystems)
-{
-  EXPECT_SOME_FALSE(cgroups::mounted("/tmp-nonexist", "cpu"));
-  EXPECT_SOME_FALSE(cgroups::mounted("/tmp", "cpu,memory"));
-  EXPECT_SOME_FALSE(cgroups::mounted("/tmp", "cpu"));
-  EXPECT_SOME_FALSE(cgroups::mounted("/tmp", "invalid"));
-  EXPECT_SOME_TRUE(cgroups::mounted(path::join(baseHierarchy, "cpu"), "cpu"));
-  EXPECT_SOME_TRUE(cgroups::mounted(
-        path::join(baseHierarchy, "memory"), "memory"));
-  EXPECT_SOME_FALSE(cgroups::mounted(baseHierarchy, "invalid"));
-  EXPECT_SOME_FALSE(cgroups::mounted(baseHierarchy + "/not_expected", "cpu"));
-}
-
-
-TEST_F(CgroupsAnyHierarchyWithCpuMemoryTest, ROOT_CGROUPS_CreateRemove)
-{
-  EXPECT_ERROR(cgroups::create("/tmp", "test"));
-  EXPECT_ERROR(cgroups::create(baseHierarchy, "mesos_test_missing/1"));
-  ASSERT_SOME(cgroups::create(
-        path::join(baseHierarchy, "cpu"), "mesos_test_missing"));
-  EXPECT_ERROR(cgroups::remove(baseHierarchy, "invalid"));
-  ASSERT_SOME(cgroups::remove(
-        path::join(baseHierarchy, "cpu"), "mesos_test_missing"));
-}
-
-
-TEST_F(CgroupsAnyHierarchyTest, ROOT_CGROUPS_Get)
-{
-  std::string hierarchy = path::join(baseHierarchy, "cpu");
-
-  ASSERT_SOME(cgroups::create(hierarchy, "mesos_test1"));
-  ASSERT_SOME(cgroups::create(hierarchy, "mesos_test2"));
-
-  Try<std::vector<std::string>> cgroups = cgroups::get(hierarchy);
-  ASSERT_SOME(cgroups);
-
-  EXPECT_NE(cgroups.get().end(),
-            find(cgroups.get().begin(), cgroups.get().end(), "mesos_test2"));
-  EXPECT_NE(cgroups.get().end(),
-            find(cgroups.get().begin(), cgroups.get().end(), "mesos_test1"));
-
-  ASSERT_SOME(cgroups::remove(hierarchy, "mesos_test1"));
-  ASSERT_SOME(cgroups::remove(hierarchy, "mesos_test2"));
-}
-
-
-TEST_F(CgroupsAnyHierarchyTest, ROOT_CGROUPS_NestedCgroups)
-{
-  std::string hierarchy = path::join(baseHierarchy, "cpu");
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-  std::string cgroup1 = path::join(TEST_CGROUPS_ROOT, "1");
-  std::string cgroup2 = path::join(TEST_CGROUPS_ROOT, "2");
-
-  ASSERT_SOME(cgroups::create(hierarchy, cgroup1))
-    << "-------------------------------------------------------------\n"
-    << "We cannot run this test because it appears you do not have\n"
-    << "a modern enough version of the Linux kernel. You won't be\n"
-    << "able to use the cgroups isolator, but feel free to disable\n"
-    << "this test.\n"
-    << "-------------------------------------------------------------";
-
-  ASSERT_SOME(cgroups::create(hierarchy, cgroup2));
-
-  Try<std::vector<std::string>> cgroups =
-    cgroups::get(hierarchy, TEST_CGROUPS_ROOT);
-  ASSERT_SOME(cgroups);
-
-  ASSERT_EQ(2u, cgroups.get().size());
-
-  EXPECT_NE(cgroups.get().end(),
-            find(cgroups.get().begin(), cgroups.get().end(), cgroup2));
-  EXPECT_NE(cgroups.get().end(),
-            find(cgroups.get().begin(), cgroups.get().end(), cgroup1));
-
-  ASSERT_SOME(cgroups::remove(hierarchy, cgroup1));
-  ASSERT_SOME(cgroups::remove(hierarchy, cgroup2));
-}
-
-
-TEST_F(CgroupsAnyHierarchyTest, ROOT_CGROUPS_Tasks)
-{
-  pid_t pid = ::getpid();
-
-  Result<std::string> cgroup = cgroups::cpu::cgroup(pid);
-  ASSERT_SOME(cgroup);
-
-  std::string hierarchy = path::join(baseHierarchy, "cpu");
-
-  Try<std::set<pid_t>> pids = cgroups::processes(hierarchy, cgroup.get());
-  ASSERT_SOME(pids);
-
-  EXPECT_NE(0u, pids.get().count(pid));
-}
-
-
-TEST_F(CgroupsAnyHierarchyTest, ROOT_CGROUPS_Read)
-{
-  std::string hierarchy = path::join(baseHierarchy, "cpu");
-
-  EXPECT_ERROR(cgroups::read(hierarchy, TEST_CGROUPS_ROOT, "invalid42"));
-
-  pid_t pid = ::getpid();
-
-  Result<std::string> cgroup = cgroups::cpu::cgroup(pid);
-  ASSERT_SOME(cgroup);
-
-  Try<std::string> read = cgroups::read(hierarchy, cgroup.get(), "tasks");
-  ASSERT_SOME(read);
-
-  EXPECT_TRUE(strings::contains(read.get(), stringify(pid)));
-}
-
-
-TEST_F(CgroupsAnyHierarchyTest, ROOT_CGROUPS_Write)
-{
-  std::string hierarchy = path::join(baseHierarchy, "cpu");
-  EXPECT_ERROR(
-      cgroups::write(hierarchy, TEST_CGROUPS_ROOT, "invalid", "invalid"));
-
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-
-  pid_t pid = ::fork();
-  ASSERT_NE(-1, pid);
-
-  if (pid == 0) {
-    // In child process, wait for kill signal.
-    while (true) { sleep(1); }
-
-    // Should not reach here.
-    const char* message = "Error, child should be killed before reaching here";
-    while (write(STDERR_FILENO, message, strlen(message)) == -1 &&
-           errno == EINTR);
-
-    _exit(1);
-  }
-
-  // In parent process.
-  ASSERT_SOME(
-      cgroups::write(hierarchy,
-                     TEST_CGROUPS_ROOT,
-                     "cgroup.procs",
-                     stringify(pid)));
-
-  Try<std::set<pid_t> > pids = cgroups::processes(hierarchy, TEST_CGROUPS_ROOT);
-  ASSERT_SOME(pids);
-
-  EXPECT_NE(0u, pids.get().count(pid));
-
-  // Kill the child process.
-  ASSERT_NE(-1, ::kill(pid, SIGKILL));
-
-  // Wait for the child process.
-  int status;
-  EXPECT_NE(-1, ::waitpid((pid_t) -1, &status, 0));
-  ASSERT_TRUE(WIFSIGNALED(status));
-  EXPECT_EQ(SIGKILL, WTERMSIG(status));
-}
-
-
-TEST_F(CgroupsAnyHierarchyTest, ROOT_CGROUPS_Cfs_Big_Quota)
-{
-  std::string hierarchy = path::join(baseHierarchy, "cpu");
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-
-  Duration quota = Seconds(100); // Big quota.
-  ASSERT_SOME(cgroups::cpu::cfs_quota_us(hierarchy, TEST_CGROUPS_ROOT, quota));
-
-  // Ensure we can read back the correct quota.
-  ASSERT_SOME_EQ(
-      quota,
-      cgroups::cpu::cfs_quota_us(hierarchy, TEST_CGROUPS_ROOT));
-}
-
-
-class CgroupsAnyHierarchyWithCpuAcctMemoryTest
-  : public CgroupsAnyHierarchyTest
-{
-public:
-  CgroupsAnyHierarchyWithCpuAcctMemoryTest()
-    : CgroupsAnyHierarchyTest("cpuacct,memory") {}
-};
-
-
-TEST_F(CgroupsAnyHierarchyWithCpuAcctMemoryTest, ROOT_CGROUPS_Stat)
-{
-  EXPECT_ERROR(cgroups::stat(baseHierarchy, TEST_CGROUPS_ROOT, "invalid"));
-
-  Try<hashmap<std::string, uint64_t> > result =
-    cgroups::stat(
-        path::join(baseHierarchy, "cpuacct"), "/", "cpuacct.stat");
-  ASSERT_SOME(result);
-  EXPECT_TRUE(result.get().contains("user"));
-  EXPECT_TRUE(result.get().contains("system"));
-  EXPECT_GT(result.get().get("user").get(), 0llu);
-  EXPECT_GT(result.get().get("system").get(), 0llu);
-
-  result = cgroups::stat(
-      path::join(baseHierarchy, "memory"), "/", "memory.stat");
-  ASSERT_SOME(result);
-  EXPECT_TRUE(result.get().contains("rss"));
-  EXPECT_GT(result.get().get("rss").get(), 0llu);
-}
-
-
-TEST_F(CgroupsAnyHierarchyWithCpuMemoryTest, ROOT_CGROUPS_Listen)
-{
-  std::string hierarchy = path::join(baseHierarchy, "memory");
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-  ASSERT_SOME(
-      cgroups::memory::oom::killer::enabled(hierarchy, TEST_CGROUPS_ROOT))
-    << "-------------------------------------------------------------\n"
-    << "We cannot run this test because it appears you do not have\n"
-    << "a modern enough version of the Linux kernel. You won't be\n"
-    << "able to use the cgroups isolator, but feel free to disable\n"
-    << "this test.\n"
-    << "-------------------------------------------------------------";
-
-  const Bytes limit =  Megabytes(64);
-
-  ASSERT_SOME(cgroups::memory::limit_in_bytes(
-      hierarchy, TEST_CGROUPS_ROOT, limit));
-
-  // Listen on oom events for test cgroup.
-  Future<Nothing> future =
-    cgroups::memory::oom::listen(hierarchy, TEST_CGROUPS_ROOT);
-
-  ASSERT_FALSE(future.isFailed());
-
-  // Test the cancellation.
-  future.discard();
-
-  // Test the normal operation below.
-  future = cgroups::memory::oom::listen(hierarchy, TEST_CGROUPS_ROOT);
-  ASSERT_FALSE(future.isFailed());
-
-  MemoryTestHelper helper;
-  ASSERT_SOME(helper.spawn());
-  ASSERT_SOME(helper.pid());
-
-  EXPECT_SOME(cgroups::assign(
-      hierarchy, TEST_CGROUPS_ROOT, helper.pid().get()));
-
-  // Request more RSS memory in the subprocess than the limit.
-  // NOTE: We enable the kernel oom killer in this test. If it were
-  // disabled, the subprocess might hang and the following call won't
-  // return. By enabling the oom killer, we let the subprocess get
-  // killed and expect that an error is returned.
-  EXPECT_ERROR(helper.increaseRSS(limit * 2));
-
-  AWAIT_READY(future);
-}
-
-
-TEST_F(CgroupsAnyHierarchyWithFreezerTest, ROOT_CGROUPS_Freeze)
-{
-  int pipes[2];
-  int dummy;
-  ASSERT_NE(-1, ::pipe(pipes));
-
-  std::string hierarchy = path::join(baseHierarchy, "freezer");
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-
-  pid_t pid = ::fork();
-  ASSERT_NE(-1, pid);
-
-  if (pid == 0) {
-    // In child process.
-    ::close(pipes[0]);
-
-    // Put self into the test cgroup.
-    Try<Nothing> assign =
-      cgroups::assign(hierarchy, TEST_CGROUPS_ROOT, ::getpid());
-
-    if (assign.isError()) {
-      std::cerr << "Failed to assign cgroup: " << assign.error() << std::endl;
-      abort();
-    }
-
-    // Notify the parent.
-    if (::write(pipes[1], &dummy, sizeof(dummy)) != sizeof(dummy)) {
-      perror("Failed to notify the parent");
-      abort();
-    }
-    ::close(pipes[1]);
-
-    // Infinite loop here.
-    while (true);
-
-    // Should not reach here.
-    std::cerr << "Reach an unreachable statement!" << std::endl;
-    abort();
-  }
-
-  // In parent process.
-  ::close(pipes[1]);
-
-  // Wait until child has assigned the cgroup.
-  ASSERT_LT(0, ::read(pipes[0], &dummy, sizeof(dummy)));
-  ::close(pipes[0]);
-
-  // Freeze the test cgroup.
-  AWAIT_EXPECT_READY(cgroups::freezer::freeze(hierarchy, TEST_CGROUPS_ROOT));
-
-  // Thaw the test cgroup.
-  AWAIT_EXPECT_READY(cgroups::freezer::thaw(hierarchy, TEST_CGROUPS_ROOT));
-
-  // Kill the child process.
-  ASSERT_NE(-1, ::kill(pid, SIGKILL));
-
-  // Wait for the child process.
-  int status;
-  EXPECT_NE(-1, ::waitpid((pid_t) -1, &status, 0));
-  ASSERT_TRUE(WIFSIGNALED(status));
-  EXPECT_EQ(SIGKILL, WTERMSIG(status));
-}
-
-
-TEST_F(CgroupsAnyHierarchyWithCpuMemoryTest, ROOT_CGROUPS_FreezeNonFreezer)
-{
-  std::string hierarchy = path::join(baseHierarchy, "cpu");
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-
-  AWAIT_EXPECT_FAILED(cgroups::freezer::freeze(hierarchy, TEST_CGROUPS_ROOT));
-  AWAIT_EXPECT_FAILED(cgroups::freezer::thaw(hierarchy, TEST_CGROUPS_ROOT));
-
-  // The cgroup is empty so we should still be able to destroy it.
-  AWAIT_READY(cgroups::destroy(hierarchy, TEST_CGROUPS_ROOT));
-}
-
-
-TEST_F(CgroupsAnyHierarchyWithFreezerTest, ROOT_CGROUPS_Kill)
-{
-  int pipes[2];
-  int dummy;
-  ASSERT_NE(-1, ::pipe(pipes));
-
-  std::string hierarchy = path::join(baseHierarchy, "freezer");
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-
-  pid_t pid = ::fork();
-  ASSERT_NE(-1, pid);
-
-  if (pid > 0) {
-    // In parent process.
-    ::close(pipes[1]);
-
-    // Wait until all children have assigned the cgroup.
-    ASSERT_LT(0, ::read(pipes[0], &dummy, sizeof(dummy)));
-    ASSERT_LT(0, ::read(pipes[0], &dummy, sizeof(dummy)));
-    ASSERT_LT(0, ::read(pipes[0], &dummy, sizeof(dummy)));
-    ASSERT_LT(0, ::read(pipes[0], &dummy, sizeof(dummy)));
-    ::close(pipes[0]);
-
-    Try<Nothing> kill = cgroups::kill(hierarchy, TEST_CGROUPS_ROOT, SIGKILL);
-    EXPECT_SOME(kill);
-
-    int status;
-    EXPECT_NE(-1, ::waitpid((pid_t) -1, &status, 0));
-    ASSERT_TRUE(WIFSIGNALED(status));
-    EXPECT_EQ(SIGKILL, WTERMSIG(status));
-  } else {
-    // In child process.
-
-    // We create 4 child processes here using two forks to test the case in
-    // which there are multiple active processes in the given cgroup.
-    ::fork();
-    ::fork();
-
-    // Put self into the test cgroup.
-    Try<Nothing> assign =
-      cgroups::assign(hierarchy, TEST_CGROUPS_ROOT, ::getpid());
-
-    if (assign.isError()) {
-      std::cerr << "Failed to assign cgroup: " << assign.error() << std::endl;
-      abort();
-    }
-
-    // Notify the parent.
-    ::close(pipes[0]); // TODO(benh): Close after first fork?
-    if (::write(pipes[1], &dummy, sizeof(dummy)) != sizeof(dummy)) {
-      perror("Failed to notify the parent");
-      abort();
-    }
-    ::close(pipes[1]);
-
-    // Wait kill signal from parent.
-    while (true);
-
-    // Should not reach here.
-    std::cerr << "Reach an unreachable statement!" << std::endl;
-    abort();
-  }
-}
-
-
-// TODO(benh): Write a version of this test with nested cgroups.
-TEST_F(CgroupsAnyHierarchyWithFreezerTest, ROOT_CGROUPS_Destroy)
-{
-  int pipes[2];
-  int dummy;
-  ASSERT_NE(-1, ::pipe(pipes));
-
-  std::string hierarchy = path::join(baseHierarchy, "freezer");
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-
-  pid_t pid = ::fork();
-  ASSERT_NE(-1, pid);
-
-  if (pid > 0) {
-    // In parent process.
-    ::close(pipes[1]);
-
-    // Wait until all children have assigned the cgroup.
-    ASSERT_LT(0, ::read(pipes[0], &dummy, sizeof(dummy)));
-    ASSERT_LT(0, ::read(pipes[0], &dummy, sizeof(dummy)));
-    ASSERT_LT(0, ::read(pipes[0], &dummy, sizeof(dummy)));
-    ASSERT_LT(0, ::read(pipes[0], &dummy, sizeof(dummy)));
-    ::close(pipes[0]);
-
-    AWAIT_READY(cgroups::destroy(hierarchy, TEST_CGROUPS_ROOT));
-
-    // cgroups::destroy will reap all processes in the cgroup so we should
-    // *not* be able to reap it now.
-    int status;
-    EXPECT_EQ(-1, ::waitpid(pid, &status, 0));
-    EXPECT_EQ(ECHILD, errno);
-  } else {
-    // In child process.
-
-    // We create 4 child processes here using two forks to test the case in
-    // which there are multiple active processes in the given cgroup.
-    ::fork();
-    ::fork();
-
-    // Put self into the test cgroup.
-    Try<Nothing> assign =
-      cgroups::assign(hierarchy, TEST_CGROUPS_ROOT, ::getpid());
-
-    if (assign.isError()) {
-      std::cerr << "Failed to assign cgroup: " << assign.error() << std::endl;
-      abort();
-    }
-
-    // Notify the parent.
-    ::close(pipes[0]); // TODO(benh): Close after first fork?
-    if (::write(pipes[1], &dummy, sizeof(dummy)) != sizeof(dummy)) {
-      perror("Failed to notify the parent");
-      abort();
-    }
-    ::close(pipes[1]);
-
-    // Wait kill signal from parent.
-    while (true) {}
-
-    // Should not reach here.
-    std::cerr << "Reach an unreachable statement!" << std::endl;
-    abort();
-  }
-}
-
-
-void* threadFunction(void*)
-{
-  // Newly created threads have PTHREAD_CANCEL_ENABLE and
-  // PTHREAD_CANCEL_DEFERRED so they can be cancelled from the main thread.
-  while (true) { sleep(1); }
-
-  return NULL;
-}
-
-
-TEST_F(CgroupsAnyHierarchyWithFreezerTest, ROOT_CGROUPS_AssignThreads)
-{
-  size_t numThreads = 5;
-
-  pthread_t pthreads[numThreads];
-
-  // Create additional threads.
-  for (size_t i = 0; i < numThreads; i++)
-  {
-    EXPECT_EQ(0, pthread_create(&pthreads[i], NULL, threadFunction, NULL));
-  }
-
-  std::string hierarchy = path::join(baseHierarchy, "freezer");
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-
-  // Check the test cgroup is initially empty.
-  Try<set<pid_t> > cgroupThreads =
-    cgroups::threads(hierarchy, TEST_CGROUPS_ROOT);
-  EXPECT_SOME(cgroupThreads);
-  EXPECT_EQ(0u, cgroupThreads.get().size());
-
-  // Assign ourselves to the test cgroup.
-  CHECK_SOME(cgroups::assign(hierarchy, TEST_CGROUPS_ROOT, ::getpid()));
-
-  // Get our threads (may be more than the numThreads we created if
-  // other threads are running).
-  Try<set<pid_t> > threads = proc::threads(::getpid());
-  ASSERT_SOME(threads);
-
-  // Check the test cgroup now only contains all child threads.
-  cgroupThreads = cgroups::threads(hierarchy, TEST_CGROUPS_ROOT);
-  EXPECT_SOME(cgroupThreads);
-  EXPECT_SOME_EQ(threads.get(), cgroupThreads);
-
-  // Terminate the additional threads.
-  for (size_t i = 0; i < numThreads; i++)
-  {
-    EXPECT_EQ(0, pthread_cancel(pthreads[i]));
-    EXPECT_EQ(0, pthread_join(pthreads[i], NULL));
-  }
-
-  // Move ourselves to the root cgroup.
-  CHECK_SOME(cgroups::assign(hierarchy, "", ::getpid()));
-
-  // Destroy the cgroup.
-  AWAIT_READY(cgroups::destroy(hierarchy, TEST_CGROUPS_ROOT));
-}
-
-
-TEST_F(CgroupsAnyHierarchyWithFreezerTest, ROOT_CGROUPS_DestroyStoppedProcess)
-{
-  std::string hierarchy = path::join(baseHierarchy, "freezer");
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-
-  pid_t pid = ::fork();
-  ASSERT_NE(-1, pid);
-
-  if (pid == 0) {
-    // In child process.
-    while (true) { sleep(1); }
-
-    ABORT("Child should not reach this statement");
-  }
-
-  // In parent process.
-
-  // Put child into the freezer cgroup.
-  Try<Nothing> assign = cgroups::assign(hierarchy, TEST_CGROUPS_ROOT, pid);
-
-  // Stop the child process.
-  EXPECT_EQ(0, kill(pid, SIGSTOP));
-
-  AWAIT_READY(cgroups::destroy(hierarchy, TEST_CGROUPS_ROOT));
-
-  // cgroups::destroy will reap all processes in the cgroup so we should
-  // *not* be able to reap it now.
-  int status;
-  EXPECT_EQ(-1, ::waitpid(pid, &status, 0));
-  EXPECT_EQ(ECHILD, errno);
-}
-
-
-TEST_F(CgroupsAnyHierarchyWithFreezerTest, ROOT_CGROUPS_DestroyTracedProcess)
-{
-  std::string hierarchy = path::join(baseHierarchy, "freezer");
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-
-  pid_t pid = ::fork();
-  ASSERT_NE(-1, pid);
-
-  if (pid == 0) {
-    // In child process.
-    while (true) { sleep(1); }
-
-    ABORT("Child should not reach this statement");
-  }
-
-  // In parent process.
-  Try<Nothing> assign = cgroups::assign(hierarchy, TEST_CGROUPS_ROOT, pid);
-  ASSERT_SOME(assign);
-
-  // Attach to the child process.
-  ASSERT_EQ(0, ptrace(PT_ATTACH, pid, NULL, NULL));
-
-  // Wait until the process is in traced state ('t' or 'T').
-  Duration elapsed = Duration::zero();
-  while (true) {
-    Result<proc::ProcessStatus> process = proc::status(pid);
-    ASSERT_SOME(process);
-
-    if (process.get().state == 'T' || process.get().state == 't') {
-      break;
-    }
-
-    if (elapsed > Seconds(1)) {
-      FAIL() << "Failed to wait for process to be traced";
-    }
-
-    os::sleep(Milliseconds(5));
-    elapsed += Milliseconds(5);
-  }
-
-  // Now destroy the cgroup.
-  AWAIT_READY(cgroups::destroy(hierarchy, TEST_CGROUPS_ROOT));
-
-  // cgroups::destroy will reap all processes in the cgroup so we should
-  // *not* be able to reap it now.
-  int status;
-  EXPECT_EQ(-1, ::waitpid(pid, &status, 0));
-  EXPECT_EQ(ECHILD, errno);
-}
-
-
-class CgroupsAnyHierarchyWithPerfEventTest
-  : public CgroupsAnyHierarchyTest
-{
-public:
-  CgroupsAnyHierarchyWithPerfEventTest()
-    : CgroupsAnyHierarchyTest("perf_event") {}
-};
-
-
-TEST_F(CgroupsAnyHierarchyWithPerfEventTest, ROOT_CGROUPS_Perf)
-{
-  int pipes[2];
-  int dummy;
-  ASSERT_NE(-1, ::pipe(pipes));
-
-  std::string hierarchy = path::join(baseHierarchy, "perf_event");
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-
-  pid_t pid = ::fork();
-  ASSERT_NE(-1, pid);
-
-  if (pid == 0) {
-    // In child process.
-    ::close(pipes[1]);
-
-    // Wait until parent has assigned us to the cgroup.
-    ssize_t len;
-    while ((len = ::read(pipes[0], &dummy, sizeof(dummy))) == -1 &&
-           errno == EINTR);
-    ASSERT_EQ((ssize_t) sizeof(dummy), len);
-    ::close(pipes[0]);
-
-    while (true) {
-      // Don't sleep so 'perf' can actually sample something.
-    }
-
-    ABORT("Child should not reach here");
-  }
-
-  // In parent.
-  ::close(pipes[0]);
-
-  // Put child into the test cgroup.
-  ASSERT_SOME(cgroups::assign(hierarchy, TEST_CGROUPS_ROOT, pid));
-
-  ssize_t len;
-  while ((len = ::write(pipes[1], &dummy, sizeof(dummy))) == -1 &&
-         errno == EINTR);
-  ASSERT_EQ((ssize_t) sizeof(dummy), len);
-  ::close(pipes[1]);
-
-  std::set<std::string> events;
-  // Hardware event.
-  events.insert("cycles");
-  // Software event.
-  events.insert("task-clock");
-
-  // NOTE: Wait at least 2 seconds as we've seen some variance in how
-  // well 'perf' does across Linux distributions (e.g., Ubuntu 14.04)
-  // and we want to make sure that we collect some non-zero values.
-  Future<mesos::PerfStatistics> statistics =
-    perf::sample(events, TEST_CGROUPS_ROOT, Seconds(2));
-  AWAIT_READY(statistics);
-
-  ASSERT_TRUE(statistics.get().has_cycles());
-
-  // TODO(benh): Some Linux distributions (Ubuntu 14.04) fail to
-  // properly sample 'cycles' with 'perf', so we don't explicitly
-  // check the value here. See MESOS-3082.
-  // EXPECT_LT(0u, statistics.get().cycles());
-
-  ASSERT_TRUE(statistics.get().has_task_clock());
-  EXPECT_LT(0.0, statistics.get().task_clock());
-
-  // Kill the child process.
-  ASSERT_NE(-1, ::kill(pid, SIGKILL));
-
-  // Wait for the child process.
-  int status;
-  EXPECT_NE(-1, ::waitpid((pid_t) -1, &status, 0));
-  ASSERT_TRUE(WIFSIGNALED(status));
-  EXPECT_EQ(SIGKILL, WTERMSIG(status));
-
-  // Destroy the cgroup.
-  Future<Nothing> destroy = cgroups::destroy(hierarchy, TEST_CGROUPS_ROOT);
-  AWAIT_READY(destroy);
-}
-
-
-class CgroupsAnyHierarchyMemoryPressureTest
-  : public CgroupsAnyHierarchyTest
-{
-public:
-  CgroupsAnyHierarchyMemoryPressureTest()
-    : CgroupsAnyHierarchyTest("memory"),
-      cgroup(TEST_CGROUPS_ROOT) {}
-
-protected:
-  virtual void SetUp()
-  {
-    CgroupsAnyHierarchyTest::SetUp();
-
-    hierarchy = path::join(baseHierarchy, "memory");
-
-    ASSERT_SOME(cgroups::create(hierarchy, cgroup));
-  }
-
-  void listen()
-  {
-    const std::vector<Level> levels = {
-      Level::LOW,
-      Level::MEDIUM,
-      Level::CRITICAL
-    };
-
-    foreach (Level level, levels) {
-      Try<Owned<Counter>> counter = Counter::create(hierarchy, cgroup, level);
-      EXPECT_SOME(counter);
-
-      counters[level] = counter.get();
-    }
-  }
-
-  std::string hierarchy;
-  const std::string cgroup;
-
-  hashmap<Level, Owned<Counter>> counters;
-};
-
-
-TEST_F(CgroupsAnyHierarchyMemoryPressureTest, ROOT_IncreaseUnlockedRSS)
-{
-  MemoryTestHelper helper;
-  ASSERT_SOME(helper.spawn());
-  ASSERT_SOME(helper.pid());
-
-  const Bytes limit = Megabytes(16);
-
-  // Move the memory test helper into a cgroup and set the limit.
-  EXPECT_SOME(cgroups::memory::limit_in_bytes(hierarchy, cgroup, limit));
-  EXPECT_SOME(cgroups::assign(hierarchy, cgroup, helper.pid().get()));
-
-  listen();
-
-  // Used to save the counter readings from last iteration.
-  uint64_t previousLow = 0;
-  uint64_t previousMedium = 0;
-  uint64_t previousCritical = 0;
-
-  // Used to save the counter readings from this iteration.
-  uint64_t low;
-  uint64_t medium;
-  uint64_t critical;
-
-  // Use a guard to error out if it's been too long.
-  // TODO(chzhcn): Use a better way to set testing time limit.
-  uint64_t iterationLimit = limit.bytes() / getpagesize() * 10;
-
-  for (uint64_t i = 0; i < iterationLimit; i++) {
-    EXPECT_SOME(helper.increaseRSS(getpagesize()));
-
-    Future<uint64_t> _low = counters[Level::LOW]->value();
-    Future<uint64_t> _medium = counters[Level::MEDIUM]->value();
-    Future<uint64_t> _critical = counters[Level::CRITICAL]->value();
-
-    AWAIT_READY(_low);
-    AWAIT_READY(_medium);
-    AWAIT_READY(_critical);
-
-    low = _low.get();
-    medium = _medium.get();
-    critical = _critical.get();
-
-    // We need to know the readings are the same as last time to be
-    // sure they are stable, because the reading is not atomic. For
-    // example, the medium could turn positive after we read low to be
-    // 0, but this should be fixed by the next read immediately.
-    if ((low == previousLow &&
-         medium == previousMedium &&
-         critical == previousCritical)) {
-      if (low != 0) {
-        EXPECT_LE(medium, low);
-        EXPECT_LE(critical, medium);
-
-        // When child's RSS is full, it will be OOM-kill'ed if we
-        // don't stop it right away.
-        break;
-      } else {
-        EXPECT_EQ(0u, medium);
-        EXPECT_EQ(0u, critical);
-      }
-    }
-
-    previousLow = low;
-    previousMedium = medium;
-    previousCritical = critical;
-  }
-}
-
-
-TEST_F(CgroupsAnyHierarchyMemoryPressureTest, ROOT_IncreasePageCache)
-{
-  MemoryTestHelper helper;
-  ASSERT_SOME(helper.spawn());
-  ASSERT_SOME(helper.pid());
-
-  const Bytes limit = Megabytes(16);
-
-  // Move the memory test helper into a cgroup and set the limit.
-  EXPECT_SOME(cgroups::memory::limit_in_bytes(hierarchy, cgroup, limit));
-  EXPECT_SOME(cgroups::assign(hierarchy, cgroup, helper.pid().get()));
-
-  listen();
-
-  // Used to save the counter readings from last iteration.
-  uint64_t previousLow = 0;
-  uint64_t previousMedium = 0;
-  uint64_t previousCritical = 0;
-
-  // Used to save the counter readings from this iteration.
-  uint64_t low;
-  uint64_t medium;
-  uint64_t critical;
-
-  // Use a guard to error out if it's been too long.
-  // TODO(chzhcn): Use a better way to set testing time limit.
-  uint64_t iterationLimit = limit.bytes() / Megabytes(1).bytes() * 2;
-
-  for (uint64_t i = 0; i < iterationLimit; i++) {
-    EXPECT_SOME(helper.increasePageCache(Megabytes(1)));
-
-    Future<uint64_t> _low = counters[Level::LOW]->value();
-    Future<uint64_t> _medium = counters[Level::MEDIUM]->value();
-    Future<uint64_t> _critical = counters[Level::CRITICAL]->value();
-
-    AWAIT_READY(_low);
-    AWAIT_READY(_medium);
-    AWAIT_READY(_critical);
-
-    low = _low.get();
-    medium = _medium.get();
-    critical = _critical.get();
-
-    // We need to know the readings are the same as last time to be
-    // sure they are stable, because the reading is not atomic. For
-    // example, the medium could turn positive after we read low to be
-    // 0, but this should be fixed by the next read immediately.
-    if ((low == previousLow &&
-         medium == previousMedium &&
-         critical == previousCritical)) {
-      if (low != 0) {
-        EXPECT_LE(medium, low);
-        EXPECT_LE(critical, medium);
-
-        // Different from the RSS test, since the child is only
-        // consuming at a slow rate the page cache, which is evictable
-        // and reclaimable, we could therefore be in this state
-        // forever. Our guard will let us out shortly.
-      } else {
-        EXPECT_EQ(0u, medium);
-        EXPECT_EQ(0u, critical);
-      }
-    }
-
-    previousLow = low;
-    previousMedium = medium;
-    previousCritical = critical;
-  }
-
-  EXPECT_LT(0u, low);
-}
-
-// Tests the cpuacct::stat API. This test just tests for ANY value returned by
-// the API.
-TEST_F(CgroupsAnyHierarchyWithCpuAcctMemoryTest, ROOT_CGROUPS_CpuAcctsStats)
-{
-  const std::string hierarchy = path::join(baseHierarchy, "cpuacct");
-  ASSERT_SOME(cgroups::create(hierarchy, TEST_CGROUPS_ROOT));
-
-  CHECK_SOME(cgroups::assign(hierarchy, TEST_CGROUPS_ROOT, ::getpid()));
-
-  ASSERT_SOME(cgroups::cpuacct::stat(hierarchy, TEST_CGROUPS_ROOT));
-
-  // Move ourselves to the root cgroup.
-  CHECK_SOME(cgroups::assign(hierarchy, "", ::getpid()));
-
-  AWAIT_READY(cgroups::destroy(hierarchy, TEST_CGROUPS_ROOT));
-}
-
-} // namespace tests {
-} // namespace internal {
-} // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/96351372/src/tests/composing_containerizer_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/composing_containerizer_tests.cpp b/src/tests/composing_containerizer_tests.cpp
deleted file mode 100644
index d66f519..0000000
--- a/src/tests/composing_containerizer_tests.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include <process/future.hpp>
-#include <process/gmock.hpp>
-
-#include <stout/option.hpp>
-
-#include "messages/messages.hpp"
-
-#include "slave/containerizer/containerizer.hpp"
-#include "slave/containerizer/composing.hpp"
-
-#include "tests/mesos.hpp"
-
-using namespace mesos::internal::slave;
-
-using namespace process;
-
-using std::vector;
-
-using testing::_;
-using testing::Return;
-
-namespace mesos {
-namespace internal {
-namespace tests {
-
-
-class ComposingContainerizerTest : public MesosTest {};
-
-class MockContainerizer : public slave::Containerizer
-{
-public:
-  MOCK_METHOD1(
-      recover,
-      process::Future<Nothing>(
-          const Option<slave::state::SlaveState>&));
-
-  MOCK_METHOD7(
-      launch,
-      process::Future<bool>(
-          const ContainerID&,
-          const ExecutorInfo&,
-          const std::string&,
-          const Option<std::string>&,
-          const SlaveID&,
-          const process::PID<Slave>&,
-          bool));
-
-  MOCK_METHOD8(
-      launch,
-      process::Future<bool>(
-          const ContainerID&,
-          const TaskInfo&,
-          const ExecutorInfo&,
-          const std::string&,
-          const Option<std::string>&,
-          const SlaveID&,
-          const process::PID<Slave>&,
-          bool));
-
-  MOCK_METHOD2(
-      update,
-      process::Future<Nothing>(
-          const ContainerID&,
-          const Resources&));
-
-  MOCK_METHOD1(
-      usage,
-      process::Future<ResourceStatistics>(
-          const ContainerID&));
-
-  MOCK_METHOD1(
-      wait,
-      process::Future<containerizer::Termination>(
-          const ContainerID&));
-
-  MOCK_METHOD1(
-      destroy,
-      void(const ContainerID&));
-
-  MOCK_METHOD0(
-      containers,
-      process::Future<hashset<ContainerID> >());
-};
-
-
-// This test checks if destroy is called while container is being
-// launched, the composing containerizer still calls the underlying
-// containerizer's destroy and skip calling the rest of the
-// containerizers.
-TEST_F(ComposingContainerizerTest, DestroyWhileLaunching)
-{
-  vector<Containerizer*> containerizers;
-
-  MockContainerizer* mockContainerizer = new MockContainerizer();
-  MockContainerizer* mockContainerizer2 = new MockContainerizer();
-
-  containerizers.push_back(mockContainerizer);
-  containerizers.push_back(mockContainerizer2);
-
-  ComposingContainerizer containerizer(containerizers);
-  ContainerID containerId;
-  containerId.set_value("container");
-  TaskInfo taskInfo;
-  ExecutorInfo executorInfo;
-  SlaveID slaveId;
-  PID<Slave> slavePid;
-
-  Promise<bool> launchPromise;
-
-  EXPECT_CALL(*mockContainerizer, launch(_, _, _, _, _, _, _, _))
-    .WillOnce(Return(launchPromise.future()));
-
-  Future<Nothing> destroy;
-
-  EXPECT_CALL(*mockContainerizer, destroy(_))
-    .WillOnce(FutureSatisfy(&destroy));
-
-  Future<bool> launch = containerizer.launch(
-      containerId,
-      taskInfo,
-      executorInfo,
-      "dir",
-      "user",
-      slaveId,
-      slavePid,
-      false);
-
-  Resources resources = Resources::parse("cpus:1;mem:256").get();
-
-  EXPECT_TRUE(launch.isPending());
-
-  containerizer.destroy(containerId);
-
-  EXPECT_CALL(*mockContainerizer2, launch(_, _, _, _, _, _, _, _))
-    .Times(0);
-
-  // We make sure the destroy is being called on the first containerizer.
-  // The second containerizer shouldn't be called as well since the
-  // container is already destroyed.
-  AWAIT_READY(destroy);
-
-  launchPromise.set(false);
-  AWAIT_FAILED(launch);
-}
-
-} // namespace tests {
-} // namespace internal {
-} // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/96351372/src/tests/containerizer/cgroups_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/cgroups_isolator_tests.cpp b/src/tests/containerizer/cgroups_isolator_tests.cpp
new file mode 100644
index 0000000..a4ccc8e
--- /dev/null
+++ b/src/tests/containerizer/cgroups_isolator_tests.cpp
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <map>
+#include <utility>
+
+#include <gtest/gtest.h>
+
+#include <stout/foreach.hpp>
+#include <stout/proc.hpp>
+#include <stout/stringify.hpp>
+
+#include "slave/containerizer/mesos/containerizer.hpp"
+
+#include "tests/script.hpp"
+
+using std::map;
+
+namespace mesos {
+namespace internal {
+namespace tests {
+
+
+// Run the balloon framework under a mesos containerizer.
+TEST_SCRIPT(ContainerizerTest,
+            ROOT_CGROUPS_BalloonFramework,
+            "balloon_framework_test.sh")
+
+} // namespace tests {
+} // namespace internal {
+} // namespace mesos {