mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-01 14:35:29 +00:00
[5674] Use pausing capability of StateModel in HA library.
This commit is contained in:
@@ -35,7 +35,6 @@ libha_la_SOURCES += ha_log.cc ha_log.h
|
||||
libha_la_SOURCES += ha_server_type.h
|
||||
libha_la_SOURCES += ha_service.cc ha_service.h
|
||||
libha_la_SOURCES += ha_service_states.cc ha_service_states.h
|
||||
libha_la_SOURCES += ha_state_machine_control.cc ha_state_machine_control.h
|
||||
libha_la_SOURCES += query_filter.cc query_filter.h
|
||||
libha_la_SOURCES += version.cc
|
||||
|
||||
|
@@ -10,6 +10,8 @@
|
||||
#include <ha_service_states.h>
|
||||
#include <sstream>
|
||||
|
||||
using namespace isc::util;
|
||||
|
||||
namespace isc {
|
||||
namespace ha {
|
||||
|
||||
@@ -78,7 +80,7 @@ HAConfig::PeerConfig::roleToString(const HAConfig::PeerConfig::Role& role) {
|
||||
}
|
||||
|
||||
HAConfig::StateConfig::StateConfig(const int state)
|
||||
: state_(state), pausing_(HAConfig::StateConfig::PAUSE_NEVER) {
|
||||
: state_(state), pausing_(STATE_PAUSE_NEVER) {
|
||||
}
|
||||
|
||||
void
|
||||
@@ -86,31 +88,31 @@ HAConfig::StateConfig::setPausing(const std::string& pausing) {
|
||||
pausing_ = stringToPausing(pausing);
|
||||
}
|
||||
|
||||
HAConfig::StateConfig::Pausing
|
||||
StatePausing
|
||||
HAConfig::StateConfig::stringToPausing(const std::string& pausing) {
|
||||
if (pausing == "always") {
|
||||
return (HAConfig::StateConfig::PAUSE_ALWAYS);
|
||||
return (STATE_PAUSE_ALWAYS);
|
||||
|
||||
} else if (pausing == "never") {
|
||||
return (HAConfig::StateConfig::PAUSE_NEVER);
|
||||
return (STATE_PAUSE_NEVER);
|
||||
|
||||
} else if (pausing == "once") {
|
||||
return (HAConfig::StateConfig::PAUSE_ONCE);
|
||||
return (STATE_PAUSE_ONCE);
|
||||
}
|
||||
|
||||
isc_throw(BadValue, "unsupported value " << pausing << " of 'pause' parameter");
|
||||
}
|
||||
|
||||
std::string
|
||||
HAConfig::StateConfig::pausingToString(const HAConfig::StateConfig::Pausing& pausing) {
|
||||
HAConfig::StateConfig::pausingToString(const StatePausing& pausing) {
|
||||
switch (pausing) {
|
||||
case HAConfig::StateConfig::PAUSE_ALWAYS:
|
||||
case STATE_PAUSE_ALWAYS:
|
||||
return ("always");
|
||||
|
||||
case HAConfig::StateConfig::PAUSE_NEVER:
|
||||
case STATE_PAUSE_NEVER:
|
||||
return ("never");
|
||||
|
||||
case HAConfig::StateConfig::PAUSE_ONCE:
|
||||
case STATE_PAUSE_ONCE:
|
||||
return ("once");
|
||||
|
||||
default:
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <exceptions/exceptions.h>
|
||||
#include <http/url.h>
|
||||
#include <util/state_model.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
@@ -165,18 +166,6 @@ public:
|
||||
class StateConfig {
|
||||
public:
|
||||
|
||||
/// @brief State machine pausing modes.
|
||||
///
|
||||
/// Supported modes are:
|
||||
/// - always pause in the given state,
|
||||
/// - never pause in the given state,
|
||||
/// - pause upon first transition to the given state.
|
||||
enum Pausing {
|
||||
PAUSE_ALWAYS,
|
||||
PAUSE_NEVER,
|
||||
PAUSE_ONCE
|
||||
};
|
||||
|
||||
/// @brief Constructor.
|
||||
///
|
||||
/// @param state state identifier.
|
||||
@@ -188,7 +177,7 @@ public:
|
||||
}
|
||||
|
||||
/// @brief Returns pausing mode for the given state.
|
||||
Pausing getPausing() const {
|
||||
util::StatePausing getPausing() const {
|
||||
return (pausing_);
|
||||
}
|
||||
|
||||
@@ -202,12 +191,12 @@ public:
|
||||
///
|
||||
/// @param pausing pausing mode in the textual form. Supported
|
||||
/// values are: always, never, once.
|
||||
static Pausing stringToPausing(const std::string& pausing);
|
||||
static util::StatePausing stringToPausing(const std::string& pausing);
|
||||
|
||||
/// @brief Returns pausing mode in the textual form.
|
||||
///
|
||||
/// @param pausing pausing mode.
|
||||
static std::string pausingToString(const Pausing& pausing);
|
||||
static std::string pausingToString(const util::StatePausing& pausing);
|
||||
|
||||
private:
|
||||
|
||||
@@ -215,7 +204,7 @@ public:
|
||||
int state_;
|
||||
|
||||
/// @brief Pausing mode in the given state.
|
||||
Pausing pausing_;
|
||||
util::StatePausing pausing_;
|
||||
};
|
||||
|
||||
/// @brief Pointer to the state configuration.
|
||||
|
@@ -45,7 +45,7 @@ HAService::HAService(const IOServicePtr& io_service, const NetworkStatePtr& netw
|
||||
const HAConfigPtr& config, const HAServerType& server_type)
|
||||
: io_service_(io_service), network_state_(network_state), config_(config),
|
||||
server_type_(server_type), client_(*io_service), communication_state_(),
|
||||
query_filter_(config), state_machine_control_(config), pending_requests_() {
|
||||
query_filter_(config), pending_requests_() {
|
||||
|
||||
if (server_type == HAServerType::DHCPv4) {
|
||||
communication_state_.reset(new CommunicationState4(io_service_, config));
|
||||
@@ -55,7 +55,6 @@ HAService::HAService(const IOServicePtr& io_service, const NetworkStatePtr& netw
|
||||
}
|
||||
|
||||
startModel(HA_WAITING_ST);
|
||||
state_machine_control_.notify(HA_WAITING_ST);
|
||||
|
||||
LOG_INFO(ha_logger, HA_SERVICE_STARTED)
|
||||
.arg(HAConfig::HAModeToString(config->getHAMode()))
|
||||
@@ -87,28 +86,36 @@ HAService::defineStates() {
|
||||
StateModel::defineStates();
|
||||
|
||||
defineState(HA_BACKUP_ST, stateToString(HA_BACKUP_ST),
|
||||
boost::bind(&HAService::backupStateHandler, this));
|
||||
boost::bind(&HAService::backupStateHandler, this),
|
||||
config_->getStateMachineConfig()->getStateConfig(HA_BACKUP_ST)->getPausing());
|
||||
|
||||
defineState(HA_HOT_STANDBY_ST, stateToString(HA_HOT_STANDBY_ST),
|
||||
boost::bind(&HAService::normalStateHandler, this));
|
||||
boost::bind(&HAService::normalStateHandler, this),
|
||||
config_->getStateMachineConfig()->getStateConfig(HA_HOT_STANDBY_ST)->getPausing());
|
||||
|
||||
defineState(HA_LOAD_BALANCING_ST, stateToString(HA_LOAD_BALANCING_ST),
|
||||
boost::bind(&HAService::normalStateHandler, this));
|
||||
boost::bind(&HAService::normalStateHandler, this),
|
||||
config_->getStateMachineConfig()->getStateConfig(HA_LOAD_BALANCING_ST)->getPausing());
|
||||
|
||||
defineState(HA_PARTNER_DOWN_ST, stateToString(HA_PARTNER_DOWN_ST),
|
||||
boost::bind(&HAService::partnerDownStateHandler, this));
|
||||
boost::bind(&HAService::partnerDownStateHandler, this),
|
||||
config_->getStateMachineConfig()->getStateConfig(HA_PARTNER_DOWN_ST)->getPausing());
|
||||
|
||||
defineState(HA_READY_ST, stateToString(HA_READY_ST),
|
||||
boost::bind(&HAService::readyStateHandler, this));
|
||||
boost::bind(&HAService::readyStateHandler, this),
|
||||
config_->getStateMachineConfig()->getStateConfig(HA_READY_ST)->getPausing());
|
||||
|
||||
defineState(HA_SYNCING_ST, stateToString(HA_SYNCING_ST),
|
||||
boost::bind(&HAService::syncingStateHandler, this));
|
||||
boost::bind(&HAService::syncingStateHandler, this),
|
||||
config_->getStateMachineConfig()->getStateConfig(HA_SYNCING_ST)->getPausing());
|
||||
|
||||
defineState(HA_TERMINATED_ST, stateToString(HA_TERMINATED_ST),
|
||||
boost::bind(&HAService::terminatedStateHandler, this));
|
||||
boost::bind(&HAService::terminatedStateHandler, this),
|
||||
config_->getStateMachineConfig()->getStateConfig(HA_TERMINATED_ST)->getPausing());
|
||||
|
||||
defineState(HA_WAITING_ST, stateToString(HA_WAITING_ST),
|
||||
boost::bind(&HAService::waitingStateHandler, this));
|
||||
boost::bind(&HAService::waitingStateHandler, this),
|
||||
config_->getStateMachineConfig()->getStateConfig(HA_WAITING_ST)->getPausing());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -135,7 +142,7 @@ HAService::normalStateHandler() {
|
||||
|
||||
scheduleHeartbeat();
|
||||
|
||||
if (state_machine_control_.amPaused()) {
|
||||
if (isModelPaused()) {
|
||||
postNextEvent(NOP_EVT);
|
||||
return;
|
||||
}
|
||||
@@ -190,7 +197,7 @@ HAService::partnerDownStateHandler() {
|
||||
|
||||
scheduleHeartbeat();
|
||||
|
||||
if (state_machine_control_.amPaused()) {
|
||||
if (isModelPaused()) {
|
||||
postNextEvent(NOP_EVT);
|
||||
return;
|
||||
}
|
||||
@@ -235,7 +242,7 @@ HAService::readyStateHandler() {
|
||||
|
||||
scheduleHeartbeat();
|
||||
|
||||
if (state_machine_control_.amPaused()) {
|
||||
if (isModelPaused()) {
|
||||
postNextEvent(NOP_EVT);
|
||||
return;
|
||||
}
|
||||
@@ -295,7 +302,7 @@ HAService::syncingStateHandler() {
|
||||
adjustNetworkState();
|
||||
}
|
||||
|
||||
if (state_machine_control_.amPaused()) {
|
||||
if (isModelPaused()) {
|
||||
postNextEvent(NOP_EVT);
|
||||
return;
|
||||
}
|
||||
@@ -389,7 +396,7 @@ HAService::waitingStateHandler() {
|
||||
scheduleHeartbeat();
|
||||
}
|
||||
|
||||
if (state_machine_control_.amPaused()) {
|
||||
if (isModelPaused()) {
|
||||
postNextEvent(NOP_EVT);
|
||||
return;
|
||||
}
|
||||
@@ -482,7 +489,6 @@ HAService::verboseTransition(const unsigned state) {
|
||||
|
||||
// Do the actual transition.
|
||||
transition(state, getNextEvent());
|
||||
state_machine_control_.notify(state);
|
||||
|
||||
// Inform the administrator whether or not lease updates are generated.
|
||||
// Updates are never generated by a backup server so it doesn't make
|
||||
@@ -505,11 +511,24 @@ HAService::verboseTransition(const unsigned state) {
|
||||
.arg(new_state_name);
|
||||
}
|
||||
}
|
||||
|
||||
// Inform the administrator if the state machine is paused.
|
||||
if (isModelPaused()) {
|
||||
std::string state_name = stateToString(state);
|
||||
boost::to_upper(state_name);
|
||||
LOG_INFO(ha_logger, HA_STATE_MACHINE_PAUSED)
|
||||
.arg(state_name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
HAService::unpause() {
|
||||
state_machine_control_.unpause();
|
||||
if (isModelPaused()) {
|
||||
LOG_INFO(ha_logger, HA_STATE_MACHINE_CONTINUED);
|
||||
unpauseModel();
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -10,7 +10,6 @@
|
||||
#include <communication_state.h>
|
||||
#include <ha_config.h>
|
||||
#include <ha_server_type.h>
|
||||
#include <ha_state_machine_control.h>
|
||||
#include <query_filter.h>
|
||||
#include <asiolink/io_service.h>
|
||||
#include <cc/data.h>
|
||||
@@ -247,12 +246,14 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
/// @brief Un-pauses the state machine.
|
||||
/// @brief Unpauses the HA state machine with logging.
|
||||
///
|
||||
/// This is method is invoked when the server receives the 'ha-continue'
|
||||
/// command which instructs the server to unblock the HA state machine
|
||||
/// so as it may transition to a next state.
|
||||
void unpause();
|
||||
/// It un-pauses the state machine if it is paused and logs an informational
|
||||
/// message. It doesn't log the message if the state machine is not paused.
|
||||
///
|
||||
/// @return true if the state machine was unpaused, false if the state
|
||||
/// machine was not paused when this method was invoked.
|
||||
bool unpause();
|
||||
|
||||
/// @brief Instructs the HA service to serve default scopes.
|
||||
///
|
||||
@@ -643,9 +644,6 @@ protected:
|
||||
/// @brief Selects queries to be processed/dropped.
|
||||
QueryFilter query_filter_;
|
||||
|
||||
/// @brief Controls state machine pausing and unpausing.
|
||||
HAStateMachineControl state_machine_control_;
|
||||
|
||||
/// @brief Map holding a number of scheduled requests for a given packet.
|
||||
///
|
||||
/// A single callout may send multiple requests at the same time, e.g.
|
||||
|
@@ -1,58 +0,0 @@
|
||||
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <ha_log.h>
|
||||
#include <ha_service_states.h>
|
||||
#include <ha_state_machine_control.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
namespace isc {
|
||||
namespace ha {
|
||||
|
||||
HAStateMachineControl::HAStateMachineControl(const HAConfigPtr& config)
|
||||
: config_(config), paused_(false), visited_states_() {
|
||||
}
|
||||
|
||||
void
|
||||
HAStateMachineControl::notify(const int state) {
|
||||
// Always get the configuration to verify that the state identifier is
|
||||
// recognized.
|
||||
HAConfig::StateConfigPtr state_config = config_->getStateMachineConfig()->
|
||||
getStateConfig(state);
|
||||
|
||||
// Pause if we should always pause in this state or we should pause once
|
||||
// and this is the first time we visit this state.
|
||||
bool first_visit = (visited_states_.count(state) == 0);
|
||||
|
||||
// If this is the first time we're in this state, record it.
|
||||
if (first_visit) {
|
||||
visited_states_.insert(state);
|
||||
}
|
||||
|
||||
// Only pause the state machine if it is not paused already.
|
||||
if (!amPaused()) {
|
||||
if ((state_config->getPausing() == HAConfig::StateConfig::PAUSE_ALWAYS) ||
|
||||
((state_config->getPausing() == HAConfig::StateConfig::PAUSE_ONCE) &&
|
||||
first_visit)) {
|
||||
std::string state_name = stateToString(state);
|
||||
boost::to_upper(state_name);
|
||||
LOG_INFO(ha_logger, HA_STATE_MACHINE_PAUSED)
|
||||
.arg(state_name);
|
||||
paused_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HAStateMachineControl::unpause() {
|
||||
if (amPaused()) {
|
||||
LOG_INFO(ha_logger, HA_STATE_MACHINE_CONTINUED);
|
||||
paused_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // end of namespace isc::ha
|
||||
} // end of namespace isc
|
@@ -1,81 +0,0 @@
|
||||
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef HA_STATE_MACHINE_CONTROL_H
|
||||
#define HA_STATE_MACHINE_CONTROL_H
|
||||
|
||||
#include <ha_config.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <set>
|
||||
|
||||
namespace isc {
|
||||
namespace ha {
|
||||
|
||||
/// @brief Hold runtime information about HA state machine.
|
||||
///
|
||||
/// Currently, the only available runtime information is whether the
|
||||
/// state machine is paused and if it should paused in certain states
|
||||
/// upon next transition to these states. Note that the server may be
|
||||
/// configured to only pause the state machine upon the first transition
|
||||
/// to the certain states.
|
||||
///
|
||||
/// The @c HAService calls @c notify upon transition to the next state.
|
||||
/// This class determines whether the state machine should be paused
|
||||
/// in this state based on the provided configuration and the history
|
||||
/// of already visited states. The @c amPaused method should be later
|
||||
/// called in the state handlers to check if the state machine is
|
||||
/// paused or running. In the former case, it should not transition to
|
||||
/// any other state until the state machine is unpaused.
|
||||
class HAStateMachineControl {
|
||||
public:
|
||||
|
||||
/// @brief Constructor.
|
||||
///
|
||||
/// @param config HA hooks library configuration.
|
||||
explicit HAStateMachineControl(const HAConfigPtr& config);
|
||||
|
||||
/// @brief Receives notification from the HA state handlers about
|
||||
/// the current state.
|
||||
///
|
||||
/// This method pauses sets a flag to pause the HA state machine if
|
||||
/// it should be paused in the given state. It also records that
|
||||
/// state as "visited", so as it is possible to determine whether
|
||||
/// the state machine should be paused the next time it transitions
|
||||
/// to this state.
|
||||
///
|
||||
/// @param state current state of the state machine.
|
||||
/// @throw BadValue if the state is not recognized.
|
||||
void notify(int state);
|
||||
|
||||
/// @brief Informs whether the state machine is paused.
|
||||
///
|
||||
/// @return true if the state machine is paused, false otherwise.
|
||||
bool amPaused() const {
|
||||
return (paused_);
|
||||
}
|
||||
|
||||
/// @brief Clears flag indicating that the state machine is paused.
|
||||
void unpause();
|
||||
|
||||
private:
|
||||
|
||||
/// @brief HA configuration
|
||||
HAConfigPtr config_;
|
||||
|
||||
/// @brief Boolean flag indicating if the state machine is paused.
|
||||
bool paused_;
|
||||
|
||||
/// @brief Keeps track of visited states.
|
||||
std::set<int> visited_states_;
|
||||
};
|
||||
|
||||
/// @brief Shared pointer to the @c HAStateMachineControl.
|
||||
typedef boost::shared_ptr<HAStateMachineControl> HAStateMachineControlPtr;
|
||||
|
||||
} // end of namespace isc::ha
|
||||
} // end of namespace isc
|
||||
|
||||
#endif
|
@@ -29,7 +29,6 @@ ha_unittests_SOURCES += communication_state_unittest.cc
|
||||
ha_unittests_SOURCES += ha_config_unittest.cc
|
||||
ha_unittests_SOURCES += ha_impl_unittest.cc
|
||||
ha_unittests_SOURCES += ha_service_unittest.cc
|
||||
ha_unittests_SOURCES += ha_state_machine_control_unittest.cc
|
||||
ha_unittests_SOURCES += ha_test.cc ha_test.h
|
||||
ha_unittests_SOURCES += query_filter_unittest.cc
|
||||
ha_unittests_SOURCES += run_unittests.cc
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include <cc/data.h>
|
||||
#include <cc/dhcp_config_error.h>
|
||||
#include <config/command_mgr.h>
|
||||
#include <util/state_model.h>
|
||||
#include <string>
|
||||
|
||||
using namespace isc;
|
||||
@@ -21,6 +22,7 @@ using namespace isc::data;
|
||||
using namespace isc::ha;
|
||||
using namespace isc::hooks;
|
||||
using namespace isc::ha::test;
|
||||
using namespace isc::util;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -150,37 +152,37 @@ TEST_F(HAConfigTest, configureLoadBalancing) {
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_BACKUP_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER, state_cfg->getPausing());
|
||||
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_LOAD_BALANCING_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER, state_cfg->getPausing());
|
||||
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_PARTNER_DOWN_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER, state_cfg->getPausing());
|
||||
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_READY_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_ALWAYS, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_ALWAYS, state_cfg->getPausing());
|
||||
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_SYNCING_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER, state_cfg->getPausing());
|
||||
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_TERMINATED_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER, state_cfg->getPausing());
|
||||
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_WAITING_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_ONCE, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_ONCE, state_cfg->getPausing());
|
||||
}
|
||||
|
||||
// Verifies that load balancing configuration is parsed correctly.
|
||||
@@ -249,37 +251,37 @@ TEST_F(HAConfigTest, configureHotStandby) {
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_BACKUP_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER, state_cfg->getPausing());
|
||||
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_HOT_STANDBY_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER, state_cfg->getPausing());
|
||||
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_PARTNER_DOWN_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER, state_cfg->getPausing());
|
||||
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_READY_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER, state_cfg->getPausing());
|
||||
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_SYNCING_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER, state_cfg->getPausing());
|
||||
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_TERMINATED_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER, state_cfg->getPausing());
|
||||
|
||||
ASSERT_NO_THROW(state_cfg = impl->getConfig()->getStateMachineConfig()->
|
||||
getStateConfig(HA_WAITING_ST));
|
||||
ASSERT_TRUE(state_cfg);
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER, state_cfg->getPausing());
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER, state_cfg->getPausing());
|
||||
}
|
||||
|
||||
// This server name must not be empty.
|
||||
@@ -985,22 +987,22 @@ TEST_F(HAConfigTest, HAModeToString) {
|
||||
|
||||
// Test that conversion of the 'pause' value works correctly.
|
||||
TEST_F(HAConfigTest, stringToPausing) {
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_ALWAYS,
|
||||
EXPECT_EQ(STATE_PAUSE_ALWAYS,
|
||||
HAConfig::StateConfig::stringToPausing("always"));
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_NEVER,
|
||||
EXPECT_EQ(STATE_PAUSE_NEVER,
|
||||
HAConfig::StateConfig::stringToPausing("never"));
|
||||
EXPECT_EQ(HAConfig::StateConfig::PAUSE_ONCE,
|
||||
EXPECT_EQ(STATE_PAUSE_ONCE,
|
||||
HAConfig::StateConfig::stringToPausing("once"));
|
||||
}
|
||||
|
||||
// Test that pause parameter value is generated correctly.
|
||||
TEST_F(HAConfigTest, pausingToString) {
|
||||
EXPECT_EQ("always",
|
||||
HAConfig::StateConfig::pausingToString(HAConfig::StateConfig::PAUSE_ALWAYS));
|
||||
HAConfig::StateConfig::pausingToString(STATE_PAUSE_ALWAYS));
|
||||
EXPECT_EQ("never",
|
||||
HAConfig::StateConfig::pausingToString(HAConfig::StateConfig::PAUSE_NEVER));
|
||||
HAConfig::StateConfig::pausingToString(STATE_PAUSE_NEVER));
|
||||
EXPECT_EQ("once",
|
||||
HAConfig::StateConfig::pausingToString(HAConfig::StateConfig::PAUSE_ONCE));
|
||||
HAConfig::StateConfig::pausingToString(STATE_PAUSE_ONCE));
|
||||
|
||||
}
|
||||
|
||||
|
@@ -3573,7 +3573,9 @@ TEST_F(HAServiceStateMachineTest, stateTransitionsLoadBalancingPause) {
|
||||
FinalState(HA_LOAD_BALANCING_ST));
|
||||
EXPECT_TRUE(state_->isHeartbeatRunning());
|
||||
|
||||
service_->unpause();
|
||||
EXPECT_TRUE(service_->unpause());
|
||||
// An additional attempt to unpause should return false.
|
||||
EXPECT_FALSE(service_->unpause());
|
||||
|
||||
testTransition(MyState(HA_LOAD_BALANCING_ST), PartnerState(HA_TERMINATED_ST),
|
||||
FinalState(HA_TERMINATED_ST));
|
||||
@@ -3587,7 +3589,7 @@ TEST_F(HAServiceStateMachineTest, stateTransitionsLoadBalancingPause) {
|
||||
FinalState(HA_PARTNER_DOWN_ST));
|
||||
EXPECT_TRUE(state_->isHeartbeatRunning());
|
||||
|
||||
service_->unpause();
|
||||
EXPECT_TRUE(service_->unpause());
|
||||
|
||||
testTransition(MyState(HA_PARTNER_DOWN_ST), PartnerState(HA_LOAD_BALANCING_ST),
|
||||
FinalState(HA_WAITING_ST));
|
||||
@@ -3602,7 +3604,7 @@ TEST_F(HAServiceStateMachineTest, stateTransitionsLoadBalancingPause) {
|
||||
FinalState(HA_READY_ST));
|
||||
EXPECT_TRUE(state_->isHeartbeatRunning());
|
||||
|
||||
service_->unpause();
|
||||
EXPECT_TRUE(service_->unpause());
|
||||
|
||||
testTransition(MyState(HA_READY_ST), PartnerState(HA_LOAD_BALANCING_ST),
|
||||
FinalState(HA_LOAD_BALANCING_ST));
|
||||
@@ -3617,7 +3619,7 @@ TEST_F(HAServiceStateMachineTest, stateTransitionsLoadBalancingPause) {
|
||||
FinalState(HA_WAITING_ST));
|
||||
EXPECT_TRUE(state_->isHeartbeatRunning());
|
||||
|
||||
service_->unpause();
|
||||
EXPECT_TRUE(service_->unpause());
|
||||
|
||||
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_LOAD_BALANCING_ST),
|
||||
FinalState(HA_SYNCING_ST));
|
||||
@@ -3671,7 +3673,7 @@ TEST_F(HAServiceStateMachineTest, syncingTransitionsLoadBalancingPause) {
|
||||
EXPECT_NE(service_->getLastEvent(), HAService::HA_SYNCING_SUCCEEDED_EVT);
|
||||
|
||||
// Unpause the state machine.
|
||||
service_->unpause();
|
||||
EXPECT_TRUE(service_->unpause());
|
||||
|
||||
// Retry the test. It should now transition to the ready state.
|
||||
testSyncingTransition(FinalState(HA_READY_ST));
|
||||
|
@@ -1,70 +0,0 @@
|
||||
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include <ha_state_machine_control.h>
|
||||
#include <ha_test.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace isc::ha;
|
||||
using namespace isc::ha::test;
|
||||
|
||||
namespace {
|
||||
|
||||
class HAStateMachineControlTest : public HATest {
|
||||
public:
|
||||
|
||||
/// @brief Constructor.
|
||||
HAStateMachineControlTest()
|
||||
: HATest() {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// This test verifies that pausing HA state machine works as expected.
|
||||
TEST_F(HAStateMachineControlTest, pause) {
|
||||
HAConfigPtr config = createValidConfiguration();
|
||||
|
||||
// Always pause in the waiting state and pause on first transition to
|
||||
// the ready state. Do not pause for other states.
|
||||
config->getStateMachineConfig()->getStateConfig(HA_WAITING_ST)->setPausing("always");
|
||||
config->getStateMachineConfig()->getStateConfig(HA_READY_ST)->setPausing("once");
|
||||
|
||||
// Initially we shouldn't be paused.
|
||||
HAStateMachineControl control(config);
|
||||
EXPECT_FALSE(control.amPaused());
|
||||
|
||||
// Should not pause in load-balancing state.
|
||||
EXPECT_NO_THROW(control.notify(HA_LOAD_BALANCING_ST));
|
||||
EXPECT_FALSE(control.amPaused());
|
||||
|
||||
// Should always pause in waiting state.
|
||||
EXPECT_NO_THROW(control.notify(HA_WAITING_ST));
|
||||
EXPECT_TRUE(control.amPaused());
|
||||
|
||||
control.unpause();
|
||||
EXPECT_FALSE(control.amPaused());
|
||||
|
||||
// Should pause once in the ready state.
|
||||
EXPECT_NO_THROW(control.notify(HA_READY_ST));
|
||||
EXPECT_TRUE(control.amPaused());
|
||||
|
||||
control.unpause();
|
||||
EXPECT_FALSE(control.amPaused());
|
||||
|
||||
// Do not pause the second time in the ready state.
|
||||
EXPECT_NO_THROW(control.notify(HA_READY_ST));
|
||||
EXPECT_FALSE(control.amPaused());
|
||||
|
||||
// Never pause in the load-balancing state.
|
||||
EXPECT_NO_THROW(control.notify(HA_LOAD_BALANCING_ST));
|
||||
EXPECT_FALSE(control.amPaused());
|
||||
|
||||
// Always pause in the waiting state.
|
||||
EXPECT_NO_THROW(control.notify(HA_WAITING_ST));
|
||||
EXPECT_TRUE(control.amPaused());
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user