Repository: mesos Updated Branches: refs/heads/master 40a1626f1 -> 65c1450f2
Added registry tests for /weights endpoint. Review: https://reviews.apache.org/r/44511/ Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/92dd4f27 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/92dd4f27 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/92dd4f27 Branch: refs/heads/master Commit: 92dd4f27507814932bf58a203bbcf670769d15cb Parents: 40a1626 Author: Yongqiao Wang <yq...@cn.ibm.com> Authored: Thu Mar 24 00:25:55 2016 -0700 Committer: Adam B <a...@mesosphere.io> Committed: Thu Mar 24 00:25:55 2016 -0700 ---------------------------------------------------------------------- src/tests/dynamic_weights_tests.cpp | 140 ++++++++++++++++++++++++++++--- src/tests/registrar_tests.cpp | 83 ++++++++++++++++++ 2 files changed, 212 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/92dd4f27/src/tests/dynamic_weights_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/dynamic_weights_tests.cpp b/src/tests/dynamic_weights_tests.cpp index ee0c4b1..6357cf4 100644 --- a/src/tests/dynamic_weights_tests.cpp +++ b/src/tests/dynamic_weights_tests.cpp @@ -185,7 +185,7 @@ protected: " }" " ]" "}"); - } else if (weights == UPDATED_WEIGHTS) { + } else if (weights == UPDATED_WEIGHTS1) { expected = JSON::parse( "{" " \"roles\": [" @@ -221,6 +221,52 @@ protected: " }" " ]" "}"); + } else if (weights == UPDATED_WEIGHTS2) { + expected = JSON::parse( + "{" + " \"roles\": [" + " {" + " \"frameworks\": []," + " \"name\": \"*\"," + " \"resources\": {" + " \"cpus\": 0," + " \"disk\": 0," + " \"mem\": 0" + " }," + " \"weight\": 1.0" + " }," + " {" + " \"frameworks\": []," + " \"name\": \"role1\"," + " \"resources\": {" + " \"cpus\": 0," + " \"disk\": 0," + " \"mem\": 0" + " }," + " \"weight\": 1.0" + " }," + " {" + " \"frameworks\": []," + " \"name\": \"role2\"," + " \"resources\": {" + " \"cpus\": 0," + " \"disk\": 0," + " \"mem\": 0" + " }," + " \"weight\": 4.0" + " }," + " {" + " \"frameworks\": []," + " \"name\": \"role3\"," + " \"resources\": {" + " \"cpus\": 0," + " \"disk\": 0," + " \"mem\": 0" + " }," + " \"weight\": 2.5" + " }" + " ]" + "}"); } else { expected = Error("Unexpected weights string."); } @@ -233,7 +279,8 @@ protected: const string ROLE1 = "role1"; const string ROLE2 = "role2"; const string DEFAULT_WEIGHTS = "role1=1.0,role2=1.0"; - const string UPDATED_WEIGHTS = "role1=2.0,role2=4.0"; + const string UPDATED_WEIGHTS1 = "role1=2.0,role2=4.0"; + const string UPDATED_WEIGHTS2 = "role1=1.0,role3=2.5"; }; @@ -449,12 +496,12 @@ TEST_F(DynamicWeightsTest, UpdateWeightsWithExplictRoles) false, "weights", createBasicAuthHeaders(DEFAULT_CREDENTIAL), - createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS)))); + createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS1)))); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response) << response.get().body; - checkWithRolesEndpoint(master.get()->pid, UPDATED_WEIGHTS); + checkWithRolesEndpoint(master.get()->pid, UPDATED_WEIGHTS1); } @@ -479,7 +526,7 @@ TEST_F(DynamicWeightsTest, UnauthenticatedUpdateWeightRequest) false, "weights", createBasicAuthHeaders(credential), - createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS)))); + createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS1)))); AWAIT_EXPECT_RESPONSE_STATUS_EQ(Unauthorized({}).status, response1) << response1.get().body; @@ -494,7 +541,7 @@ TEST_F(DynamicWeightsTest, UnauthenticatedUpdateWeightRequest) false, "weights", None(), - createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS)))); + createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS1)))); AWAIT_EXPECT_RESPONSE_STATUS_EQ(Unauthorized({}).status, response2) << response2.get().body; @@ -529,12 +576,12 @@ TEST_F(DynamicWeightsTest, AuthorizedWeightUpdateRequest) false, "weights", createBasicAuthHeaders(DEFAULT_CREDENTIAL), - createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS)))); + createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS1)))); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response) << response.get().body; - checkWithRolesEndpoint(master.get()->pid, UPDATED_WEIGHTS); + checkWithRolesEndpoint(master.get()->pid, UPDATED_WEIGHTS1); } @@ -568,12 +615,12 @@ TEST_F(DynamicWeightsTest, AuthorizedUpdateWeightRequestWithoutPrincipal) false, "weights", None(), - createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS)))); + createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS1)))); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response) << response.get().body; - checkWithRolesEndpoint(master.get()->pid, UPDATED_WEIGHTS); + checkWithRolesEndpoint(master.get()->pid, UPDATED_WEIGHTS1); } @@ -599,7 +646,7 @@ TEST_F(DynamicWeightsTest, UnauthorizedWeightUpdateRequest) false, "weights", createBasicAuthHeaders(DEFAULT_CREDENTIAL), - createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS)))); + createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS1)))); AWAIT_EXPECT_RESPONSE_STATUS_EQ(Forbidden().status, response) << response.get().body; @@ -607,6 +654,77 @@ TEST_F(DynamicWeightsTest, UnauthorizedWeightUpdateRequest) checkWithRolesEndpoint(master.get()->pid); } + +// Checks that the weights information can be recovered from the registry. +TEST_F(DynamicWeightsTest, RecoveredWeightsFromRegistry) +{ + // Start a master with `--weights` flag. + master::Flags masterFlags = CreateMasterFlags(); + masterFlags.weights = UPDATED_WEIGHTS1; + Try<Owned<cluster::Master>> master = StartMaster(masterFlags); + ASSERT_SOME(master); + + // Tests whether the weights replicated log is initialized with the + // `--weights` flag when bootstrapping the cluster. + { + checkWithRolesEndpoint(master.get()->pid, UPDATED_WEIGHTS1); + + // Stop the master + master->reset(); + + // Restart the master. + masterFlags.weights = None(); + master = StartMaster(masterFlags); + ASSERT_SOME(master); + + checkWithRolesEndpoint(master.get()->pid, UPDATED_WEIGHTS1); + } + + // Tests whether the weights replicated log can be updated with + // `/weights` endpoint. + { + // Send a weights update request for the specified roles. + Future<Response> response = process::http::request( + process::http::createRequest( + master.get()->pid, + "PUT", + false, + "weights", + createBasicAuthHeaders(DEFAULT_CREDENTIAL), + createUpdateRequestBody(createWeightInfos(UPDATED_WEIGHTS2)))); + + AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response) + << response.get().body; + + checkWithRolesEndpoint(master.get()->pid, UPDATED_WEIGHTS2); + + // Stop the master + master->reset(); + + // Restart the master without `--weights` flag. + masterFlags.weights = None(); + master = StartMaster(masterFlags); + ASSERT_SOME(master); + + checkWithRolesEndpoint(master.get()->pid, UPDATED_WEIGHTS2); + } + + // Tests whether the `--weights` flag is ignored and use the registry value + // instead when Mesos master subsequently starts with `--weights` flag + // still specified. + { + // Stop the master + master->reset(); + + // Restart the master with `--weights` flag. + masterFlags.weights = UPDATED_WEIGHTS1; + master = StartMaster(masterFlags); + ASSERT_SOME(master); + + checkWithRolesEndpoint(master.get()->pid, UPDATED_WEIGHTS2); + } +} + } // namespace tests { } // namespace internal { } // namespace mesos { http://git-wip-us.apache.org/repos/asf/mesos/blob/92dd4f27/src/tests/registrar_tests.cpp ---------------------------------------------------------------------- diff --git a/src/tests/registrar_tests.cpp b/src/tests/registrar_tests.cpp index c330af2..6f1ddf5 100644 --- a/src/tests/registrar_tests.cpp +++ b/src/tests/registrar_tests.cpp @@ -50,6 +50,7 @@ #include "master/master.hpp" #include "master/quota.hpp" #include "master/registrar.hpp" +#include "master/weights.hpp" #include "state/log.hpp" #include "state/protobuf.hpp" @@ -90,12 +91,14 @@ namespace internal { namespace tests { namespace quota = mesos::internal::master::quota; +namespace weights = mesos::internal::master::weights; using namespace mesos::maintenance; using namespace mesos::quota; using namespace mesos::internal::master::maintenance; using namespace mesos::internal::master::quota; +using namespace mesos::internal::master::weights; using state::Entry; using state::LogStorage; @@ -103,6 +106,22 @@ using state::Storage; using state::protobuf::State; + +static vector<WeightInfo> getWeightInfos( + const hashmap<string, double>& weights) { + vector<WeightInfo> weightInfos; + + foreachpair (const string& role, double weight, weights) { + WeightInfo weightInfo; + weightInfo.set_role(role); + weightInfo.set_weight(weight); + weightInfos.push_back(weightInfo); + } + + return weightInfos; +} + + // TODO(xujyan): This class copies code from LogStateTest. It would // be nice to find a common location for log related base tests when // there are more uses of it. @@ -879,6 +898,70 @@ TEST_P(RegistrarTest, RemoveQuota) } +// Tests that updating weights in the registry works properly. +TEST_P(RegistrarTest, UpdateWeights) +{ + const string ROLE1 = "role1"; + double WEIGHT1 = 2.0; + double UPDATED_WEIGHT1 = 1.0; + + const string ROLE2 = "role2"; + double WEIGHT2 = 3.5; + + { + hashmap<string, double> weights; + weights[ROLE1] = WEIGHT1; + vector<WeightInfo> weightInfos = getWeightInfos(weights); + + // Prepare the registrar. + Registrar registrar(flags, state); + Future<Registry> registry = registrar.recover(master); + AWAIT_READY(registry); + + ASSERT_EQ(0, registry.get().weights_size()); + + // Store the weight for 'ROLE1' without weight in registry before. + AWAIT_EQ(true, registrar.apply( + Owned<Operation>(new UpdateWeights(weightInfos)))); + } + + { + hashmap<string, double> weights; + weights[ROLE1] = UPDATED_WEIGHT1; + weights[ROLE2] = WEIGHT2; + vector<WeightInfo> weightInfos = getWeightInfos(weights); + + Registrar registrar(flags, state); + Future<Registry> registry = registrar.recover(master); + AWAIT_READY(registry); + + // Check that the recovered weights matches the weights we stored + // previously. + ASSERT_EQ(1, registry.get().weights_size()); + EXPECT_EQ(ROLE1, registry.get().weights(0).info().role()); + ASSERT_EQ(WEIGHT1, registry.get().weights(0).info().weight()); + + // Change weight for 'ROLE1', and store the weight for 'ROLE2'. + AWAIT_EQ(true, registrar.apply( + Owned<Operation>(new UpdateWeights(weightInfos)))); + } + + { + Registrar registrar(flags, state); + Future<Registry> registry = registrar.recover(master); + AWAIT_READY(registry); + + // Check that the recovered weights matches the weights we updated + // previously. + ASSERT_EQ(2, registry.get().weights_size()); + EXPECT_EQ(ROLE1, registry.get().weights(0).info().role()); + ASSERT_EQ(UPDATED_WEIGHT1, registry.get().weights(0).info().weight()); + EXPECT_EQ(ROLE2, registry.get().weights(1).info().role()); + ASSERT_EQ(WEIGHT2, registry.get().weights(1).info().weight()); + } +} + + TEST_P(RegistrarTest, Bootstrap) { // Run 1 readmits a slave that is not present.