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 2015/02/28 03:07:12 UTC
[5/5] mesos git commit: Added tests for rate limiting slave removals
during master failover.
Added tests for rate limiting slave removals during master failover.
Review: https://reviews.apache.org/r/31516
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/d55a7239
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/d55a7239
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/d55a7239
Branch: refs/heads/master
Commit: d55a7239cf0707ec291d73e30b69a07f7ee845d3
Parents: 26546a4
Author: Benjamin Mahler <be...@gmail.com>
Authored: Wed Feb 25 17:29:14 2015 -0800
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Fri Feb 27 17:52:40 2015 -0800
----------------------------------------------------------------------
src/tests/master_tests.cpp | 173 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 173 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/d55a7239/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index 5692f07..3af20e9 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -37,6 +37,7 @@
#include <process/metrics/metrics.hpp>
#include <stout/json.hpp>
+#include <stout/memory.hpp>
#include <stout/net.hpp>
#include <stout/option.hpp>
#include <stout/os.hpp>
@@ -56,9 +57,12 @@
#include "slave/containerizer/mesos/containerizer.hpp"
#include "tests/containerizer.hpp"
+#include "tests/limiter.hpp"
#include "tests/mesos.hpp"
#include "tests/utils.hpp"
+using memory::shared_ptr;
+
using mesos::internal::master::Master;
using mesos::internal::master::allocator::MesosAllocatorProcess;
@@ -72,6 +76,7 @@ using process::Clock;
using process::Future;
using process::Owned;
using process::PID;
+using process::Promise;
using process::UPID;
using std::string;
@@ -1843,6 +1848,174 @@ TEST_F(MasterTest, NonStrictRegistryWriteOnly)
}
+// This test ensures that slave removals during master recovery
+// are rate limited.
+TEST_F(MasterTest, RateLimitRecoveredSlaveRemoval)
+{
+ // Start a master.
+ master::Flags masterFlags = CreateMasterFlags();
+ Try<PID<Master> > master = StartMaster(masterFlags);
+ ASSERT_SOME(master);
+
+ Future<SlaveRegisteredMessage> slaveRegisteredMessage =
+ FUTURE_PROTOBUF(SlaveRegisteredMessage(), master.get(), _);
+
+ // Start a slave.
+ Try<PID<Slave> > slave = StartSlave();
+ ASSERT_SOME(slave);
+
+ AWAIT_READY(slaveRegisteredMessage);
+
+ // Stop the slave while the master is down.
+ this->Stop(master.get());
+ this->Stop(slave.get());
+
+ shared_ptr<MockRateLimiter> slaveRemovalLimiter(new MockRateLimiter());
+
+ // Return a pending future from the rate limiter.
+ Future<Nothing> acquire;
+ Promise<Nothing> promise;
+ EXPECT_CALL(*slaveRemovalLimiter, acquire())
+ .WillOnce(DoAll(FutureSatisfy(&acquire),
+ Return(promise.future())));
+
+ // Restart the master.
+ master = StartMaster(slaveRemovalLimiter, masterFlags);
+ ASSERT_SOME(master);
+
+ // Start a scheduler to ensure the master would notify
+ // a framework about slave removal.
+ MockScheduler sched;
+ MesosSchedulerDriver driver(
+ &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
+
+ Future<Nothing> registered;
+ EXPECT_CALL(sched, registered(&driver, _, _))
+ .WillOnce(FutureSatisfy(®istered));
+
+ Future<Nothing> slaveLost;
+ EXPECT_CALL(sched, slaveLost(&driver, _))
+ .WillRepeatedly(FutureSatisfy(&slaveLost));
+
+ driver.start();
+
+ AWAIT_READY(registered);
+
+ // Trigger the slave re-registration timeout.
+ Clock::pause();
+ Clock::advance(masterFlags.slave_reregister_timeout);
+
+ // The master should attempt to acquire a permit.
+ AWAIT_READY(acquire);
+
+ // The removal should not occur before the permit is satisfied.
+ Clock::settle();
+ ASSERT_TRUE(slaveLost.isPending());
+
+ // Once the permit is satisfied, the slave should be removed.
+ promise.set(Nothing());
+ AWAIT_READY(slaveLost);
+
+ driver.stop();
+ driver.join();
+
+ Shutdown();
+}
+
+
+// This test ensures that slave removals that get scheduled during
+// master recovery can be canceled if the slave re-registers.
+TEST_F(MasterTest, CancelRecoveredSlaveRemoval)
+{
+ // Start a master.
+ master::Flags masterFlags = CreateMasterFlags();
+ Try<PID<Master> > master = StartMaster(masterFlags);
+ ASSERT_SOME(master);
+
+ Future<SlaveRegisteredMessage> slaveRegisteredMessage =
+ FUTURE_PROTOBUF(SlaveRegisteredMessage(), master.get(), _);
+
+ // Start a slave with checkpointing.
+ slave::Flags slaveFlags = CreateSlaveFlags();
+ slaveFlags.checkpoint = true;
+ slaveFlags.recover = "reconnect";
+ slaveFlags.strict = true;
+ Try<PID<Slave> > slave = StartSlave(slaveFlags);
+ ASSERT_SOME(slave);
+
+ AWAIT_READY(slaveRegisteredMessage);
+
+ // Stop the slave while the master is down.
+ this->Stop(master.get());
+ this->Stop(slave.get());
+
+ shared_ptr<MockRateLimiter> slaveRemovalLimiter(new MockRateLimiter());
+
+ // Return a pending future from the rate limiter.
+ Future<Nothing> acquire;
+ Promise<Nothing> promise;
+ EXPECT_CALL(*slaveRemovalLimiter, acquire())
+ .WillOnce(DoAll(FutureSatisfy(&acquire),
+ Return(promise.future())));
+
+ // Restart the master.
+ master = StartMaster(slaveRemovalLimiter, masterFlags);
+ ASSERT_SOME(master);
+
+ // Start a scheduler to ensure the master would notify
+ // a framework about slave removal.
+ MockScheduler sched;
+ MesosSchedulerDriver driver(
+ &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);
+
+ Future<Nothing> registered;
+ EXPECT_CALL(sched, registered(&driver, _, _))
+ .WillOnce(FutureSatisfy(®istered));
+
+ Future<Nothing> slaveLost;
+ EXPECT_CALL(sched, slaveLost(&driver, _))
+ .WillRepeatedly(FutureSatisfy(&slaveLost));
+
+ driver.start();
+
+ AWAIT_READY(registered);
+
+ // Trigger the slave re-registration timeout.
+ Clock::pause();
+ Clock::advance(masterFlags.slave_reregister_timeout);
+
+ // The master should attempt to acquire a permit.
+ AWAIT_READY(acquire);
+
+ // The removal should not occur before the permit is satisfied.
+ Clock::settle();
+ ASSERT_TRUE(slaveLost.isPending());
+
+ // Ignore resource offers from the re-registered slave.
+ EXPECT_CALL(sched, resourceOffers(&driver, _))
+ .WillRepeatedly(Return());
+
+ Future<SlaveReregisteredMessage> slaveReregisteredMessage =
+ FUTURE_PROTOBUF(SlaveReregisteredMessage(), master.get(), _);
+
+ // Restart the slave.
+ slave = StartSlave(slaveFlags);
+ ASSERT_SOME(slave);
+
+ AWAIT_READY(slaveReregisteredMessage);
+
+ // Satisfy the rate limit permit. Ensure a removal does not occur!
+ promise.set(Nothing());
+ Clock::settle();
+ ASSERT_TRUE(slaveLost.isPending());
+
+ driver.stop();
+ driver.join();
+
+ Shutdown();
+}
+
+
// This test ensures that when a slave is recovered from the registry
// and re-registers with the master, it is *not* removed after the
// re-registration timeout elapses.