You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by jo...@apache.org on 2015/09/14 19:58:58 UTC
[14/16] mesos git commit: Maintenance Primitives: Used V1 API for
Master maintenance test.
Maintenance Primitives: Used V1 API for Master maintenance test.
Review: https://reviews.apache.org/r/37283
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/bf82689f
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/bf82689f
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/bf82689f
Branch: refs/heads/master
Commit: bf82689f69a21286177d52d7d7e5d2f713c1e5b1
Parents: 388eaa5
Author: Joris Van Remoortere <jo...@gmail.com>
Authored: Tue Aug 25 18:50:21 2015 -0400
Committer: Joris Van Remoortere <jo...@gmail.com>
Committed: Mon Sep 14 13:58:37 2015 -0400
----------------------------------------------------------------------
src/tests/master_maintenance_tests.cpp | 152 +++++++++++++++++++++-------
1 file changed, 118 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/bf82689f/src/tests/master_maintenance_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_maintenance_tests.cpp b/src/tests/master_maintenance_tests.cpp
index a857ab9..8f39ac3 100644
--- a/src/tests/master_maintenance_tests.cpp
+++ b/src/tests/master_maintenance_tests.cpp
@@ -20,6 +20,12 @@
#include <mesos/maintenance/maintenance.hpp>
+#include <mesos/v1/mesos.hpp>
+#include <mesos/v1/resources.hpp>
+#include <mesos/v1/scheduler.hpp>
+
+#include <mesos/v1/scheduler/scheduler.hpp>
+
#include <process/clock.hpp>
#include <process/future.hpp>
#include <process/http.hpp>
@@ -37,6 +43,9 @@
#include "common/protobuf_utils.hpp"
+#include "internal/devolve.hpp"
+#include "internal/evolve.hpp"
+
#include "master/master.hpp"
#include "slave/flags.hpp"
@@ -48,9 +57,14 @@ using mesos::internal::master::Master;
using mesos::internal::slave::Slave;
+using mesos::v1::scheduler::Call;
+using mesos::v1::scheduler::Event;
+using mesos::v1::scheduler::Mesos;
+
using process::Clock;
using process::Future;
using process::PID;
+using process::Queue;
using process::Time;
using process::http::BadRequest;
@@ -65,6 +79,7 @@ using mesos::internal::protobuf::maintenance::createWindow;
using std::string;
using std::vector;
+using testing::AtMost;
using testing::DoAll;
namespace mesos {
@@ -111,9 +126,40 @@ public:
// Default unavailability. Used when the test does not care
// about the value of the unavailability.
Unavailability unavailability;
+
+protected:
+ // Helper class for using EXPECT_CALL since the Mesos scheduler API
+ // is callback based.
+ class Callbacks
+ {
+ public:
+ MOCK_METHOD0(connected, void(void));
+ MOCK_METHOD0(disconnected, void(void));
+ MOCK_METHOD1(received, void(const std::queue<Event>&));
+ };
};
+// Enqueues all received events into a libprocess queue.
+// TODO(jmlvanre): Factor this common code out of tests into V1
+// helper.
+ACTION_P(Enqueue, queue)
+{
+ std::queue<Event> events = arg0;
+ while (!events.empty()) {
+ // Note that we currently drop HEARTBEATs because most of these tests
+ // are not designed to deal with heartbeats.
+ // TODO(vinod): Implement DROP_HTTP_CALLS that can filter heartbeats.
+ if (events.front().type() == Event::HEARTBEAT) {
+ VLOG(1) << "Ignoring HEARTBEAT event";
+ } else {
+ queue->put(events.front());
+ }
+ events.pop();
+ }
+}
+
+
// Posts valid and invalid schedules to the maintenance schedule endpoint.
TEST_F(MasterMaintenanceTest, UpdateSchedule)
{
@@ -304,7 +350,10 @@ TEST_F(MasterMaintenanceTest, FailToUnscheduleDeactivatedMachines)
// slave is scheduled to go down for maintenance.
TEST_F(MasterMaintenanceTest, PendingUnavailabilityTest)
{
- Try<PID<Master>> master = StartMaster();
+ master::Flags flags = CreateMasterFlags();
+ flags.authenticate_frameworks = false;
+
+ Try<PID<Master>> master = StartMaster(flags);
ASSERT_SOME(master);
MockExecutor exec(DEFAULT_EXECUTOR_ID);
@@ -312,36 +361,49 @@ TEST_F(MasterMaintenanceTest, PendingUnavailabilityTest)
Try<PID<Slave>> slave = StartSlave(&exec);
ASSERT_SOME(slave);
- MockScheduler sched;
- MesosSchedulerDriver driver(
- &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
+ Callbacks callbacks;
+
+ Future<Nothing> connected;
+ EXPECT_CALL(callbacks, connected())
+ .WillOnce(FutureSatisfy(&connected));
- EXPECT_CALL(sched, registered(&driver, _, _))
- .Times(1);
+ Mesos mesos(
+ master.get(),
+ lambda::bind(&Callbacks::connected, lambda::ref(callbacks)),
+ lambda::bind(&Callbacks::disconnected, lambda::ref(callbacks)),
+ lambda::bind(&Callbacks::received, lambda::ref(callbacks), lambda::_1));
- // Intercept offers sent to the scheduler.
- Future<vector<Offer>> normalOffers;
- Future<vector<Offer>> unavailabilityOffers;
- EXPECT_CALL(sched, resourceOffers(&driver, _))
- .WillOnce(FutureArg<1>(&normalOffers))
- .WillOnce(FutureArg<1>(&unavailabilityOffers))
- .WillRepeatedly(Return()); // Ignore subsequent offers.
+ AWAIT_READY(connected);
- // The original offers should be rescinded when the unavailability
- // is changed.
- Future<Nothing> offerRescinded;
- EXPECT_CALL(sched, offerRescinded(&driver, _))
- .WillOnce(FutureSatisfy(&offerRescinded));
+ Queue<Event> events;
+
+ EXPECT_CALL(callbacks, received(_))
+ .WillRepeatedly(Enqueue(&events));
+
+ {
+ Call call;
+ call.set_type(Call::SUBSCRIBE);
+
+ Call::Subscribe* subscribe = call.mutable_subscribe();
+ subscribe->mutable_framework_info()->CopyFrom(DEFAULT_V1_FRAMEWORK_INFO);
+
+ mesos.send(call);
+ }
+
+ Future<Event> event = events.get();
+ AWAIT_READY(event);
+ EXPECT_EQ(Event::SUBSCRIBED, event.get().type());
- // Start the test.
- driver.start();
+ v1::FrameworkID id(event.get().subscribed().framework_id());
- // Wait for some normal offers.
- AWAIT_READY(normalOffers);
- EXPECT_NE(0u, normalOffers.get().size());
+ event = events.get();
+ AWAIT_READY(event);
+ EXPECT_EQ(Event::OFFERS, event.get().type());
+ EXPECT_NE(0, event.get().offers().offers().size());
+ const size_t numberOfOffers = event.get().offers().offers().size();
- // Check that unavailability is not set.
- foreach (const Offer& offer, normalOffers.get()) {
+ // Regular offers shouldn't have unavailability.
+ foreach (const v1::Offer& offer, event.get().offers().offers()) {
EXPECT_FALSE(offer.has_unavailability());
}
@@ -372,19 +434,41 @@ TEST_F(MasterMaintenanceTest, PendingUnavailabilityTest)
AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
- // Wait for some offers.
- AWAIT_READY(unavailabilityOffers);
- EXPECT_NE(0u, unavailabilityOffers.get().size());
+ // The original offers should be rescinded when the unavailability
+ // is changed. We expect as many rescind events as we received
+ // original offers.
+ for (size_t offerNumber = 0; offerNumber < numberOfOffers; ++offerNumber) {
+ event = events.get();
+ AWAIT_READY(event);
+ EXPECT_EQ(Event::RESCIND, event.get().type());
+ }
- // Check that each offer has an unavailability.
- foreach (const Offer& offer, unavailabilityOffers.get()) {
+ event = events.get();
+ AWAIT_READY(event);
+ EXPECT_EQ(Event::OFFERS, event.get().type());
+ EXPECT_NE(0, event.get().offers().offers().size());
+
+ // Make sure the new offers have the unavailability set.
+ foreach (const v1::Offer& offer, event.get().offers().offers()) {
EXPECT_TRUE(offer.has_unavailability());
- EXPECT_EQ(unavailability.start(), offer.unavailability().start());
- EXPECT_EQ(unavailability.duration(), offer.unavailability().duration());
+ EXPECT_EQ(
+ unavailability.start().nanoseconds(),
+ offer.unavailability().start().nanoseconds());
+
+ EXPECT_EQ(
+ unavailability.duration().nanoseconds(),
+ offer.unavailability().duration().nanoseconds());
}
- driver.stop();
- driver.join();
+ // We also expect an inverse offer for the slave to go under
+ // maintenance.
+ event = events.get();
+ AWAIT_READY(event);
+ EXPECT_EQ(Event::OFFERS, event.get().type());
+ EXPECT_NE(0, event.get().offers().inverse_offers().size());
+
+ EXPECT_CALL(exec, shutdown(_))
+ .Times(AtMost(1));
Shutdown(); // Must shutdown before 'containerizer' gets deallocated.
}