This is an automated email from the ASF dual-hosted git repository. bmahler pushed a commit to branch 1.9.x in repository https://gitbox.apache.org/repos/asf/mesos.git
commit 9a2a645e313467d048ee26c6f16a73c4220a4f9b Author: Benjamin Mahler <[email protected]> AuthorDate: Tue Oct 8 23:54:05 2019 -0400 Added tests for validation of large quota scalars. Review: https://reviews.apache.org/r/71596 --- src/tests/master_quota_tests.cpp | 61 ++++++++++++++++++++++++++ src/tests/master_validation_tests.cpp | 81 ++++++++++++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 2 deletions(-) diff --git a/src/tests/master_quota_tests.cpp b/src/tests/master_quota_tests.cpp index 5832869..d6c4d11 100644 --- a/src/tests/master_quota_tests.cpp +++ b/src/tests/master_quota_tests.cpp @@ -536,6 +536,67 @@ TEST_F(MasterQuotaTest, UpdateQuotaMultipleRoles) } +TEST_F(MasterQuotaTest, UpdateQuotaTooLarge) +{ + TestAllocator<> allocator; + EXPECT_CALL(allocator, initialize(_, _, _)); + + Try<Owned<cluster::Master>> master = StartMaster(&allocator); + ASSERT_SOME(master); + + process::http::Headers headers = createBasicAuthHeaders(DEFAULT_CREDENTIAL); + headers["Content-Type"] = "application/json"; + + // The quota endpoint only allows memory / disk up to + // 1 exabyte (in megabytes) or 1 trillion cores/ports/other. + + Future<Response> response = process::http::post( + master.get()->pid, + "/api/v1", + headers, + createUpdateQuotaRequestBody( + createQuotaConfig(ROLE1, "cpus:1000000000000", "cpus:1000000000001"), + true)); + + AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response); + EXPECT_TRUE(strings::contains( + response->body, + "Invalid 'QuotaConfig.limits': {'cpus': 1000000000001} is invalid:" + " values greater than 1 trillion (1000000000000) are not supported")) + << response->body; + + response = process::http::post( + master.get()->pid, + "/api/v1", + headers, + createUpdateQuotaRequestBody( + createQuotaConfig(ROLE1, "mem:1099511627776", "mem:1099511627777"), + true)); + + AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response); + EXPECT_TRUE(strings::contains( + response->body, + "Invalid 'QuotaConfig.limits': {'mem': 1099511627777} is invalid:" + " values greater than 1 exabyte (1099511627776) are not supported")) + << response->body; + + response = process::http::post( + master.get()->pid, + "/api/v1", + headers, + createUpdateQuotaRequestBody( + createQuotaConfig(ROLE1, "disk:1099511627777", ""), + true)); + + AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response); + EXPECT_TRUE(strings::contains( + response->body, + "Invalid 'QuotaConfig.guarantees': {'disk': 1099511627777} is invalid:" + " values greater than 1 exabyte (1099511627776) are not supported")) + << response->body; +} + + // These are request validation tests. They verify JSON is well-formed, // convertible to corresponding protobufs, all necessary fields are present, // while irrelevant fields are not present. diff --git a/src/tests/master_validation_tests.cpp b/src/tests/master_validation_tests.cpp index 90b8447..e9ea213 100644 --- a/src/tests/master_validation_tests.cpp +++ b/src/tests/master_validation_tests.cpp @@ -134,8 +134,6 @@ TEST(MasterCallValidationTest, UpdateQuota) error = mesos::internal::master::quota::validate(config); ASSERT_NONE(error); - // Now test the guarantees <= limits validation. - auto resourceMap = [](const vector<pair<string, double>>& vector) -> Map<string, Value::Scalar> { Map<string, Value::Scalar> result; @@ -149,6 +147,85 @@ TEST(MasterCallValidationTest, UpdateQuota) return result; }; + // The quota endpoint only allows memory / disk up to + // 1 exabyte (in megabytes) or 1 trillion cores/ports/other. + double largestMegabytes = 1024.0 * 1024.0 * 1024.0 * 1024.0; + double largestCpuPortsOrOther = 1000.0 * 1000.0 * 1000.0 * 1000.0; + + *config.mutable_guarantees() = resourceMap({ + {"disk", largestMegabytes}, + {"mem", largestMegabytes}, + {"cpus", largestCpuPortsOrOther}, + {"ports", largestCpuPortsOrOther}, + {"foobars", largestCpuPortsOrOther} + }); + *config.mutable_limits() = resourceMap({ + {"disk", largestMegabytes}, + {"mem", largestMegabytes}, + {"cpus", largestCpuPortsOrOther}, + {"ports", largestCpuPortsOrOther}, + {"foobars", largestCpuPortsOrOther}, + }); + + error = mesos::internal::master::quota::validate(config); + EXPECT_NONE(error) + << error->message; + + config.clear_guarantees(); + *config.mutable_limits() = resourceMap({{"disk", largestMegabytes + 1.0}}); + + error = mesos::internal::master::quota::validate(config); + ASSERT_SOME(error); + EXPECT_TRUE(strings::contains( + error->message, + "values greater than 1 exabyte (1099511627776) are not supported")) + << error->message; + + config.clear_guarantees(); + *config.mutable_limits() = resourceMap({{"mem", largestMegabytes + 1.0}}); + + error = mesos::internal::master::quota::validate(config); + ASSERT_SOME(error); + EXPECT_TRUE(strings::contains( + error->message, + "values greater than 1 exabyte (1099511627776) are not supported")) + << error->message; + + config.clear_limits(); + *config.mutable_guarantees() = resourceMap({ + {"cpus", largestCpuPortsOrOther + 1.0}}); + + error = mesos::internal::master::quota::validate(config); + ASSERT_SOME(error); + EXPECT_TRUE(strings::contains( + error->message, + "values greater than 1 trillion (1000000000000) are not supported")) + << error->message; + + config.clear_limits(); + *config.mutable_guarantees() = resourceMap({ + {"ports", largestCpuPortsOrOther + 1.0}}); + + error = mesos::internal::master::quota::validate(config); + ASSERT_SOME(error); + EXPECT_TRUE(strings::contains( + error->message, + "values greater than 1 trillion (1000000000000) are not supported")) + << error->message; + + config.clear_limits(); + *config.mutable_guarantees() = resourceMap({ + {"foobars", largestCpuPortsOrOther + 1.0}}); + + error = mesos::internal::master::quota::validate(config); + ASSERT_SOME(error); + EXPECT_TRUE(strings::contains( + error->message, + "values greater than 1 trillion (1000000000000) are not supported")) + << error->message; + + // Now test the guarantees <= limits validation. + // Guarantees > limits. Map<string, Value::Scalar> superset = resourceMap({{"cpus", 20}, {"mem", 40}});
