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/02/04 21:08:07 UTC

mesos git commit: Added validation for CREATE offer operation.

Repository: mesos
Updated Branches:
  refs/heads/master 6e5212e4c -> 66157a6ce


Added validation for CREATE offer operation.

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


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

Branch: refs/heads/master
Commit: 66157a6ce2d82f446fd3b59b252d8b473f5b2006
Parents: 6e5212e
Author: Jie Yu <yu...@gmail.com>
Authored: Fri Jan 30 14:42:03 2015 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Wed Feb 4 12:07:15 2015 -0800

----------------------------------------------------------------------
 src/Makefile.am                       |   1 +
 src/master/validation.cpp             |  40 ++-
 src/master/validation.hpp             |   6 +-
 src/tests/master_validation_tests.cpp | 156 ++++++++++
 src/tests/resource_offers_tests.cpp   | 440 -----------------------------
 5 files changed, 201 insertions(+), 442 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/66157a6c/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 5b1885d..93537d1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1279,6 +1279,7 @@ mesos_tests_SOURCES =				\
   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				\

http://git-wip-us.apache.org/repos/asf/mesos/blob/66157a6c/src/master/validation.cpp
----------------------------------------------------------------------
diff --git a/src/master/validation.cpp b/src/master/validation.cpp
index 8804ba6..550782e 100644
--- a/src/master/validation.cpp
+++ b/src/master/validation.cpp
@@ -121,6 +121,22 @@ Option<Error> validateUniquePersistenceID(
 }
 
 
