You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2019/07/10 03:37:49 UTC

[mesos] 06/06: Added a test for /roles quota.consumed field.

This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 121dcb59d183005a1dd55f987c12617a327a7654
Author: Benjamin Mahler <bm...@apache.org>
AuthorDate: Mon Jul 8 13:36:09 2019 -0400

    Added a test for /roles quota.consumed field.
    
    This ensures that the various edge different states of resources
    are correctly handled, see test comment for more details.
    
    Review: https://reviews.apache.org/r/71032
---
 src/tests/role_tests.cpp | 148 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)

diff --git a/src/tests/role_tests.cpp b/src/tests/role_tests.cpp
index 384b1d5..f7a8234 100644
--- a/src/tests/role_tests.cpp
+++ b/src/tests/role_tests.cpp
@@ -57,6 +57,7 @@ using process::http::Response;
 using process::http::Unauthorized;
 
 using testing::AtMost;
+using testing::DoAll;
 
 namespace mesos {
 namespace internal {
@@ -471,6 +472,153 @@ TEST_F_TEMP_DISABLED_ON_WINDOWS(RoleTest, RolesEndpointContainsQuota)
 }
 
 
+// This test ensures that quota consumption is included
+// in /roles endpoint of master.
+//
+// We set up the following that should be included in
+// the quota consumption:
+//   - Allocated unreserved resources
+//   - Allocated reservation
+//   - Unallocated reservation
+//
+// And we set up the following that should not be included
+// in the quota consumption:
+//   - Outstanding offer
+//
+// TODO(bmahler): Test hierarchical accounting accuracy.
+TEST_F(RoleTest, RolesEndpointContainsConsumedQuota)
+{
+  Try<Owned<cluster::Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  // Start an agent with reserved resources and
+  // allocate them to a task.
+  slave::Flags agentFlags1 = CreateSlaveFlags();
+  agentFlags1.resources = "cpus(role):1;mem(role):10;"
+                          "disk:0;ports:[]";
+
+  Owned<MasterDetector> detector = master.get()->createDetector();
+  Try<Owned<cluster::Slave>> slave1 = StartSlave(detector.get(), agentFlags1);
+
+  FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
+  frameworkInfo.set_roles(0, "role");
+
+  MockScheduler sched;
+  MesosSchedulerDriver driver(
+      &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);
+
+  Future<FrameworkID> frameworkId;
+  EXPECT_CALL(sched, registered(&driver, _, _))
+    .WillOnce(FutureArg<1>(&frameworkId));
+
+  ExecutorInfo executorInfo = createExecutorInfo("dummy", "sleep 3600");
+
+  Future<Nothing> task1Launched;
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(DoAll(LaunchTasks(executorInfo, 1, 1, 10, "role"),
+                    FutureSatisfy(&task1Launched)));
+
+  EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillRepeatedly(Return());
+
+  driver.start();
+
+  AWAIT_READY(task1Launched);
+
+  // Now we have:
+  //  - Allocated reservation: cpus:1;mem:10
+
+  // Start an agent with unreserved resources and allocate
+  // them to a task.
+
+  Future<Nothing> task2Launched;
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(DoAll(LaunchTasks(executorInfo, 1, 10, 100, "role"),
+                    FutureSatisfy(&task2Launched)));
+
+  slave::Flags agentFlags2 = CreateSlaveFlags();
+  agentFlags2.resources = "cpus:10;mem:100;"
+                          "disk:0;ports:[]";
+
+  Try<Owned<cluster::Slave>> slave2 = StartSlave(detector.get(), agentFlags2);
+
+  AWAIT_READY(task2Launched);
+
+  // Now we have:
+  //  - Allocated reservation: cpus:1;mem:10
+  //  - Allocated unreserved resources: cpus:10;mem:100
+
+  // Start an agent with both reserved and unreserved
+  // resources, but let them remain offered.
+
+  Future<Nothing> offer;
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(FutureSatisfy(&offer));
+
+  slave::Flags agentFlags3 = CreateSlaveFlags();
+  agentFlags3.resources = "cpus(role):100;mem(role):1000;"
+                          "cpus:1000;mem:10000;"
+                          ";disk:0;ports:[]";
+
+  Try<Owned<cluster::Slave>> slave3 = StartSlave(detector.get(), agentFlags3);
+
+  AWAIT_READY(offer);
+
+  // Now we have:
+  //  - Allocated reservation: cpus:1;mem:10
+  //  - Allocated unreserved resources: cpus:10;mem:100
+  //  - Offered reservation: cpus:100;mem:1000
+  //  - Offered unreserved resources: cpus:1000;mem:10000
+
+  // Check that the /roles endopint has the correct quota
+  // consumption information.
+  {
+    Future<Response> response = process::http::get(
+        master.get()->pid,
+        "roles",
+        None(),
+        createBasicAuthHeaders(DEFAULT_CREDENTIAL));
+
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
+
+    Try<JSON::Value> parse = JSON::parse(response->body);
+    ASSERT_SOME(parse);
+
+    Try<JSON::Value> expected = JSON::parse(
+        "{"
+        "  \"roles\": ["
+        "    {"
+        "      \"frameworks\": [\"" + frameworkId->value() + "\"],"
+        "      \"name\": \"role\","
+        "      \"resources\": {"
+        "        \"cpus\": 1111.0,"
+        "        \"mem\":  11110.0,"
+        "        \"disk\": 0,"
+        "        \"gpus\": 0"
+        "      },"
+        "      \"quota\": {"
+        "        \"consumed\": {"
+        "          \"cpus\": 111.0,"
+        "          \"mem\": 1110.0"
+        "        },"
+        "        \"guarantee\": {},"
+        "        \"limit\": {},"
+        "        \"role\": \"role\""
+        "      },"
+        "      \"weight\": 1.0"
+        "    }"
+        "  ]"
+        "}");
+
+    ASSERT_SOME(expected);
+
+    EXPECT_EQ(*expected, *parse)
+      << "expected " << stringify(*expected)
+      << " vs actual " << stringify(*parse);
+  }
+}
+
+
 // This test checks that when using implicit roles, the "/roles"
 // endpoint shows roles that have a configured weight even if they
 // have no registered frameworks.