[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mesos-commits
Subject:    [mesos] 04/04: Added a test to ensure agents cannot be reactivated while DRAINING.
From:       bmahler () apache ! org
Date:       2020-02-26 17:22:16
Message-ID: 20200226172213.49EFC8DACA () gitbox ! apache ! org
[Download RAW message or body]

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 b3e96e108c7972a3a93b3b3878cc9817026109cb
Author: Benjamin Mahler <bmahler@apache.org>
AuthorDate: Wed Feb 12 22:11:53 2020 -0500

    Added a test to ensure agents cannot be reactivated while DRAINING.
    
    Review: https://reviews.apache.org/r/72126
---
 src/tests/master_draining_tests.cpp | 135 +++++++++++++++++++++++++++++++++++-
 1 file changed, 134 insertions(+), 1 deletion(-)

diff --git a/src/tests/master_draining_tests.cpp b/src/tests/master_draining_tests.cpp
index f1a00df..a91201e 100644
--- a/src/tests/master_draining_tests.cpp
+++ b/src/tests/master_draining_tests.cpp
@@ -47,6 +47,7 @@
 #include "messages/messages.hpp"
 
 #include "tests/cluster.hpp"
+#include "tests/containerizer.hpp"
 #include "tests/mesos.hpp"
 #include "tests/resources_utils.hpp"
 
@@ -55,10 +56,15 @@ namespace http = process::http;
 
 using mesos::master::detector::MasterDetector;
 
+using mesos::slave::ContainerTermination;
+
 using process::Clock;
 using process::Failure;
 using process::Future;
 using process::Owned;
+using process::Promise;
+
+using std::vector;
 
 using testing::_;
 using testing::AllOf;
@@ -126,7 +132,7 @@ public:
 
   // Helper function to post a request to "/api/v1" master endpoint and return
   // the response.
-  Future<http::Response> post(
+  static Future<http::Response> post(
       const process::PID<master::Master>& pid,
       const v1::master::Call& call,
       const ContentType& contentType,
@@ -1013,6 +1019,133 @@ TEST_P(MasterDrainingTest, DrainAgentUnreachable)
   EXPECT_EQ(agentId, offers->offers(0).agent_id());
 }
 
+
+class MasterDrainingTest2
+  : public MesosTest,
+    public WithParamInterface<ContentType> {};
+
+// These tests are parameterized by the content type of the HTTP request.
+INSTANTIATE_TEST_CASE_P(
+    ContentType,
+    MasterDrainingTest2,
+    ::testing::Values(ContentType::PROTOBUF, ContentType::JSON));
+
+
+// This test ensures that the user cannot reactivate an agent
+// that is still in the DRAINING state (which was previously
+// possible and problematic, see MESOS-10096).
+//
+// We use a mock executor that ignores the kill task request
+// to ensure the agent doesn't transition out of draining.
+TEST_P(MasterDrainingTest2, DisallowReactivationWhileDraining)
+{
+  Try<Owned<cluster::Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  MockExecutor exec(DEFAULT_EXECUTOR_ID);
+
+  TestContainerizer containerizer(&exec);
+
+  Owned<MasterDetector> detector = master.get()->createDetector();
+  auto slaveOptions = SlaveOptions(detector.get())
+                        .withFlags(CreateSlaveFlags())
+                        .withId(process::ID::generate())
+                        .withContainerizer(&containerizer);
+  Try<Owned<cluster::Slave>> slave = StartSlave(slaveOptions);
+  ASSERT_SOME(slave);
+
+  FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
+  frameworkInfo.set_checkpoint(true);
+
+  MockScheduler sched;
+  MesosSchedulerDriver driver(
+      &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);
+
+  // Start the scheduler and launch a task.
+  EXPECT_CALL(sched, registered(&driver, _, _));
+
+  Future<vector<Offer>> offers;
+  EXPECT_CALL(sched, resourceOffers(&driver, _))
+    .WillOnce(FutureArg<1>(&offers))
+    .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+  driver.start();
+
+  AWAIT_READY(offers);
+  ASSERT_FALSE(offers->empty());
+  Offer offer = offers.get()[0];
+
+  TaskInfo task;
+  task.set_name("");
+  task.mutable_task_id()->set_value("1");
+  *task.mutable_slave_id() = offer.slave_id();
+  *task.mutable_resources() = offer.resources();
+  *task.mutable_executor() = DEFAULT_EXECUTOR_INFO;
+
+  EXPECT_CALL(exec, registered(_, _, _, _));
+
+  EXPECT_CALL(exec, launchTask(_, _))
+    .WillRepeatedly(SendStatusUpdateFromTask(TASK_RUNNING));
+
+  EXPECT_CALL(containerizer, update(_, _))
+    .WillRepeatedly(Return(Nothing()));
+
+  Promise<Option<ContainerTermination>> hang;
+
+  EXPECT_CALL(containerizer, wait(_))
+    .WillRepeatedly(Return(hang.future()));
+
+  Future<TaskStatus> statusRunning1;
+  EXPECT_CALL(sched, statusUpdate(&driver, _))
+    .WillOnce(FutureArg<1>(&statusRunning1));
+
+  driver.launchTasks(offer.id(), {task});
+
+  AWAIT_READY(statusRunning1);
+  ASSERT_EQ(TASK_RUNNING, statusRunning1->state());
+
+  ContentType contentType = GetParam();
+
+  // Start draining the agent.
+  // Don't do anything upon the kill task request.
+  EXPECT_CALL(exec, killTask(_, _));
+
+  {
+    v1::master::Call::DrainAgent drainAgent;
+    *drainAgent.mutable_agent_id() = evolve(offer.slave_id());
+
+    v1::master::Call call;
+    call.set_type(v1::master::Call::DRAIN_AGENT);
+    *call.mutable_drain_agent() = drainAgent;
+
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(
+        http::OK().status,
+        MasterAlreadyDrainedTest::post(
+            (*master)->pid, call, contentType));
+  }
+
+  // The agent should now be in the draining state.
+
+  // Attempt to reactivate the agent while it is in
+  // draining, this should be rejected.
+  {
+    v1::master::Call::ReactivateAgent reactivateAgent;
+    *reactivateAgent.mutable_agent_id() = evolve(offer.slave_id());
+
+    v1::master::Call call;
+    call.set_type(v1::master::Call::REACTIVATE_AGENT);
+    call.mutable_reactivate_agent()->CopyFrom(reactivateAgent);
+
+    Future<http::Response> response =
+      MasterAlreadyDrainedTest::post((*master)->pid, call, contentType);
+
+    AWAIT_READY(response);
+    EXPECT_EQ(http::BadRequest().status, response->status);
+    EXPECT_EQ("Agent is still in the DRAINING state",
+              response->body);
+  }
+}
+
 } // namespace tests {
 } // namespace internal {
 } // namespace mesos {

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic