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


The following commit(s) were added to refs/heads/master by this push:
     new a4ce050f3 [agent] Add test for framework_id and executor_id support in 
/containers.
a4ce050f3 is described below

commit a4ce050f3bc791844db48f8282f88992bc4744f1
Author: None <None>
AuthorDate: Thu May 23 19:11:08 2024 -0400

    [agent] Add test for framework_id and executor_id support in /containers.
    
    Review: https://reviews.apache.org/r/75010/
---
 src/tests/slave_tests.cpp | 172 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 170 insertions(+), 2 deletions(-)

diff --git a/src/tests/slave_tests.cpp b/src/tests/slave_tests.cpp
index a5e01ef42..89afbb8dc 100644
--- a/src/tests/slave_tests.cpp
+++ b/src/tests/slave_tests.cpp
@@ -134,6 +134,7 @@ using process::UPID;
 
 using process::filter;
 
+using process::http::BadRequest;
 using process::http::InternalServerError;
 using process::http::OK;
 using process::http::Response;
@@ -2512,7 +2513,8 @@ TEST_F(SlaveTest, ContainersEndpointNoExecutor)
 // This is an end-to-end test that verifies that the slave returns the
 // correct container status and resource statistics based on the currently
 // running executors, and ensures that '/containers' endpoint returns the
-// correct container when it is provided a container ID query parameter.
+// correct container when it is provided a container ID, framework ID, or
+// executor ID query parameters.
 TEST_F(SlaveTest, ContainersEndpoint)
 {
   Try<Owned<cluster::Master>> master = StartMaster();
@@ -2540,7 +2542,9 @@ TEST_F(SlaveTest, ContainersEndpoint)
   MesosSchedulerDriver driver(
       &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL);
 
-  EXPECT_CALL(sched, registered(&driver, _, _));
+  Future<FrameworkID> frameworkId;
+  EXPECT_CALL(sched, registered(&driver, _, _))
+    .WillOnce(FutureArg<1>(&frameworkId));
 
   Future<vector<Offer>> offers;
   EXPECT_CALL(sched, resourceOffers(&driver, _))
@@ -2549,6 +2553,7 @@ TEST_F(SlaveTest, ContainersEndpoint)
 
   driver.start();
 
+  AWAIT_READY(frameworkId);
   AWAIT_READY(offers);
   ASSERT_FALSE(offers->empty());
 
@@ -2786,6 +2791,169 @@ TEST_F(SlaveTest, ContainersEndpoint)
     EXPECT_TRUE(value->contains(expected.get()));
   }
 