+// Validates that all the given resources are persistent volumes.
+Option<Error> validatePersistentVolume(
+    const RepeatedPtrField<Resource>& volumes)
+{
+  foreach (const Resource& volume, volumes) {
+    if (!volume.has_disk()) {
+      return Error("Resource " + stringify(volume) + " does not have DiskInfo");
+    } else if (!volume.disk().has_persistence()) {
+      return Error("'persistence' is not set in DiskInfo");
+    }
+  }
+
+  return None();
+}
+
+
 Option<Error> validate(const RepeatedPtrField<Resource>& resources)
 {
   Option<Error> error = Resources::validate(resources);
@@ -516,7 +532,29 @@ Option<Error> validate(
 
 namespace operation {
 
-// TODO(jieyu): Added validate functions for Offer operations.
+Option<Error> validate(
+    const Offer::Operation::Create& create,
+    const Resources& checkpointedResources)
+{
+  Option<Error> error = resource::validate(create.volumes());
+  if (error.isSome()) {
+    return Error("Invalid resources: " + error.get().message);
+  }
+
+  error = resource::validatePersistentVolume(create.volumes());
+  if (error.isSome()) {
+    return Error("Not a persistent volume: " + error.get().message);
+  }
+
+  error = resource::validateUniquePersistenceID(
+      checkpointedResources + create.volumes());
+
+  if (error.isSome()) {
+    return error;
+  }
+
+  return None();
+}
 
 } // namespace operation {
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/66157a6c/src/master/validation.hpp
----------------------------------------------------------------------
diff --git a/src/master/validation.hpp b/src/master/validation.hpp
index 642c375..81dc7ee 100644
--- a/src/master/validation.hpp
+++ b/src/master/validation.hpp
@@ -81,7 +81,11 @@ Option<Error> validate(
 
 namespace operation {
 
-// TODO(jieyu): Added validate functions for Offer operations.
+// Validates the CREATE operation. We need slave's checkpointed
+// resources so that we can validate persistence ID uniqueness.
+Option<Error> validate(
+    const Offer::Operation::Create& create,
+    const Resources& checkpointedResources);
 
 } // namespace operation {
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/66157a6c/src/tests/master_validation_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_validation_tests.cpp b/src/tests/master_validation_tests.cpp
new file mode 100644
index 0000000..1277311
--- /dev/null
+++ b/src/tests/master_validation_tests.cpp
@@ -0,0 +1,156 @@
+/**
+ * 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 <google/protobuf/repeated_field.h>
+
+#include <gtest/gtest.h>
+
+#include <mesos/mesos.hpp>
+#include <mesos/resources.hpp>
+
+#include <stout/gtest.hpp>
+
+#include "master/validation.hpp"
+
+#include "tests/mesos.hpp"
+
+using namespace mesos;
+using namespace mesos::internal::tests;
+using namespace mesos::internal::master::validation;
+
+using google::protobuf::RepeatedPtrField;
+
+
+class ResourceValidationTest : public ::testing::Test
+{
+protected:
+  RepeatedPtrField<Resource> CreateResources(const Resource& resource)
+  {
+    RepeatedPtrField<Resource> resources;
+    resources.Add()->CopyFrom(resource);
+    return resources;
+  }
+};
+
+
+TEST_F(ResourceValidationTest, PersistentVolume)
+{
+  Resource volume = Resources::parse("disk", "128", "role1").get();
+  volume.mutable_disk()->CopyFrom(createDiskInfo("id1", "path1"));
+
+  EXPECT_NONE(resource::validate(CreateResources(volume)));
+}
+
+
+TEST_F(ResourceValidationTest, UnreservedDiskInfo)
+{
+  Resource volume = Resources::parse("disk", "128", "*").get();
+  volume.mutable_disk()->CopyFrom(createDiskInfo("id1", "path1"));
+
+  EXPECT_SOME(resource::validate(CreateResources(volume)));
+}
+
+
+TEST_F(ResourceValidationTest, InvalidPersistenceID)
+{
+  Resource volume = Resources::parse("disk", "128", "role1").get();
+  volume.mutable_disk()->CopyFrom(createDiskInfo("id1/", "path1"));
+
+  EXPECT_SOME(resource::validate(CreateResources(volume)));
+}
+
+
+TEST_F(ResourceValidationTest, PersistentVolumeWithoutVolumeInfo)
+{
+  Resource volume = Resources::parse("disk", "128", "role1").get();
+  volume.mutable_disk()->CopyFrom(createDiskInfo("id1", None()));
+
+  EXPECT_SOME(resource::validate(CreateResources(volume)));
+}
+
+
+TEST_F(ResourceValidationTest, ReadOnlyPersistentVolume)
+{
+  Resource volume = Resources::parse("disk", "128", "role1").get();
+  volume.mutable_disk()->CopyFrom(createDiskInfo("id1", "path1", Volume::RO));
+
+  EXPECT_SOME(resource::validate(CreateResources(volume)));
+}
+
+
+TEST_F(ResourceValidationTest, PersistentVolumeWithHostPath)
+{
+  Resource volume = Resources::parse("disk", "128", "role1").get();
+  volume.mutable_disk()->CopyFrom(
+      createDiskInfo("id1", "path1", Volume::RW, "foo"));
+
+  EXPECT_SOME(resource::validate(CreateResources(volume)));
+}
+
+
+TEST_F(ResourceValidationTest, NonPersistentVolume)
+{
+  Resource volume = Resources::parse("disk", "128", "role1").get();
+  volume.mutable_disk()->CopyFrom(createDiskInfo(None(), "path1"));
+
+  EXPECT_SOME(resource::validate(CreateResources(volume)));
+}
+
+
+class CreateOperationValidationTest : public ::testing::Test {};
+
+
+// This test verifies that all resources specified in the CREATE
+// operation are persistent volumes.
+TEST_F(CreateOperationValidationTest, PersistentVolumes)
+{
+  Resource volume = Resources::parse("disk", "128", "role1").get();
+  volume.mutable_disk()->CopyFrom(createDiskInfo("id1", "path1"));
+
+  Offer::Operation::Create create;
+  create.add_volumes()->CopyFrom(volume);
+
+  EXPECT_NONE(operation::validate(create, Resources()));
+
+  Resource cpus = Resources::parse("cpus", "2", "*").get();
+
+  create.add_volumes()->CopyFrom(cpus);
+
+  EXPECT_SOME(operation::validate(create, Resources()));
+}
+
+
+TEST_F(CreateOperationValidationTest, DuplicatedPersistenceID)
+{
+  Resource volume1 = Resources::parse("disk", "128", "role1").get();
+  volume1.mutable_disk()->CopyFrom(createDiskInfo("id1", "path1"));
+
+  Offer::Operation::Create create;
+  create.add_volumes()->CopyFrom(volume1);
+
+  EXPECT_NONE(operation::validate(create, Resources()));
+
+  Resource volume2 = Resources::parse("disk", "64", "role1").get();
+  volume2.mutable_disk()->CopyFrom(createDiskInfo("id1", "path1"));
+
+  EXPECT_SOME(operation::validate(create, volume1));
+
+  create.add_volumes()->CopyFrom(volume2);
+
+  EXPECT_SOME(operation::validate(create, Resources()));
+}

http://git-wip-us.apache.org/repos/asf/mesos/blob/66157a6c/src/tests/resource_offers_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/resource_offers_tests.cpp b/src/tests/resource_offers_tests.cpp
index 24a7eab..3e529ba 100644
--- a/src/tests/resource_offers_tests.cpp
+++ b/src/tests/resource_offers_tests.cpp
@@ -553,446 +553,6 @@ TEST_F(TaskValidationTest, ExecutorInfoDiffersOnDifferentSlaves)
 }
 
 
-// TODO(jieyu): Disable all persistent volume related tests for now.
-// Those tests should be moved to OfferOperationValidationTest.
-TEST_F(TaskValidationTest, DISABLED_UnreservedDiskInfo)
-{
-  Try<PID<Master>> master = StartMaster();
-  ASSERT_SOME(master);
-
-  Try<PID<Slave>> slave = StartSlave();
-  ASSERT_SOME(slave);
-
-  MockScheduler sched;
-  MesosSchedulerDriver driver(
-      &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
-
-  EXPECT_CALL(sched, registered(&driver, _, _))
-    .Times(1);
-
-  Future<vector<Offer>> offers;
-  EXPECT_CALL(sched, resourceOffers(&driver, _))
-    .WillOnce(FutureArg<1>(&offers))
-    .WillRepeatedly(Return()); // Ignore subsequent offers.
-
-  driver.start();
-
-  AWAIT_READY(offers);
-  EXPECT_NE(0u, offers.get().size());
-
-  // Create a persistent volume with "*" role.
-  Resource diskResource = Resources::parse("disk", "128", "*").get();
-  diskResource.mutable_disk()->CopyFrom(createDiskInfo("1", "1"));
-
-  // Include other resources in task resources.
-  Resources taskResources =
-    Resources::parse("cpus:1;mem:128").get() + diskResource;
-
-  Offer offer = offers.get()[0];
-  TaskInfo task =
-    createTask(offer.slave_id(), taskResources, "", DEFAULT_EXECUTOR_ID);
-
-  vector<TaskInfo> tasks;
-  tasks.push_back(task);
-
-  Future<TaskStatus> status;
-  EXPECT_CALL(sched, statusUpdate(&driver, _))
-    .WillOnce(FutureArg<1>(&status));
-
-  driver.launchTasks(offer.id(), tasks);
-
-  AWAIT_READY(status);
-  EXPECT_EQ(task.task_id(), status.get().task_id());
-  EXPECT_EQ(TASK_ERROR, status.get().state());
-  EXPECT_EQ(TaskStatus::REASON_TASK_INVALID, status.get().reason());
-  EXPECT_TRUE(status.get().has_message());
-  EXPECT_TRUE(strings::contains(
-      status.get().message(),
-      "Persistent disk volume is disallowed for '*' role"));
-
-  driver.stop();
-  driver.join();
-
-  Shutdown();
-}
-
-
-TEST_F(TaskValidationTest, DISABLED_InvalidPersistenceID)
-{
-  Try<PID<Master>> master = StartMaster();
-  ASSERT_SOME(master);
-
-  Try<PID<Slave>> slave = StartSlave();
-  ASSERT_SOME(slave);
-
-  MockScheduler sched;
-  MesosSchedulerDriver driver(
-      &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
-
-  EXPECT_CALL(sched, registered(&driver, _, _))
-    .Times(1);
-
-  Future<vector<Offer>> offers;
-  EXPECT_CALL(sched, resourceOffers(&driver, _))
-    .WillOnce(FutureArg<1>(&offers))
-    .WillRepeatedly(Return()); // Ignore subsequent offers.
-
-  driver.start();
-
-  AWAIT_READY(offers);
-  EXPECT_NE(0u, offers.get().size());
-
-  // Create a persistent volume with an invalid persistence id.
-  Resource diskResource = Resources::parse("disk", "128", "role1").get();
-  diskResource.mutable_disk()->CopyFrom(createDiskInfo("1/", "1"));
-
-  // Include other resources in task resources.
-  Resources taskResources =
-    Resources::parse("cpus:1;mem:128").get() + diskResource;
-
-  Offer offer = offers.get()[0];
-  TaskInfo task =
-    createTask(offer.slave_id(), taskResources, "", DEFAULT_EXECUTOR_ID);
-
-  vector<TaskInfo> tasks;
-  tasks.push_back(task);
-
-  Future<TaskStatus> status;
-  EXPECT_CALL(sched, statusUpdate(&driver, _))
-    .WillOnce(FutureArg<1>(&status));
-
-  driver.launchTasks(offer.id(), tasks);
-
-  AWAIT_READY(status);
-  EXPECT_EQ(task.task_id(), status.get().task_id());
-  EXPECT_EQ(TASK_ERROR, status.get().state());
-  EXPECT_EQ(TaskStatus::REASON_TASK_INVALID, status.get().reason());
-  EXPECT_TRUE(status.get().has_message());
-  EXPECT_TRUE(strings::contains(
-      status.get().message(),
-      "Persistence ID '1/' contains invalid characters"));
-
-  driver.stop();
-  driver.join();
-
-  Shutdown();
-}
-
-
-TEST_F(TaskValidationTest, DISABLED_PersistentDiskInfoWithoutVolume)
-{
-  Try<PID<Master>> master = StartMaster();
-  ASSERT_SOME(master);
-
-  Try<PID<Slave>> slave = StartSlave();
-  ASSERT_SOME(slave);
-
-  MockScheduler sched;
-  MesosSchedulerDriver driver(
-      &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
-
-  EXPECT_CALL(sched, registered(&driver, _, _))
-    .Times(1);
-
-  Future<vector<Offer>> offers;
-  EXPECT_CALL(sched, resourceOffers(&driver, _))
-    .WillOnce(FutureArg<1>(&offers))
-    .WillRepeatedly(Return()); // Ignore subsequent offers.
-
-  driver.start();
-
-  AWAIT_READY(offers);
-  EXPECT_NE(0u, offers.get().size());
-
-  // Create a persistent volume no volume information.
-  Resource diskResource = Resources::parse("disk", "128", "role1").get();
-  diskResource.mutable_disk()->CopyFrom(createDiskInfo("1", None()));
-
-  // Include other resources in task resources.
-  Resources taskResources =
-    Resources::parse("cpus:1;mem:128").get() + diskResource;
-
-  Offer offer = offers.get()[0];
-  TaskInfo task =
-    createTask(offer.slave_id(), taskResources, "", DEFAULT_EXECUTOR_ID);
-
-  vector<TaskInfo> tasks;
-  tasks.push_back(task);
-
-  Future<TaskStatus> status;
-  EXPECT_CALL(sched, statusUpdate(&driver, _))
-    .WillOnce(FutureArg<1>(&status));
-
-  driver.launchTasks(offer.id(), tasks);
-
-  AWAIT_READY(status);
-  EXPECT_EQ(task.task_id(), status.get().task_id());
-  EXPECT_EQ(TASK_ERROR, status.get().state());
-  EXPECT_EQ(TaskStatus::REASON_TASK_INVALID, status.get().reason());
-  EXPECT_TRUE(status.get().has_message());
-  EXPECT_TRUE(strings::contains(
-      status.get().message(),
-      "Persistent disk should specify a volume"));
-
-  driver.stop();
-  driver.join();
-
-  Shutdown();
-}
-
-
-TEST_F(TaskValidationTest, DISABLED_PersistentDiskInfoWithReadOnlyVolume)
-{
-  Try<PID<Master>> master = StartMaster();
-  ASSERT_SOME(master);
-
-  Try<PID<Slave>> slave = StartSlave();
-  ASSERT_SOME(slave);
-
-  MockScheduler sched;
-  MesosSchedulerDriver driver(
-      &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
-
-  EXPECT_CALL(sched, registered(&driver, _, _))
-    .Times(1);
-
-  Future<vector<Offer>> offers;
-  EXPECT_CALL(sched, resourceOffers(&driver, _))
-    .WillOnce(FutureArg<1>(&offers))
-    .WillRepeatedly(Return()); // Ignore subsequent offers.
-
-  driver.start();
-
-  AWAIT_READY(offers);
-  EXPECT_NE(0u, offers.get().size());
-
-  // Create a read-only persistent volume.
-  Resource diskResource = Resources::parse("disk", "128", "role1").get();
-  diskResource.mutable_disk()->CopyFrom(createDiskInfo("1", "1", Volume::RO));
-
-  // Include other resources in task resources.
-  Resources taskResources =
-    Resources::parse("cpus:1;mem:128").get() + diskResource;
-
-  Offer offer = offers.get()[0];
-  TaskInfo task =
-    createTask(offer.slave_id(), taskResources, "", DEFAULT_EXECUTOR_ID);
-
-  vector<TaskInfo> tasks;
-  tasks.push_back(task);
-
-  Future<TaskStatus> status;
-  EXPECT_CALL(sched, statusUpdate(&driver, _))
-    .WillOnce(FutureArg<1>(&status));
-
-  driver.launchTasks(offer.id(), tasks);
-
-  AWAIT_READY(status);
-  EXPECT_EQ(task.task_id(), status.get().task_id());
-  EXPECT_EQ(TASK_ERROR, status.get().state());
-  EXPECT_EQ(TaskStatus::REASON_TASK_INVALID, status.get().reason());
-  EXPECT_TRUE(status.get().has_message());
-  EXPECT_TRUE(strings::contains(
-      status.get().message(),
-      "Read-only volume is not supported for DiskInfo"));
-
-  driver.stop();
-  driver.join();
-
-  Shutdown();
-}
-
-
-TEST_F(TaskValidationTest, DISABLED_PersistentDiskInfoWithHostPath)
-{
-  Try<PID<Master>> master = StartMaster();
-  ASSERT_SOME(master);
-
-  Try<PID<Slave>> slave = StartSlave();
-  ASSERT_SOME(slave);
-
-  MockScheduler sched;
-  MesosSchedulerDriver driver(
-      &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
-
-  EXPECT_CALL(sched, registered(&driver, _, _))
-    .Times(1);
-
-  Future<vector<Offer>> offers;
-  EXPECT_CALL(sched, resourceOffers(&driver, _))
-    .WillOnce(FutureArg<1>(&offers))
-    .WillRepeatedly(Return()); // Ignore subsequent offers.
-
-  driver.start();
-
-  AWAIT_READY(offers);
-  EXPECT_NE(0u, offers.get().size());
-
-  // Create a persistent volume with host path.
-  Resource diskResource = Resources::parse("disk", "128", "role1").get();
-  diskResource.mutable_disk()->CopyFrom(
-      createDiskInfo("1", "1", Volume::RW, "foo"));
-
-  // Include other resources in task resources.
-  Resources taskResources =
-    Resources::parse("cpus:1;mem:128").get() + diskResource;
-
-  Offer offer = offers.get()[0];
-  TaskInfo task =
-    createTask(offer.slave_id(), taskResources, "", DEFAULT_EXECUTOR_ID);
-
-  vector<TaskInfo> tasks;
-  tasks.push_back(task);
-
-  Future<TaskStatus> status;
-  EXPECT_CALL(sched, statusUpdate(&driver, _))
-    .WillOnce(FutureArg<1>(&status));
-
-  driver.launchTasks(offer.id(), tasks);
-
-  AWAIT_READY(status);
-  EXPECT_EQ(task.task_id(), status.get().task_id());
-  EXPECT_EQ(TASK_ERROR, status.get().state());
-  EXPECT_EQ(TaskStatus::REASON_TASK_INVALID, status.get().reason());
-  EXPECT_TRUE(status.get().has_message());
-  EXPECT_TRUE(strings::contains(
-      status.get().message(),
-      "Volume in DiskInfo should not have 'host_path' set"));
-
-  driver.stop();
-  driver.join();
-
-  Shutdown();
-}
-
-
-TEST_F(TaskValidationTest, DISABLED_NonPersistentDiskInfoWithVolume)
-{
-  Try<PID<Master>> master = StartMaster();
-  ASSERT_SOME(master);
-
-  Try<PID<Slave>> slave = StartSlave();
-  ASSERT_SOME(slave);
-
-  MockScheduler sched;
-  MesosSchedulerDriver driver(
-      &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
-
-  EXPECT_CALL(sched, registered(&driver, _, _))
-    .Times(1);
-
-  Future<vector<Offer>> offers;
-  EXPECT_CALL(sched, resourceOffers(&driver, _))
-    .WillOnce(FutureArg<1>(&offers))
-    .WillRepeatedly(Return()); // Ignore subsequent offers.
-
-  driver.start();
-
-  AWAIT_READY(offers);
-  EXPECT_NE(0u, offers.get().size());
-
-  // Create a non-persistent volume.
-  Resource diskResource = Resources::parse("disk", "128", "role1").get();
-  diskResource.mutable_disk()->CopyFrom(createDiskInfo(None(), "1"));
-
-  // Include other resources in task resources.
-  Resources taskResources =
-    Resources::parse("cpus:1;mem:128").get() + diskResource;
-
-  Offer offer = offers.get()[0];
-  TaskInfo task =
-    createTask(offer.slave_id(), taskResources, "", DEFAULT_EXECUTOR_ID);
-
-  vector<TaskInfo> tasks;
-  tasks.push_back(task);
-
-  Future<TaskStatus> status;
-  EXPECT_CALL(sched, statusUpdate(&driver, _))
-    .WillOnce(FutureArg<1>(&status));
-
-  driver.launchTasks(offer.id(), tasks);
-
-  AWAIT_READY(status);
-  EXPECT_EQ(task.task_id(), status.get().task_id());
-  EXPECT_EQ(TASK_ERROR, status.get().state());
-  EXPECT_EQ(TaskStatus::REASON_TASK_INVALID, status.get().reason());
-  EXPECT_TRUE(status.get().has_message());
-  EXPECT_TRUE(strings::contains(
-      status.get().message(),
-      "Non-persistent volume is not supported"));
-
-  driver.stop();
-  driver.join();
-
-  Shutdown();
-}
-
-
-TEST_F(TaskValidationTest, DISABLED_DuplicatedPersistenceIDWithinTask)
-{
-  Try<PID<Master>> master = StartMaster();
-  ASSERT_SOME(master);
-
-  Try<PID<Slave>> slave = StartSlave();
-  ASSERT_SOME(slave);
-
-  MockScheduler sched;
-  MesosSchedulerDriver driver(
-      &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
-
-  EXPECT_CALL(sched, registered(&driver, _, _))
-    .Times(1);
-
-  Future<vector<Offer>> offers;
-  EXPECT_CALL(sched, resourceOffers(&driver, _))
-    .WillOnce(FutureArg<1>(&offers))
-    .WillRepeatedly(Return()); // Ignore subsequent offers.
-
-  driver.start();
-
-  AWAIT_READY(offers);
-  EXPECT_NE(0u, offers.get().size());
-
-  // Create two persistent volumes with the same id.
-  Resource diskResource1 = Resources::parse("disk", "128", "role1").get();
-  diskResource1.mutable_disk()->CopyFrom(createDiskInfo("1", "1"));
-
-  Resource diskResource2 = Resources::parse("disk", "64", "role1").get();
-  diskResource2.mutable_disk()->CopyFrom(createDiskInfo("1", "1"));
-
-  // Include other resources in task resources.
-  Resources taskResources =
-    Resources::parse("cpus:1;mem:128").get() + diskResource1 + diskResource2;
-
-  Offer offer = offers.get()[0];
-  TaskInfo task =
-    createTask(offer.slave_id(), taskResources, "", DEFAULT_EXECUTOR_ID);
-
-  vector<TaskInfo> tasks;
-  tasks.push_back(task);
-
-  Future<TaskStatus> status;
-  EXPECT_CALL(sched, statusUpdate(&driver, _))
-    .WillOnce(FutureArg<1>(&status));
-
-  driver.launchTasks(offer.id(), tasks);
-
-  AWAIT_READY(status);
-  EXPECT_EQ(task.task_id(), status.get().task_id());
-  EXPECT_EQ(TASK_ERROR, status.get().state());
-  EXPECT_EQ(TaskStatus::REASON_TASK_INVALID, status.get().reason());
-  EXPECT_TRUE(status.get().has_message());
-  EXPECT_TRUE(strings::contains(
-      status.get().message(),
-      "Task uses duplicated persistence ID 1"));
-
-  driver.stop();
-  driver.join();
-
-  Shutdown();
-}
-
-
 // This test ensures that a persistent volume that is larger than the
 // offered disk resources results in a failed task.
 TEST_F(TaskValidationTest, DISABLED_AcquirePersistentDiskTooBig)