Refactored filesystem isolator tests to allow multiple rootfses.

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


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

Branch: refs/heads/master
Commit: 40638c5413266f4a4d5117cde225247ad19b2f55
Parents: da2dfab
Author: Jie Yu <[email protected]>
Authored: Mon Aug 24 15:55:11 2015 -0700
Committer: Jie Yu <[email protected]>
Committed: Wed Aug 26 14:26:29 2015 -0700

----------------------------------------------------------------------
 include/mesos/mesos.proto                       |   4 +-
 .../containerizer/filesystem_isolator_tests.cpp | 103 +++++++++++++------
 src/tests/containerizer/provisioner.hpp         |  30 ++++--
 src/tests/mesos.hpp                             |   2 +
 4 files changed, 99 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/40638c54/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index 33e1b28..715b8cf 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -1135,7 +1135,7 @@ message Image {
 
   // Protobuf for specifying an Appc container image. See:
   // https://github.com/appc/spec/blob/master/spec/aci.md
-  message AppC {
+  message Appc {
     // The name of the image.
     required string name = 1;
 
@@ -1158,7 +1158,7 @@ message Image {
 
   // Only one of the following image messages should be set to match
   // the type.
-  optional AppC appc = 2;
+  optional Appc appc = 2;
   optional Docker docker = 3;
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/40638c54/src/tests/containerizer/filesystem_isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/filesystem_isolator_tests.cpp 
b/src/tests/containerizer/filesystem_isolator_tests.cpp
index dd1e49b..13f629c 100644
--- a/src/tests/containerizer/filesystem_isolator_tests.cpp
+++ b/src/tests/containerizer/filesystem_isolator_tests.cpp
@@ -73,22 +73,30 @@ class LinuxFilesystemIsolatorTest: public MesosTest
 public:
   // This helper creates a MesosContainerizer instance that uses the
   // LinuxFilesystemIsolator. The filesystem isolator takes a
-  // TestProvisioner which provision APPC images by copying files from
-  // the host filesystem.
-  Try<Owned<MesosContainerizer>> createContainerizer(const slave::Flags& flags)
+  // TestAppcProvisioner which provisions APPC images by copying files
+  // from the host filesystem.
+  Try<Owned<MesosContainerizer>> createContainerizer(
+      const slave::Flags& flags,
+      const vector<string>& imageNames)
   {
-    Try<Owned<Rootfs>> rootfs =
-      LinuxRootfs::create(path::join(os::getcwd(), "rootfs"));
+    // Create the root filesystems.
+    hashmap<string, Shared<Rootfs>> rootfses;
+    foreach (const string& imageName, imageNames) {
+      Try<Owned<Rootfs>> rootfs =
+        LinuxRootfs::create(path::join(os::getcwd(), "rootfses", imageName));
 
-    if (rootfs.isError()) {
-      return Error("Failed to create LinuxRootfs: " + rootfs.error());
+      if (rootfs.isError()) {
+        return Error("Failed to create LinuxRootfs: " + rootfs.error());
+      }
+
+      rootfses.put(imageName, rootfs.get().share());
     }
 
-    // NOTE: TestProvisioner provisions APPC images.
+    // Create the TestAppcProvisioner for the above root filesystems.
     hashmap<Image::Type, Owned<Provisioner>> provisioners;
     provisioners.put(
         Image::APPC,
-        Owned<Provisioner>(new TestProvisioner(rootfs.get().share())));
+        Owned<Provisioner>(new TestAppcProvisioner(rootfses)));
 
     Try<Isolator*> _isolator =
       LinuxFilesystemIsolatorProcess::create(flags, provisioners);
@@ -120,14 +128,18 @@ public:
   }
 
   ContainerInfo createContainerInfo(
-      const vector<Volume>& volumes = vector<Volume>(),
-      bool hasImage = true)
+      const Option<string>& imageName = None(),
+      const vector<Volume>& volumes = vector<Volume>())
   {
     ContainerInfo info;
     info.set_type(ContainerInfo::MESOS);
 
-    if (hasImage) {
-      info.mutable_mesos()->mutable_image()->set_type(Image::APPC);
+    if (imageName.isSome()) {
+      Image* image = info.mutable_mesos()->mutable_image();
+      image->set_type(Image::APPC);
+
+      Image::Appc* appc = image->mutable_appc();
+      appc->set_name(imageName.get());
     }
 
     foreach (const Volume& volume, volumes) {
@@ -137,16 +149,29 @@ public:
     return info;
   }
 
-  Volume createVolume(
+  Volume createVolumeFromHostPath(
+      const string& containerPath,
+      const string& hostPath,
+      const Volume::Mode& mode)
+  {
+    return CREATE_VOLUME(containerPath, hostPath, mode);
+  }
+
+  Volume createVolumeFromImage(
       const string& containerPath,
-      const Image::Type& imageType,
+      const string& imageName,
       const Volume::Mode& mode)
   {
     Volume volume;
     volume.set_container_path(containerPath);
-    volume.mutable_image()->set_type(imageType);
     volume.set_mode(mode);
 
+    Image* image = volume.mutable_image();
+    image->set_type(Image::APPC);
+
+    Image::Appc* appc = image->mutable_appc();
+    appc->set_name(imageName);
+
     return volume;
   }
 
@@ -161,7 +186,9 @@ TEST_F(LinuxFilesystemIsolatorTest, 
ROOT_ChangeRootFilesystem)
 {
   slave::Flags flags = CreateSlaveFlags();
 
-  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
+  Try<Owned<MesosContainerizer>> containerizer =
+    createContainerizer(flags, {"test_image"});
+
   ASSERT_SOME(containerizer);
 
   ContainerID containerId;
@@ -171,7 +198,7 @@ TEST_F(LinuxFilesystemIsolatorTest, 
ROOT_ChangeRootFilesystem)
       "test_executor",
       "[ ! -d '" + os::getcwd() + "' ]");
 
-  executor.mutable_container()->CopyFrom(createContainerInfo());
+  executor.mutable_container()->CopyFrom(createContainerInfo("test_image"));
 
   string directory = path::join(os::getcwd(), "sandbox");
   ASSERT_SOME(os::mkdir(directory));
@@ -207,7 +234,9 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromSandbox)
 {
   slave::Flags flags = CreateSlaveFlags();
 
-  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
+  Try<Owned<MesosContainerizer>> containerizer =
+    createContainerizer(flags, {"test_image"});
+
   ASSERT_SOME(containerizer);
 
   ContainerID containerId;
@@ -218,7 +247,8 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromSandbox)
       "echo abc > /tmp/file");
 
   executor.mutable_container()->CopyFrom(createContainerInfo(
-      {CREATE_VOLUME("/tmp", "tmp", Volume::RW)}));
+      "test_image",
+      {createVolumeFromHostPath("/tmp", "tmp", Volume::RW)}));
 
   string directory = path::join(os::getcwd(), "sandbox");
   ASSERT_SOME(os::mkdir(directory));
@@ -256,7 +286,9 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHost)
 {
   slave::Flags flags = CreateSlaveFlags();
 
-  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
+  Try<Owned<MesosContainerizer>> containerizer =
+    createContainerizer(flags, {"test_image"});
+
   ASSERT_SOME(containerizer);
 
   ContainerID containerId;
@@ -267,7 +299,8 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_VolumeFromHost)
       "test -d /tmp/sandbox");
 
   executor.mutable_container()->CopyFrom(createContainerInfo(
-      {CREATE_VOLUME("/tmp", os::getcwd(), Volume::RW)}));
+      "test_image",
+      {createVolumeFromHostPath("/tmp", os::getcwd(), Volume::RW)}));
 
   string directory = path::join(os::getcwd(), "sandbox");
   ASSERT_SOME(os::mkdir(directory));
