You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2016/10/28 23:20:07 UTC
mesos git commit: Added a test for duplicate frameworks in
"unregistered_frameworks".
Repository: mesos
Updated Branches:
refs/heads/master 83db4b0b5 -> d0d496b02
Added a test for duplicate frameworks in "unregistered_frameworks".
Review: https://reviews.apache.org/r/53275
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/d0d496b0
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/d0d496b0
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/d0d496b0
Branch: refs/heads/master
Commit: d0d496b0213dcfe49a83ebc7f6681691174e8468
Parents: 83db4b0
Author: Vinod Kone <vi...@gmail.com>
Authored: Mon Oct 24 17:07:12 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Fri Oct 28 16:19:57 2016 -0700
----------------------------------------------------------------------
src/tests/master_tests.cpp | 176 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 174 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/d0d496b0/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index 968192c..e1e264e 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -2753,8 +2753,8 @@ TEST_F(MasterZooKeeperTest, MasterInfoAddress)
// This test ensures that when a master fails over, those tasks that
// belong to some currently unregistered frameworks will appear in the
-// "orphan_tasks" field in the state endpoint. And those unregistered frameworks
-// will appear in the "unregistered_frameworks" field.
+// "orphan_tasks" field in the state endpoint. And those unregistered
+// frameworks will appear in the "unregistered_frameworks" field.
TEST_F(MasterTest, OrphanTasks)
{
// Start a master.
@@ -2936,6 +2936,178 @@ TEST_F(MasterTest, OrphanTasks)
}
+// This test verifies that a framework that has not yet re-registered after
+// a master failover doesn't show up multiple times in "unregistered_frameworks"
+// when quering "/state" or "/frameworks" endpoints. This is to catch
+// any regressions for MESOS-4973 and MESOS-6461.
+TEST_F(MasterTest, OrphanTasksMultipleAgents)
+{
+ Try<Owned<cluster::Master>> master = StartMaster();
+ ASSERT_SOME(master);
+
+ StandaloneMasterDetector slavesDetector(master.get()->pid);
+
+ MockExecutor exec1(DEFAULT_EXECUTOR_ID);
+ TestContainerizer containerizer1(&exec1);
+
+ // Start the first slave and launch a task.
+
+ Try<Owned<cluster::Slave>> slave1 =
+ StartSlave(&slavesDetector, &containerizer1);
+
+ ASSERT_SOME(slave1);
+
+ StandaloneMasterDetector schedDetector(master.get()->pid);
+
+ MockScheduler sched;
+ TestingMesosSchedulerDriver driver(&sched, &schedDetector);
+
+ FrameworkID frameworkId;
+ EXPECT_CALL(sched, registered(&driver, _, _))
+ .WillOnce(SaveArg<1>(&frameworkId))
+ .WillRepeatedly(Return()); // Ignore subsequent events.
+
+ Future<vector<Offer>> offers1;
+ EXPECT_CALL(sched, resourceOffers(&driver, _))
+ .WillOnce(FutureArg<1>(&offers1));
+
+ driver.start();
+
+ AWAIT_READY(offers1);
+ EXPECT_NE(0u, offers1.get().size());
+
+ TaskInfo task1 =
+ createTask(offers1.get()[0], "sleep 100", DEFAULT_EXECUTOR_ID);
+
+ EXPECT_CALL(exec1, registered(_, _, _, _));
+
+ EXPECT_CALL(exec1, launchTask(_, _))
+ .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));
+
+ Future<TaskStatus> status1;
+ EXPECT_CALL(sched, statusUpdate(&driver, _))
+ .WillOnce(FutureArg<1>(&status1));
+
+ driver.launchTasks(offers1.get()[0].id(), {task1});
+
+ AWAIT_READY(status1);
+ EXPECT_EQ(TASK_RUNNING, status1.get().state());
+
+ // Start the second slave and launch a task.
+
+ Future<vector<Offer>> offers2;
+ EXPECT_CALL(sched, resourceOffers(&driver, _))
+ .WillOnce(FutureArg<1>(&offers2))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+ MockExecutor exec2(DEFAULT_EXECUTOR_ID);
+ TestContainerizer containerizer2(&exec2);
+
+ Try<Owned<cluster::Slave>> slave2 = StartSlave(
+ &slavesDetector, &containerizer2);
+
+ ASSERT_SOME(slave2);
+
+ AWAIT_READY(offers2);
+ EXPECT_NE(0u, offers2.get().size());
+
+ TaskInfo task2 =
+ createTask(offers2.get()[0], "sleep 100", DEFAULT_EXECUTOR_ID);
+
+ EXPECT_CALL(exec2, registered(_, _, _, _));
+
+ EXPECT_CALL(exec2, launchTask(_, _))
+ .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));
+
+ Future<TaskStatus> status2;
+ EXPECT_CALL(sched, statusUpdate(&driver, _))
+ .WillOnce(FutureArg<1>(&status2))
+ .WillRepeatedly(Return()); // Ignore subsequent updates.
+
+ driver.launchTasks(offers2.get()[0].id(), {task2});
+
+ AWAIT_READY(status2);
+ EXPECT_EQ(TASK_RUNNING, status2.get().state());
+
+ Future<SlaveReregisteredMessage> slaveReregisteredMessage1 =
+ FUTURE_PROTOBUF(SlaveReregisteredMessage(), _, _);
+
+ Future<SlaveReregisteredMessage> slaveReregisteredMessage2 =
+ FUTURE_PROTOBUF(SlaveReregisteredMessage(), _, _);
+
+ // Failover the master.
+ master->reset();
+ master = StartMaster();
+ ASSERT_SOME(master);
+
+ // Simulate a new master detected event to the slaves (but not the scheduler).
+ slavesDetector.appoint(master.get()->pid);
+
+ AWAIT_READY(slaveReregisteredMessage1);
+ AWAIT_READY(slaveReregisteredMessage2);
+
+ // Ensure that there are 2 orphan tasks and 1 unregistered framework
+ // in "/state" endpoint.
+ {
+ Future<Response> response = process::http::get(
+ master.get()->pid,
+ "state",
+ None(),
+ createBasicAuthHeaders(DEFAULT_CREDENTIAL));
+
+ AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
+ AWAIT_EXPECT_RESPONSE_HEADER_EQ(APPLICATION_JSON, "Content-Type", response);
+
+ Try<JSON::Object> parse = JSON::parse<JSON::Object>(response.get().body);
+ ASSERT_SOME(parse);
+
+ JSON::Object state = parse.get();
+
+ JSON::Array frameworks =
+ state.values["frameworks"].as<JSON::Array>();
+ JSON::Array orphanTasks =
+ state.values["orphan_tasks"].as<JSON::Array>();
+ JSON::Array unregisteredFrameworks =
+ state.values["unregistered_frameworks"].as<JSON::Array>();
+
+ EXPECT_EQ(0u, frameworks.values.size());
+ EXPECT_EQ(2u, orphanTasks.values.size());
+ EXPECT_EQ(1u, unregisteredFrameworks.values.size());
+ }
+
+ // Ensure that there is 1 unregistered framework in "/frameworks" endpoint.
+ {
+ Future<Response> response = process::http::get(
+ master.get()->pid,
+ "frameworks",
+ None(),
+ createBasicAuthHeaders(DEFAULT_CREDENTIAL));
+
+ AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
+ AWAIT_EXPECT_RESPONSE_HEADER_EQ(APPLICATION_JSON, "Content-Type", response);
+
+ Try<JSON::Object> parse = JSON::parse<JSON::Object>(response.get().body);
+ ASSERT_SOME(parse);
+
+ JSON::Object state = parse.get();
+
+ JSON::Array unregisteredFrameworks =
+ state.values["unregistered_frameworks"].as<JSON::Array>();
+
+ EXPECT_EQ(1u, unregisteredFrameworks.values.size());
+ }
+
+ EXPECT_CALL(exec1, shutdown(_))
+ .Times(AtMost(1));
+
+ EXPECT_CALL(exec2, shutdown(_))
+ .Times(AtMost(1));
+
+ driver.stop();
+ driver.join();
+}
+
+
// This tests /tasks endpoint to return correct task information.
TEST_F(MasterTest, TasksEndpoint)
{