src/tests/slave_tests.cpp
TEST_F(SlaveTest, RateLimitSlaveShutdown)
{
  // Start a master.
  auto slaveRemovalLimiter = std::make_shared<MockRateLimiter>();
  master::Flags masterFlags = CreateMasterFlags();

  Try<Owned<cluster::Master>> master =
    StartMaster(slaveRemovalLimiter, masterFlags);
  ASSERT_SOME(master);

  // Set these expectations up before we spawn the slave so that we
  // don't miss the first PING.
  Future<Message> ping = FUTURE_MESSAGE(
      Eq(PingSlaveMessage().GetTypeName()), _, _);

  // Drop all the PONGs to simulate health check timeout.
  DROP_PROTOBUFS(PongSlaveMessage(), _, _);

  Future<SlaveRegisteredMessage> slaveRegisteredMessage =
    FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _);

  Owned<MasterDetector> detector = master.get()->createDetector();

  // Start a slave.
  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get());
  ASSERT_SOME(slave);

  AWAIT_READY(slaveRegisteredMessage);

  // 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())));

  Future<ShutdownMessage> shutdown = FUTURE_PROTOBUF(ShutdownMessage(), _, _);

  // Induce a health check failure of the slave.
  Clock::pause();
  size_t pings = 0;
  while (true) {
    AWAIT_READY(ping);
    pings++;
    if (pings == masterFlags.max_slave_ping_timeouts) {
      Clock::advance(masterFlags.slave_ping_timeout);
      break;
    }
    ping = FUTURE_MESSAGE(Eq(PingSlaveMessage().GetTypeName()), _, _);
    Clock::advance(masterFlags.slave_ping_timeout);
  }

  // The master should attempt to acquire a permit.
  AWAIT_READY(acquire);

  // The shutdown should not occur before the permit is satisfied.
  Clock::settle();
  ASSERT_TRUE(shutdown.isPending());

  // Once the permit is satisfied, the shutdown message
  // should be sent.
  promise.set(Nothing());
  AWAIT_READY(shutdown);
}
// This test ensures that when slave removal rate limit is specified
// a slave that fails health checks is removed after a permit is
// provided by the rate limiter.
This test ensures that when slave removal rate limit is specified
a slave that fails health checks is removed after a permit is
provided by the rate limiter.
This test ensures that when slave removal rate limit is specified a slave that fails health checks is removed after a permit is provided by the rate limiter .
TEST_F(SlaveTest, RateLimitSlaveShutdown)
{
  auto slaveRemovalLimiter = std::make_shared<MockRateLimiter>();
  master::Flags masterFlags = CreateMasterFlags();
  Try<Owned<cluster::Master>> master =
    StartMaster(slaveRemovalLimiter, masterFlags);
  ASSERT_SOME(master);
  Future<Message> ping = FUTURE_MESSAGE(
      Eq(PingSlaveMessage().GetTypeName()), _, _);
  DROP_PROTOBUFS(PongSlaveMessage(), _, _);
  Future<SlaveRegisteredMessage> slaveRegisteredMessage =
    FUTURE_PROTOBUF(SlaveRegisteredMessage(), _, _);
  Owned<MasterDetector> detector = master.get()->createDetector();
  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get());
  ASSERT_SOME(slave);
  AWAIT_READY(slaveRegisteredMessage);
  Future<Nothing> acquire;
  Promise<Nothing> promise;
  EXPECT_CALL(*slaveRemovalLimiter, acquire())
    .WillOnce(DoAll(FutureSatisfy(&acquire),
                    Return(promise.future())));
  Future<ShutdownMessage> shutdown = FUTURE_PROTOBUF(ShutdownMessage(), _, _);
  Clock::pause();
  size_t pings = 0;
  while (true) {
    AWAIT_READY(ping);
    pings++;
    if (pings == masterFlags.max_slave_ping_timeouts) {
      Clock::advance(masterFlags.slave_ping_timeout);
      break;
    }
    ping = FUTURE_MESSAGE(Eq(PingSlaveMessage().GetTypeName()), _, _);
    Clock::advance(masterFlags.slave_ping_timeout);
  }
  AWAIT_READY(acquire);
  Clock::settle();
  ASSERT_TRUE(shutdown.isPending());
  promise.set(Nothing());
  AWAIT_READY(shutdown);
}
TEST_F ( SlaveTest , RateLimitSlaveShutdown ) { auto slaveRemovalLimiter = std :: make_shared < MockRateLimiter > ( ) ; master :: Flags masterFlags = CreateMasterFlags ( ) ; Try < Owned < cluster :: Master > > master = StartMaster ( slaveRemovalLimiter , masterFlags ) ; ASSERT_SOME ( master ) ; Future < Message > ping = FUTURE_MESSAGE ( Eq ( PingSlaveMessage ( ) . GetTypeName ( ) ) , _ , _ ) ; DROP_PROTOBUFS ( PongSlaveMessage ( ) , _ , _ ) ; Future < SlaveRegisteredMessage > slaveRegisteredMessage = FUTURE_PROTOBUF ( SlaveRegisteredMessage ( ) , _ , _ ) ; Owned < MasterDetector > detector = master . get ( ) -> createDetector ( ) ; Try < Owned < cluster :: Slave > > slave = StartSlave ( detector . get ( ) ) ; ASSERT_SOME ( slave ) ; AWAIT_READY ( slaveRegisteredMessage ) ; Future < Nothing > acquire ; Promise < Nothing > promise ; EXPECT_CALL ( * slaveRemovalLimiter , acquire ( ) ) . WillOnce ( DoAll ( FutureSatisfy ( & acquire ) , Return ( promise . future ( ) ) ) ) ; Future < ShutdownMessage > shutdown = FUTURE_PROTOBUF ( ShutdownMessage ( ) , _ , _ ) ; Clock :: pause ( ) ; size_t pings = 0 ; while ( true ) { AWAIT_READY ( ping ) ; pings ++ ; if ( pings == masterFlags . max_slave_ping_timeouts ) { Clock :: advance ( masterFlags . slave_ping_timeout ) ; break ; } ping = FUTURE_MESSAGE ( Eq ( PingSlaveMessage ( ) . GetTypeName ( ) ) , _ , _ ) ; Clock :: advance ( masterFlags . slave_ping_timeout ) ; } AWAIT_READY ( acquire ) ; Clock :: settle ( ) ; ASSERT_TRUE ( shutdown . isPending ( ) ) ; promise . set ( Nothing ( ) ) ; AWAIT_READY ( shutdown ) ; }
This test ensures that when slave removal rate limit is specified
a slave that fails health checks is removed after a permit is
provided by the rate limiter.
This test ensures that when slave removal rate limit is specified a slave that fails health checks is removed after a permit is provided by the rate limiter .
// Start a master. // Set these expectations up before we spawn the slave so that we // don't miss the first PING. // Drop all the PONGs to simulate health check timeout. // Start a slave. // Return a pending future from the rate limiter. // Induce a health check failure of the slave. // The master should attempt to acquire a permit. // The shutdown should not occur before the permit is satisfied. // Once the permit is satisfied, the shutdown message // should be sent.