@@ -303,7 +336,9 @@ TEST_F(LinuxFilesystemIsolatorTest, 
ROOT_VolumeFromHostSandboxMountPoint)
 {
   slave::Flags flags = CreateSlaveFlags();
 
-  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
+  Try<Owned<MesosContainerizer>> containerizer =
+    createContainerizer(flags, {"test_image"});
+
   ASSERT_SOME(containerizer);
 
   ContainerID containerId;
@@ -314,7 +349,8 @@ TEST_F(LinuxFilesystemIsolatorTest, 
ROOT_VolumeFromHostSandboxMountPoint)
       "test -d mountpoint/sandbox");
 
   executor.mutable_container()->CopyFrom(createContainerInfo(
-      {CREATE_VOLUME("mountpoint", os::getcwd(), Volume::RW)}));
+      "test_image",
+      {createVolumeFromHostPath("mountpoint", os::getcwd(), Volume::RW)}));
 
   string directory = path::join(os::getcwd(), "sandbox");
   ASSERT_SOME(os::mkdir(directory));
@@ -350,7 +386,9 @@ TEST_F(LinuxFilesystemIsolatorTest, 
ROOT_PersistentVolumeWithRootFilesystem)
   slave::Flags flags = CreateSlaveFlags();
   flags.work_dir = os::getcwd();
 
