Repository: mesos Updated Branches: refs/heads/master 41b495ecf -> 1b592c167
Added support for removing capabilities on framework re-registration. Review: https://reviews.apache.org/r/37501 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/1b592c16 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/1b592c16 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/1b592c16 Branch: refs/heads/master Commit: 1b592c16721576eddc4e7ce1167784ef5c43c111 Parents: 41b495e Author: Aditi Dixit <[email protected]> Authored: Mon Aug 24 15:53:07 2015 -0700 Committer: Vinod Kone <[email protected]> Committed: Mon Aug 24 15:53:08 2015 -0700 ---------------------------------------------------------------------- src/master/allocator/mesos/hierarchical.hpp | 2 + src/master/master.hpp | 5 +- src/tests/oversubscription_tests.cpp | 99 ++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/1b592c16/src/master/allocator/mesos/hierarchical.hpp ---------------------------------------------------------------------- diff --git a/src/master/allocator/mesos/hierarchical.hpp b/src/master/allocator/mesos/hierarchical.hpp index e278139..38f8fd2 100644 --- a/src/master/allocator/mesos/hierarchical.hpp +++ b/src/master/allocator/mesos/hierarchical.hpp @@ -492,6 +492,8 @@ HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::updateFramework( CHECK_EQ(frameworks[frameworkId].role, frameworkInfo.role()); CHECK_EQ(frameworks[frameworkId].checkpoint, frameworkInfo.checkpoint()); + frameworks[frameworkId].revocable = false; + foreach (const FrameworkInfo::Capability& capability, frameworkInfo.capabilities()) { if (capability.type() == FrameworkInfo::Capability::REVOCABLE_RESOURCES) { http://git-wip-us.apache.org/repos/asf/mesos/blob/1b592c16/src/master/master.hpp ---------------------------------------------------------------------- diff --git a/src/master/master.hpp b/src/master/master.hpp index 0432842..36c6759 100644 --- a/src/master/master.hpp +++ b/src/master/master.hpp @@ -1563,11 +1563,10 @@ struct Framework info.clear_webui_url(); } - // TODO(aditidixit): Add the case where the capabilities are - // previously set but now being unset. (MESOS-2880) - if (source.capabilities_size() > 0) { info.mutable_capabilities()->CopyFrom(source.capabilities()); + } else { + info.clear_capabilities(); } if (source.has_labels()) { http://git-wip-us.apache.org/repos/asf/mesos/blob/1b592c16/src/tests/oversubscription_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/oversubscription_tests.cpp b/src/tests/oversubscription_tests.cpp index d41f030..0c5edaf 100644 --- a/src/tests/oversubscription_tests.cpp +++ b/src/tests/oversubscription_tests.cpp @@ -997,6 +997,105 @@ TEST_F(OversubscriptionTest, UpdateAllocatorOnSchedulerFailover) Shutdown(); } +TEST_F(OversubscriptionTest, RemoveCapabilitiesOnSchedulerFailover) +{ + // Start the master. + Try<PID<Master>> master = StartMaster(); + ASSERT_SOME(master); + + // Start the slave with mock executor and test resource estimator. + MockExecutor exec(DEFAULT_EXECUTOR_ID); + + MockResourceEstimator resourceEstimator; + + EXPECT_CALL(resourceEstimator, initialize(_)); + + Queue<Resources> estimations; + EXPECT_CALL(resourceEstimator, oversubscribable()) + .WillOnce(InvokeWithoutArgs(&estimations, &Queue<Resources>::get)); + + slave::Flags flags = CreateSlaveFlags(); + + Try<PID<Slave>> slave = StartSlave(&exec, &resourceEstimator, flags); + ASSERT_SOME(slave); + + // Start the framework which accepts revocable resources. + FrameworkInfo framework1 = DEFAULT_FRAMEWORK_INFO; + framework1.add_capabilities()->set_type( + FrameworkInfo::Capability::REVOCABLE_RESOURCES); + + MockScheduler sched1; + MesosSchedulerDriver driver1( + &sched1, framework1, master.get(), DEFAULT_CREDENTIAL); + + Future<FrameworkID> frameworkId; + EXPECT_CALL(sched1, registered(&driver1, _, _)) + .WillOnce(FutureArg<1>(&frameworkId)); + + Future<vector<Offer>> offers1; + EXPECT_CALL(sched1, resourceOffers(&driver1, _)) + .WillOnce(FutureArg<1>(&offers1)); + + driver1.start(); + + // Initially the framework will get all regular resources. + AWAIT_READY(offers1); + EXPECT_NE(0u, offers1.get().size()); + EXPECT_TRUE(Resources(offers1.get()[0].resources()).revocable().empty()); + + Future<vector<Offer>> offers2; + EXPECT_CALL(sched1, resourceOffers(&driver1, _)) + .WillOnce(FutureArg<1>(&offers2)) + .WillRepeatedly(Return()); // Ignore subsequent offers. + + // Inject an estimation of oversubscribable cpu resources. + Resources taskResources = createRevocableResources("cpus", "1"); + Resources executorResources = createRevocableResources("cpus", "1"); + estimations.put(taskResources + executorResources); + + // Now the framework will get revocable resources. + AWAIT_READY(offers2); + EXPECT_NE(0u, offers2.get().size()); + EXPECT_EQ( + taskResources + executorResources, + Resources(offers2.get()[0].resources())); + + // Reregister the framework with removal of revocable resources capability. + FrameworkInfo framework2 = DEFAULT_FRAMEWORK_INFO; + framework2.mutable_id()->MergeFrom(frameworkId.get()); + + MockScheduler sched2; + MesosSchedulerDriver driver2( + &sched2, framework2, master.get(), DEFAULT_CREDENTIAL); + + EXPECT_CALL(sched2, registered(&driver2, _, _)); + + // Scheduler1's expectations. + + EXPECT_CALL(sched1, offerRescinded(&driver1, _)) + .Times(AtMost(1)); + + Future<Nothing> sched1Error; + EXPECT_CALL(sched1, error(&driver1, "Framework failed over")) + .WillOnce(FutureSatisfy(&sched1Error)); + + Future<vector<Offer>> offers3; + EXPECT_CALL(sched2, resourceOffers(&driver2, _)) + .WillOnce(FutureArg<1>(&offers3)) + .WillRepeatedly(Return()); + + driver2.start(); + + AWAIT_READY(offers3); + EXPECT_NE(0u, offers3.get().size()); + EXPECT_TRUE(Resources(offers3.get()[0].resources()).revocable().empty()); + + driver1.stop(); + driver1.join(); + + Shutdown(); +} + } // namespace tests { } // namespace internal { } // namespace mesos {
