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); \