-  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
+  Try<Owned<MesosContainerizer>> containerizer =
+    createContainerizer(flags, {"test_image"});
+
   ASSERT_SOME(containerizer);
 
   ContainerID containerId;
@@ -366,7 +404,7 @@ TEST_F(LinuxFilesystemIsolatorTest, 
ROOT_PersistentVolumeWithRootFilesystem)
       "persistent_volume_id",
       "volume"));
 
-  executor.mutable_container()->CopyFrom(createContainerInfo());
+  executor.mutable_container()->CopyFrom(createContainerInfo("test_image"));
 
   // Create a persistent volume.
   string volume = slave::paths::getPersistentVolumePath(
@@ -410,7 +448,9 @@ TEST_F(LinuxFilesystemIsolatorTest, 
ROOT_PersistentVolumeWithoutRootFilesystem)
   slave::Flags flags = CreateSlaveFlags();
   flags.work_dir = os::getcwd();
 
-  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
+  Try<Owned<MesosContainerizer>> containerizer =
+    createContainerizer(flags, {"test_image"});
+
   ASSERT_SOME(containerizer);
 
   ContainerID containerId;
@@ -426,7 +466,7 @@ TEST_F(LinuxFilesystemIsolatorTest, 
ROOT_PersistentVolumeWithoutRootFilesystem)
       "persistent_volume_id",
       "volume"));
 
-  executor.mutable_container()->CopyFrom(createContainerInfo({}, false));
+  executor.mutable_container()->CopyFrom(createContainerInfo());
 
   // Create a persistent volume.
   string volume = slave::paths::getPersistentVolumePath(
@@ -471,7 +511,9 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ImageInVolume)
 {
   slave::Flags flags = CreateSlaveFlags();
 
-  Try<Owned<MesosContainerizer>> containerizer = createContainerizer(flags);
+  Try<Owned<MesosContainerizer>> containerizer =
+    createContainerizer(flags, {"test_image"});
+
   ASSERT_SOME(containerizer);
 
   ContainerID containerId;
@@ -482,7 +524,8 @@ TEST_F(LinuxFilesystemIsolatorTest, ROOT_ImageInVolume)
       "test -d rootfs/bin");
 
   executor.mutable_container()->CopyFrom(createContainerInfo(
-      {createVolume("rootfs", Image::APPC, Volume::RW)}, false));
+      None(),
+      {createVolumeFromImage("rootfs", "test_image", Volume::RW)}));
 
   string directory = path::join(os::getcwd(), "sandbox");
   ASSERT_SOME(os::mkdir(directory));