+  // Will be called once during the third request.
+  EXPECT_CALL(containerizer, usage(_))
+    .WillOnce(Return(statistics2));
+
+  // Will be called once during the third request and might be called if
+  // the `TASK_FAILED` update reaches the agent before the test finishes.
+  EXPECT_CALL(containerizer, status(_))
+    .WillOnce(Return(containerStatus2))
+    .WillRepeatedly(Return(containerStatus2));
+
+  {
+    Future<Response> response = process::http::get(
+      slave.get()->pid,
+      "containers?executor_id=" + executor2.executor_id().value() +
+        "&framework_id=" + frameworkId->value(),
+      None(),
+      createBasicAuthHeaders(DEFAULT_CREDENTIAL));
+
+    Try<JSON::Value> value = JSON::parse<JSON::Value>(response->body);
+    ASSERT_SOME(value);
+
+    JSON::Array array = value->as<JSON::Array>();
+    EXPECT_TRUE(array.values.size() == 1);
+
+    Try<JSON::Value> expected = JSON::parse(
+        "[{"
+            "\"executor_id\":\"" + executor2.executor_id().value() + "\","
+            "\"framework_id\":\"" + frameworkId->value() + "\","
+            "\"statistics\":{"
+            "},"
+            "\"status\":{"
+                "\"container_id\":{"
+                  "\"parent\":{\"value\":\"parent\"},"
+                  "\"value\":\"child2\""
+                "},"
+                "\"cgroup_info\":{\"net_cls\":{\"classid\":42}},"
+                "\"network_infos\":[{"
+                    "\"ip_addresses\":[{\"ip_address\":\"192.168.1.21\"}]"
+                "}]"
+            "}"
+        "}]");
+
+    ASSERT_SOME(expected);
+
+    EXPECT_TRUE(value->contains(expected.get()));
+  }
+
+  EXPECT_CALL(containerizer, usage(_))
+    .WillOnce(DoAll(FutureArg<0>(&containerId1), Return(statistics1)))
+    .WillOnce(DoAll(FutureArg<0>(&containerId2), Return(statistics2)));
+
+  EXPECT_CALL(containerizer, status(_))
+    .WillOnce(Return(containerStatus1))
+    .WillOnce(Return(containerStatus2));
+
+  {
+    Future<Response> response = process::http::get(
+      slave.get()->pid,
+      "containers?framework_id=" + frameworkId->value(),
+      None(),
+      createBasicAuthHeaders(DEFAULT_CREDENTIAL));
+
+    Try<JSON::Value> value = JSON::parse<JSON::Value>(response->body);
+    ASSERT_SOME(value);
+
+    JSON::Array array = value->as<JSON::Array>();
+
+    EXPECT_TRUE(array.values.size() == 2);
+
+    Try<JSON::Value> containerJson1 = JSON::parse(
+        "{"
+            "\"framework_id\":\"" + frameworkId->value() + "\","
+            "\"executor_name\":\"\","
+            "\"source\":\"\","
+            "\"statistics\":{"
+                "\"mem_limit_bytes\":2048"
+            "},"
+            "\"status\":{"
+                "\"container_id\":{"
+                  "\"parent\":{\"value\":\"parent\"},"
+                  "\"value\":\"child1\""
+                "},"
+                "\"cgroup_info\":{\"net_cls\":{\"classid\":42}},"
+                "\"network_infos\":[{"
+                    "\"ip_addresses\":[{\"ip_address\":\"192.168.1.20\"}]"
+                "}]"
+            "}"
+          "}");
+
+    Try<JSON::Value> containerJson2 = JSON::parse(
+        "{"
+            "\"framework_id\":\"" + frameworkId->value() + "\","
+            "\"executor_name\":\"\","
+            "\"source\":\"\","
+            "\"statistics\":{"
+                "\"mem_limit_bytes\":2048"
+            "},"
+            "\"status\":{"
+                "\"container_id\":{"
+                  "\"parent\":{\"value\":\"parent\"},"
+                  "\"value\":\"child2\""
+                "},"
+                "\"cgroup_info\":{\"net_cls\":{\"classid\":42}},"
+                "\"network_infos\":[{"
+                    "\"ip_addresses\":[{\"ip_address\":\"192.168.1.21\"}]"
+                "}]"
+            "}"
+          "}");
+
+    // Since containers are stored in a hashmap, there is no strict guarantee 
of
+    // their ordering when listed. For this reason, we test both possibilities.
+    if (array.values[0].contains(containerJson1.get())) {
+      ASSERT_TRUE(array.values[1].contains(containerJson2.get()));
+    } else {
+      ASSERT_TRUE(array.values[0].contains(containerJson2.get()));
+      ASSERT_TRUE(array.values[1].contains(containerJson1.get()));
+    }
+  }
+
+  {
+    Future<Response> response = process::http::get(
+      slave.get()->pid,
+      "containers?executor_id=" + executor2.executor_id().value() +
+        "&container_id=" + containerId1->value(),
+      None(),
+      createBasicAuthHeaders(DEFAULT_CREDENTIAL));
+
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response);
+  }
+
+  {
+    Future<Response> response = process::http::get(
+      slave.get()->pid,
+      "containers?framework_id=" + frameworkId->value() +
+        "&container_id=" + containerId1->value(),
+      None(),
+      createBasicAuthHeaders(DEFAULT_CREDENTIAL));
+
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response);
+  }
+
+  {
+    Future<Response> response = process::http::get(
+      slave.get()->pid,
+      "containers?executor_id=" + executor2.executor_id().value(),
+      None(),
+      createBasicAuthHeaders(DEFAULT_CREDENTIAL));
+
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response);
+  }
+
+  {
+    Future<Response> response = process::http::get(
+      slave.get()->pid,
+      "containers?executor_id=" + executor2.executor_id().value() +
+        "&container_id=" + containerId1->value() +
+        "&framework_id=" + frameworkId->value(),
+      None(),
+      createBasicAuthHeaders(DEFAULT_CREDENTIAL));
+
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response);
+  }
+
   EXPECT_CALL(exec1, shutdown(_))
     .Times(AtMost(1));
   EXPECT_CALL(exec2, shutdown(_))

Reply via email to