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 2017/10/30 15:18:55 UTC
[09/15] mesos git commit: Added validation for disk related new
operations.
Added validation for disk related new operations.
(This is based on https://reviews.apache.org/r/61946)
Review: https://reviews.apache.org/r/63355
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/6c8ae681
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/6c8ae681
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/6c8ae681
Branch: refs/heads/master
Commit: 6c8ae68180f92bba0dbdf0516cc833c04f958f5b
Parents: ae8619d
Author: Jan Schlicht <ja...@mesosphere.io>
Authored: Tue Oct 24 00:37:36 2017 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Mon Oct 30 16:18:31 2017 +0100
----------------------------------------------------------------------
src/master/validation.cpp | 90 ++++++++++++++++
src/master/validation.hpp | 6 ++
src/tests/master_validation_tests.cpp | 164 +++++++++++++++++++++++++++++
3 files changed, 260 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/6c8ae681/src/master/validation.cpp
----------------------------------------------------------------------
diff --git a/src/master/validation.cpp b/src/master/validation.cpp
index d8ff1fd..d6d6f21 100644
--- a/src/master/validation.cpp
+++ b/src/master/validation.cpp
@@ -2268,6 +2268,96 @@ Option<Error> validate(
return None();
}
+
+Option<Error> validate(const Offer::Operation::CreateVolume& createVolume)
+{
+ const Resource& source = createVolume.source();
+
+ Option<Error> error = resource::validate(Resources(source));
+ if (error.isSome()) {
+ return Error("Invalid resource: " + error->message);
+ }
+
+ if (!Resources::hasResourceProvider(source)) {
+ return Error("Does not have a resource provider");
+ }
+
+ if (!Resources::isDisk(source, Resource::DiskInfo::Source::RAW)) {
+ return Error("'source' is not a RAW disk resource");
+ }
+
+ if (createVolume.target_type() != Resource::DiskInfo::Source::MOUNT &&
+ createVolume.target_type() != Resource::DiskInfo::Source::PATH) {
+ return Error("'target_type' is neither MOUNT or PATH");
+ }
+
+ return None();
+}
+
+
+Option<Error> validate(const Offer::Operation::DestroyVolume& destroyVolume)
+{
+ const Resource& volume = destroyVolume.volume();
+
+ Option<Error> error = resource::validate(Resources(volume));
+ if (error.isSome()) {
+ return Error("Invalid resource: " + error->message);
+ }
+
+ if (!Resources::hasResourceProvider(volume)) {
+ return Error("Does not have a resource provider");
+ }
+
+ if (!Resources::isDisk(volume, Resource::DiskInfo::Source::MOUNT) &&
+ !Resources::isDisk(volume, Resource::DiskInfo::Source::PATH)) {
+ return Error("'volume' is neither a MOUTN or PATH disk resource");
+ }
+
+ return None();
+}
+
+
+Option<Error> validate(const Offer::Operation::CreateBlock& createBlock)
+{
+ const Resource& source = createBlock.source();
+
+ Option<Error> error = resource::validate(Resources(source));
+ if (error.isSome()) {
+ return Error("Invalid resource: " + error.get().message);
+ }
+
+ if (!Resources::hasResourceProvider(source)) {
+ return Error("Does not have a resource provider");
+ }
+
+ if (!Resources::isDisk(source, Resource::DiskInfo::Source::RAW)) {
+ return Error("'source' is not a RAW disk resource");
+ }
+
+ return None();
+}
+
+
+Option<Error> validate(const Offer::Operation::DestroyBlock& destroyBlock)
+{
+ const Resource& block = destroyBlock.block();
+
+ Option<Error> error = resource::validate(Resources(block));
+ if (error.isSome()) {
+ return Error("Invalid resource: " + error.get().message);
+ }
+
+ if (!Resources::hasResourceProvider(block)) {
+ return Error("Does not have a resource provider");
+ }
+
+ if (!Resources::isDisk(block, Resource::DiskInfo::Source::BLOCK)) {
+ return Error("'block' is not a BLOCK disk resource");
+ }
+
+ return None();
+}
+
} // namespace operation {
} // namespace validation {
http://git-wip-us.apache.org/repos/asf/mesos/blob/6c8ae681/src/master/validation.hpp
----------------------------------------------------------------------
diff --git a/src/master/validation.hpp b/src/master/validation.hpp
index ccad352..ac54062 100644
--- a/src/master/validation.hpp
+++ b/src/master/validation.hpp
@@ -306,6 +306,12 @@ Option<Error> validate(
const hashmap<FrameworkID, hashmap<TaskID, TaskInfo>>& pendingTasks,
const Option<FrameworkInfo>& frameworkInfo = None());
+
+Option<Error> validate(const Offer::Operation::CreateVolume& createVolume);
+Option<Error> validate(const Offer::Operation::DestroyVolume& destroyVolume);
+Option<Error> validate(const Offer::Operation::CreateBlock& createBlock);
+Option<Error> validate(const Offer::Operation::DestroyBlock& destroyBlock);
+
} // namespace operation {
} // namespace validation {
http://git-wip-us.apache.org/repos/asf/mesos/blob/6c8ae681/src/tests/master_validation_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_validation_tests.cpp b/src/tests/master_validation_tests.cpp
index 4cf3ba7..be8c892 100644
--- a/src/tests/master_validation_tests.cpp
+++ b/src/tests/master_validation_tests.cpp
@@ -1219,6 +1219,170 @@ TEST_F(DestroyOperationValidationTest, UnknownPersistentVolume)
}
+TEST(OperationValidationTest, CreateVolume)
+{
+ Resource disk1 = createDiskResource(
+ "10", "*", None(), None(), createDiskSourceRaw());
+
+ Resource disk2 = createDiskResource(
+ "20", "*", None(), None(), createDiskSourceMount());
+
+ Resource disk3 = createDiskResource(
+ "30", "*", None(), None(), createDiskSourceRaw());
+
+ disk1.mutable_provider_id()->set_value("provider1");
+ disk2.mutable_provider_id()->set_value("provider2");
+
+ Offer::Operation::CreateVolume createVolume;
+ createVolume.mutable_source()->CopyFrom(disk1);
+ createVolume.set_target_type(Resource::DiskInfo::Source::MOUNT);
+
+ Option<Error> error = operation::validate(createVolume);
+ EXPECT_NONE(error);
+
+ createVolume.mutable_source()->CopyFrom(disk2);
+ createVolume.set_target_type(Resource::DiskInfo::Source::MOUNT);
+
+ error = operation::validate(createVolume);
+ ASSERT_SOME(error);
+ EXPECT_TRUE(strings::contains(
+ error->message,
+ "'source' is not a RAW disk resource"));
+
+ createVolume.mutable_source()->CopyFrom(disk3);
+ createVolume.set_target_type(Resource::DiskInfo::Source::PATH);
+
+ error = operation::validate(createVolume);
+ ASSERT_SOME(error);
+ EXPECT_TRUE(strings::contains(
+ error->message,
+ "Does not have a resource provider"));
+
+ createVolume.mutable_source()->CopyFrom(disk1);
+ createVolume.set_target_type(Resource::DiskInfo::Source::BLOCK);
+
+ error = operation::validate(createVolume);
+ ASSERT_SOME(error);
+ EXPECT_TRUE(strings::contains(
+ error->message,
+ "'target_type' is neither MOUNT or PATH"));
+}
+
+
+TEST(OperationValidationTest, DestroyVolume)
+{
+ Resource disk1 = createDiskResource(
+ "10", "*", None(), None(), createDiskSourceMount());
+
+ Resource disk2 = createDiskResource(
+ "20", "*", None(), None(), createDiskSourcePath());
+
+ Resource disk3 = createDiskResource(
+ "30", "*", None(), None(), createDiskSourceRaw());
+
+ disk1.mutable_provider_id()->set_value("provider1");
+ disk3.mutable_provider_id()->set_value("provider3");
+
+ Offer::Operation::DestroyVolume destroyVolume;
+ destroyVolume.mutable_volume()->CopyFrom(disk1);
+
+ Option<Error> error = operation::validate(destroyVolume);
+ EXPECT_NONE(error);
+
+ destroyVolume.mutable_volume()->CopyFrom(disk2);
+
+ error = operation::validate(destroyVolume);
+ ASSERT_SOME(error);
+ EXPECT_TRUE(strings::contains(
+ error->message,
+ "Does not have a resource provider"));
+
+ destroyVolume.mutable_volume()->CopyFrom(disk3);
+
+ error = operation::validate(destroyVolume);
+ ASSERT_SOME(error);
+ EXPECT_TRUE(strings::contains(
+ error->message,
+ "'volume' is neither a MOUTN or PATH disk resource"));
+}
+
+
+TEST(OperationValidationTest, CreateBlock)
+{
+ Resource disk1 = createDiskResource(
+ "10", "*", None(), None(), createDiskSourceRaw());
+
+ Resource disk2 = createDiskResource(
+ "20", "*", None(), None(), createDiskSourceMount());
+
+ Resource disk3 = createDiskResource(
+ "30", "*", None(), None(), createDiskSourceRaw());
+
+ disk1.mutable_provider_id()->set_value("provider1");
+ disk2.mutable_provider_id()->set_value("provider2");
+
+ Offer::Operation::CreateBlock createBlock;
+ createBlock.mutable_source()->CopyFrom(disk1);
+
+ Option<Error> error = operation::validate(createBlock);
+ EXPECT_NONE(error);
+
+ createBlock.mutable_source()->CopyFrom(disk2);
+
+ error = operation::validate(createBlock);
+ ASSERT_SOME(error);
+ EXPECT_TRUE(strings::contains(
+ error->message,
+ "'source' is not a RAW disk resource"));
+
+ createBlock.mutable_source()->CopyFrom(disk3);
+
+ error = operation::validate(createBlock);
+ ASSERT_SOME(error);
+ EXPECT_TRUE(strings::contains(
+ error->message,
+ "Does not have a resource provider"));
+}
+
+
+TEST(OperationValidationTest, DestroyBlock)
+{
+ Resource disk1 = createDiskResource(
+ "10", "*", None(), None(), createDiskSourceBlock());
+
+ Resource disk2 = createDiskResource(
+ "20", "*", None(), None(), createDiskSourceBlock());
+
+ Resource disk3 = createDiskResource(
+ "30", "*", None(), None(), createDiskSourceMount());
+
+ disk1.mutable_provider_id()->set_value("provider1");
+ disk3.mutable_provider_id()->set_value("provider3");
+
+ Offer::Operation::DestroyBlock destroyBlock;
+ destroyBlock.mutable_block()->CopyFrom(disk1);
+
+ Option<Error> error = operation::validate(destroyBlock);
+ EXPECT_NONE(error);
+
+ destroyBlock.mutable_block()->CopyFrom(disk2);
+
+ error = operation::validate(destroyBlock);
+ ASSERT_SOME(error);
+ EXPECT_TRUE(strings::contains(
+ error->message,
+ "Does not have a resource provider"));
+
+ destroyBlock.mutable_block()->CopyFrom(disk3);
+
+ error = operation::validate(destroyBlock);
+ ASSERT_SOME(error);
+ EXPECT_TRUE(strings::contains(
+ error->message,
+ "'block' is not a BLOCK disk resource"));
+}
+
+
// TODO(jieyu): All of the task validation tests have the same flow:
// launch a task, expect an update of a particular format (invalid w/
// message). Consider providing common functionalities in the test