http://git-wip-us.apache.org/repos/asf/mesos/blob/40638c54/src/tests/containerizer/provisioner.hpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/provisioner.hpp 
b/src/tests/containerizer/provisioner.hpp
index c4ba467..a26b813 100644
--- a/src/tests/containerizer/provisioner.hpp
+++ b/src/tests/containerizer/provisioner.hpp
@@ -23,6 +23,9 @@
 
 #include <process/shared.hpp>
 
+#include <stout/hashmap.hpp>
+#include <stout/stringify.hpp>
+
 #include "slave/containerizer/provisioner.hpp"
 
 #include "tests/containerizer/rootfs.hpp"
@@ -31,28 +34,29 @@ namespace mesos {
 namespace internal {
 namespace tests {
 
-class TestProvisioner : public slave::Provisioner
+class TestAppcProvisioner : public slave::Provisioner
 {
 public:
-  TestProvisioner(const process::Shared<Rootfs>& _rootfs)
-    : rootfs(_rootfs)
+  TestAppcProvisioner(
+      const hashmap<std::string, process::Shared<Rootfs>>& _rootfses)
+    : rootfses(_rootfses)
   {
     using testing::_;
     using testing::DoDefault;
     using testing::Invoke;
 
     ON_CALL(*this, recover(_, _))
-      .WillByDefault(Invoke(this, &TestProvisioner::unmocked_recover));
+      .WillByDefault(Invoke(this, &TestAppcProvisioner::unmocked_recover));
     EXPECT_CALL(*this, recover(_, _))
       .WillRepeatedly(DoDefault());
 
     ON_CALL(*this, provision(_, _))
-      .WillByDefault(Invoke(this, &TestProvisioner::unmocked_provision));
+      .WillByDefault(Invoke(this, &TestAppcProvisioner::unmocked_provision));
     EXPECT_CALL(*this, provision(_, _))
       .WillRepeatedly(DoDefault());
 
     ON_CALL(*this, destroy(_))
-      .WillByDefault(Invoke(this, &TestProvisioner::unmocked_destroy));
+      .WillByDefault(Invoke(this, &TestAppcProvisioner::unmocked_destroy));
     EXPECT_CALL(*this, destroy(_))
       .WillRepeatedly(DoDefault());
   }
@@ -85,7 +89,17 @@ public:
       const ContainerID& containerId,
       const Image& image)
   {
-    return rootfs->root;
+    if (image.type() != Image::APPC) {
+      return process::Failure(
+          "Unsupported image type '" + stringify(image.type()) + "'");
+    }
+
+    if (!rootfses.contains(image.appc().name())) {
+      return process::Failure(
+          "Image '" + image.appc().name() + "' is not found");
+    }
+
+    return rootfses[image.appc().name()]->root;
   }
 
   process::Future<bool> unmocked_destroy(
@@ -95,7 +109,7 @@ public:
   }
 
 private:
-  process::Shared<Rootfs> rootfs;
+  hashmap<std::string, process::Shared<Rootfs>> rootfses;
 };
 
 } // namespace tests {

http://git-wip-us.apache.org/repos/asf/mesos/blob/40638c54/src/tests/mesos.hpp
----------------------------------------------------------------------
diff --git a/src/tests/mesos.hpp b/src/tests/mesos.hpp
index 637636a..b2160f5 100644
--- a/src/tests/mesos.hpp
+++ b/src/tests/mesos.hpp
@@ -417,6 +417,8 @@ protected:
      commandInfo; })
 
 
+// TODO(jieyu): Consider making it a function to support more
+// overloads (e.g., createVolumeFromHost, createVolumeFromImage).
 #define CREATE_VOLUME(containerPath, hostPath, mode)                  \
       ({ Volume volume;                                               \
          volume.set_container_path(containerPath);                    \

Reply via email to