Enabled Resources::apply to handle reservation operations. Review: https://reviews.apache.org/r/32149
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/7cbd5244 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/7cbd5244 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/7cbd5244 Branch: refs/heads/master Commit: 7cbd5244d4a08d32742c729b14430a66a4f9e1ce Parents: 2d28816 Author: Michael Park <[email protected]> Authored: Sun May 3 11:53:03 2015 -0700 Committer: Jie Yu <[email protected]> Committed: Sun May 3 13:08:43 2015 -0700 ---------------------------------------------------------------------- src/common/resources.cpp | 55 +++++++++++++++++++++++++++++++++++--- src/tests/resources_tests.cpp | 43 +++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/7cbd5244/src/common/resources.cpp ---------------------------------------------------------------------- diff --git a/src/common/resources.cpp b/src/common/resources.cpp index b092352..235930f 100644 --- a/src/common/resources.cpp +++ b/src/common/resources.cpp @@ -698,10 +698,57 @@ Try<Resources> Resources::apply(const Offer::Operation& operation) const // Launch operation does not alter the offered resources. break; - case Offer::Operation::RESERVE: - case Offer::Operation::UNRESERVE: - // TODO(mpark): Provide implementation. - return Error("Unimplemented"); + case Offer::Operation::RESERVE: { + Option<Error> error = validate(operation.reserve().resources()); + if (error.isSome()) { + return Error("Invalid RESERVE Operation: " + error.get().message); + } + + foreach (const Resource& reserved, operation.reserve().resources()) { + if (!Resources::isReserved(reserved)) { + return Error("Invalid RESERVE Operation: Resource must be reserved"); + } else if (!reserved.has_reservation()) { + return Error("Invalid RESERVE Operation: Missing 'reservation'"); + } + + Resources unreserved = Resources(reserved).flatten(); + + if (!result.contains(unreserved)) { + return Error("Invalid RESERVE Operation: " + stringify(result) + + " does not contain " + stringify(unreserved)); + } + + result -= unreserved; + result += reserved; + } + break; + } + + case Offer::Operation::UNRESERVE: { + Option<Error> error = validate(operation.unreserve().resources()); + if (error.isSome()) { + return Error("Invalid UNRESERVE Operation: " + error.get().message); + } + + foreach (const Resource& reserved, operation.unreserve().resources()) { + if (!Resources::isReserved(reserved)) { + return Error("Invalid UNRESERVE Operation: Resource is not reserved"); + } else if (!reserved.has_reservation()) { + return Error("Invalid UNRESERVE Operation: Missing 'reservation'"); + } + + if (!result.contains(reserved)) { + return Error("Invalid UNRESERVE Operation: " + stringify(result) + + " does not contain " + stringify(reserved)); + } + + Resources unreserved = Resources(reserved).flatten(); + + result -= reserved; + result += unreserved; + } + break; + } case Offer::Operation::CREATE: { Option<Error> error = validate(operation.create().volumes()); http://git-wip-us.apache.org/repos/asf/mesos/blob/7cbd5244/src/tests/resources_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/resources_tests.cpp b/src/tests/resources_tests.cpp index 58d7946..a7ec59e 100644 --- a/src/tests/resources_tests.cpp +++ b/src/tests/resources_tests.cpp @@ -1080,6 +1080,49 @@ TEST(DiskResourcesTest, FilterPersistentVolumes) } +TEST(ResourcesOperationTest, ReserveResources) +{ + Resources unreservedCpus = Resources::parse("cpus:1").get(); + Resources unreservedMem = Resources::parse("mem:512").get(); + + Resources unreserved = unreservedCpus + unreservedMem; + + Resources reservedCpus1 = + unreservedCpus.flatten("role", createReservationInfo("principal")); + + EXPECT_SOME_EQ(unreservedMem + reservedCpus1, + unreserved.apply(RESERVE(reservedCpus1))); + + // Check the case of insufficient unreserved resources. + Resources reservedCpus2 = createReservedResource( + "cpus", "2", "role", createReservationInfo("principal")); + + EXPECT_ERROR(unreserved.apply(RESERVE(reservedCpus2))); +} + + +TEST(ResourcesOperationTest, UnreserveResources) +{ + Resources reservedCpus = createReservedResource( + "cpus", "1", "role", createReservationInfo("principal")); + Resources reservedMem = createReservedResource( + "mem", "512", "role", createReservationInfo("principal")); + + Resources reserved = reservedCpus + reservedMem; + + Resources unreservedCpus1 = reservedCpus.flatten(); + + EXPECT_SOME_EQ(reservedMem + unreservedCpus1, + reserved.apply(UNRESERVE(reservedCpus))); + + // Check the case of insufficient unreserved resources. + Resource reservedCpus2 = createReservedResource( + "cpus", "2", "role", createReservationInfo("principal")); + + EXPECT_ERROR(reserved.apply(UNRESERVE(reservedCpus2))); +} + + TEST(ResourcesOperationTest, CreatePersistentVolume) { Resources total = Resources::parse("cpus:1;mem:512;disk(role):1000").get();
