setWeight(d_config.d_weight);
}
- if (d_config.availability == Availability::Lazy && d_config.d_lazyHealthCheckSampleSize > 0) {
+ if (d_config.d_availability == Availability::Auto && d_config.d_healthCheckMode == HealthCheckMode::Lazy && d_config.d_lazyHealthCheckSampleSize > 0) {
d_lazyHealthCheckStats.lock()->d_lastResults.set_capacity(d_config.d_lazyHealthCheckSampleSize);
setUpStatus(true);
}
void DownstreamState::reportResponse(uint8_t rcode)
{
- if (d_config.availability == Availability::Lazy && d_config.d_lazyHealthCheckSampleSize > 0) {
+ if (d_config.d_availability == Availability::Auto && d_config.d_healthCheckMode == HealthCheckMode::Lazy && d_config.d_lazyHealthCheckSampleSize > 0) {
bool failure = d_config.d_lazyHealthCheckMode == LazyHealthCheckMode::TimeoutOrServFail ? rcode == RCode::ServFail : false;
d_lazyHealthCheckStats.lock()->d_lastResults.push_back(failure);
}
void DownstreamState::reportTimeoutOrError()
{
- if (d_config.availability == Availability::Lazy && d_config.d_lazyHealthCheckSampleSize > 0) {
+ if (d_config.d_availability == Availability::Auto && d_config.d_healthCheckMode == HealthCheckMode::Lazy && d_config.d_lazyHealthCheckSampleSize > 0) {
d_lazyHealthCheckStats.lock()->d_lastResults.push_back(true);
}
}
bool DownstreamState::healthCheckRequired(std::optional<time_t> currentTime)
{
- if (d_config.availability == DownstreamState::Availability::Lazy) {
+ if (d_config.d_availability != DownstreamState::Availability::Auto) {
+ return false;
+ }
+
+ if (d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Lazy) {
auto stats = d_lazyHealthCheckStats.lock();
if (stats->d_status == LazyHealthCheckStats::LazyStatus::PotentialFailure) {
vinfolog("Sending health-check query for %s which is still in the Potential Failure state", getNameWithAddr());
return false;
}
- else if (d_config.availability == DownstreamState::Availability::Auto) {
+ else if (d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Active) {
if (d_nextCheck > 1) {
--d_nextCheck;
setUpStatus(newResult);
if (newResult == false) {
currentCheckFailures++;
- if (d_config.availability == DownstreamState::Availability::Lazy) {
+ if (d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Lazy) {
auto stats = d_lazyHealthCheckStats.lock();
stats->d_status = LazyHealthCheckStats::LazyStatus::Failed;
updateNextLazyHealthCheck(*stats, false);
and we didn't reach the threshold yet, let's stay down */
newState = false;
- if (d_config.availability == DownstreamState::Availability::Lazy) {
+ if (d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Lazy) {
auto stats = d_lazyHealthCheckStats.lock();
updateNextLazyHealthCheck(*stats, false);
}
}
if (newState) {
- if (d_config.availability == DownstreamState::Availability::Lazy) {
+ if (d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Lazy) {
auto stats = d_lazyHealthCheckStats.lock();
vinfolog("Backend %s had %d successful checks, moving to Healthy", getNameWithAddr(), std::to_string(consecutiveSuccessfulChecks));
stats->d_status = LazyHealthCheckStats::LazyStatus::Healthy;
and we did not reach the threshold yet, let's stay up */
newState = true;
}
- else if (d_config.availability == DownstreamState::Availability::Lazy) {
+ else if (d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Lazy) {
auto stats = d_lazyHealthCheckStats.lock();
vinfolog("Backend %s failed its health-check, moving from Potential failure to Failed", getNameWithAddr());
stats->d_status = LazyHealthCheckStats::LazyStatus::Failed;
return false;
}
-std::optional<DownstreamState::Availability> DownstreamState::getAvailabilityFromStr(const std::string& mode)
+bool DownstreamState::parseAvailabilityConfigFromStr(DownstreamState::Config& config, const std::string str)
{
- if (pdns_iequals(mode, "auto")) {
- return DownstreamState::Availability::Auto;
+ if (pdns_iequals(str, "auto")) {
+ config.d_availability = DownstreamState::Availability::Auto;
+ config.d_healthCheckMode = DownstreamState::HealthCheckMode::Active;
+ return true;
}
- if (pdns_iequals(mode, "lazy")) {
- return DownstreamState::Availability::Lazy;
+ if (pdns_iequals(str, "lazy")) {
+ config.d_availability = DownstreamState::Availability::Auto;
+ config.d_healthCheckMode = DownstreamState::HealthCheckMode::Lazy;
+ return true;
}
- if (pdns_iequals(mode, "up")) {
- return DownstreamState::Availability::Up;
+ if (pdns_iequals(str, "up")) {
+ config.d_availability = DownstreamState::Availability::Up;
+ return true;
}
- if (pdns_iequals(mode, "down")) {
- return DownstreamState::Availability::Down;
+ if (pdns_iequals(str, "down")) {
+ config.d_availability = DownstreamState::Availability::Down;
+ return true;
}
- return std::nullopt;
+ return false;
}
size_t ServerPool::countServers(bool upOnly)
str << base << "queries" << ' ' << state->queries.load() << " " << now << "\r\n";
str << base << "responses" << ' ' << state->responses.load() << " " << now << "\r\n";
str << base << "drops" << ' ' << state->reuseds.load() << " " << now << "\r\n";
- str << base << "latency" << ' ' << (state->d_config.availability != DownstreamState::Availability::Down ? state->latencyUsec / 1000.0 : 0) << " " << now << "\r\n";
- str << base << "latencytcp" << ' ' << (state->d_config.availability != DownstreamState::Availability::Down ? state->latencyUsecTCP / 1000.0 : 0) << " " << now << "\r\n";
+ str << base << "latency" << ' ' << (state->d_config.d_availability != DownstreamState::Availability::Down ? state->latencyUsec / 1000.0 : 0) << " " << now << "\r\n";
+ str << base << "latencytcp" << ' ' << (state->d_config.d_availability != DownstreamState::Availability::Down ? state->latencyUsecTCP / 1000.0 : 0) << " " << now << "\r\n";
str << base << "senderrors" << ' ' << state->sendErrors.load() << " " << now << "\r\n";
str << base << "outstanding" << ' ' << state->outstanding.load() << " " << now << "\r\n";
str << base << "tcpdiedsendingquery" << ' ' << state->tcpDiedSendingQuery.load() << " " << now << "\r\n";
getLuaFunctionFromConfiguration<DownstreamState::checkfunc_t>(backendConfig.checkFunction, hcConf.function, hcConf.lua, hcConf.lua_file, "backend health-check");
- auto availability = DownstreamState::getAvailabilityFromStr(std::string(hcConf.mode));
- if (availability) {
- backendConfig.availability = *availability;
- }
+ DownstreamState::parseAvailabilityConfigFromStr(backendConfig, std::string(hcConf.mode));
backendConfig.d_lazyHealthCheckSampleSize = hcConf.lazy.sample_size;
backendConfig.d_lazyHealthCheckMinSampleCount = hcConf.lazy.min_sample_count;
config.remote = discoveredConfig.d_addr;
config.remote.setPort(discoveredConfig.d_port);
- if (backend.keepAfterUpgrade && config.availability == DownstreamState::Availability::Up) {
+ if (backend.keepAfterUpgrade && config.d_availability == DownstreamState::Availability::Up) {
/* it's OK to keep the forced state if we replace the initial
backend, but if we are adding a new backend, it should not
inherit that setting, especially since DoX backends are much
more likely to fail (certificate errors, ...) */
if (config.d_upgradeToLazyHealthChecks) {
- config.availability = DownstreamState::Availability::Lazy;
+ config.d_availability = DownstreamState::Availability::Auto;
+ config.d_healthCheckMode = DownstreamState::HealthCheckMode::Lazy;
}
else {
- config.availability = DownstreamState::Availability::Auto;
+ config.d_availability = DownstreamState::Availability::Auto;
+ config.d_healthCheckMode = DownstreamState::HealthCheckMode::Active;
}
}
luaCtx.registerFunction("isUp", &DownstreamState::isUp);
luaCtx.registerFunction("setDown", &DownstreamState::setDown);
luaCtx.registerFunction("setUp", &DownstreamState::setUp);
+ luaCtx.registerFunction<std::string (DownstreamState::*)() const>("getHealthCheckMode", [](const DownstreamState& state) -> std::string {
+ if (state.d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Active) {
+ return "active";
+ }
+ return "lazy";
+ });
luaCtx.registerFunction<void (DownstreamState::*)(boost::optional<bool> newStatus)>("setAuto", [](DownstreamState& state, boost::optional<bool> newStatus) {
if (newStatus) {
state.setUpStatus(*newStatus);
}
state.setAuto();
});
+ luaCtx.registerFunction<void (DownstreamState::*)(boost::optional<bool> newStatus)>("setActiveAuto", [](DownstreamState& state, boost::optional<bool> newStatus) {
+ if (newStatus) {
+ state.setUpStatus(*newStatus);
+ }
+ state.setActiveAuto();
+ });
luaCtx.registerFunction<void (DownstreamState::*)(boost::optional<bool> newStatus)>("setLazyAuto", [](DownstreamState& state, boost::optional<bool> newStatus) {
if (newStatus) {
state.setUpStatus(*newStatus);
if (getOptionalValue<std::string>(vars, "healthCheckMode", valueStr) > 0) {
const auto& mode = valueStr;
- auto availability = DownstreamState::getAvailabilityFromStr(mode);
- if (availability) {
- config.availability = *availability;
- }
- else {
+ if (!DownstreamState::parseAvailabilityConfigFromStr(config, valueStr)) {
warnlog("Ignoring unknown value '%s' for 'healthCheckMode' on 'newServer'", mode);
}
}
static void addServerToJSON(Json::array& servers, int identifier, const std::shared_ptr<DownstreamState>& backend)
{
string status;
- if (backend->d_config.availability == DownstreamState::Availability::Up) {
+ if (backend->d_config.d_availability == DownstreamState::Availability::Up) {
status = "UP";
}
- else if (backend->d_config.availability == DownstreamState::Availability::Down) {
+ else if (backend->d_config.d_availability == DownstreamState::Availability::Down) {
status = "DOWN";
}
else {
{"dropRate", (double)backend->dropRate}};
/* sending a latency for a DOWN server doesn't make sense */
- if (backend->d_config.availability == DownstreamState::Availability::Down) {
+ if (backend->d_config.d_availability == DownstreamState::Availability::Down) {
server["latency"] = nullptr;
server["tcpLatency"] = nullptr;
}
auto mplexer = std::unique_ptr<FDMultiplexer>(FDMultiplexer::getMultiplexerSilent(states.size()));
for (auto& dss : states) {
- if (dss->d_config.availability == DownstreamState::Availability::Auto || dss->d_config.availability == DownstreamState::Availability::Lazy) {
- if (dss->d_config.availability == DownstreamState::Availability::Auto) {
+ if (dss->d_config.d_availability == DownstreamState::Availability::Auto) {
+ if (dss->d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Active) {
dss->d_nextCheck = dss->d_config.checkInterval;
}
{
Up,
Down,
- Auto,
+ Auto
+ };
+ enum class HealthCheckMode : uint8_t
+ {
+ Active,
Lazy
};
enum class LazyHealthCheckMode : uint8_t
uint8_t minRiseSuccesses{1};
uint8_t udpTimeout{0};
uint8_t dscp{0};
- Availability availability{Availability::Auto};
+ Availability d_availability{Availability::Auto};
+ HealthCheckMode d_healthCheckMode{HealthCheckMode::Active};
bool d_tlsSubjectIsAddr{false};
bool mustResolve{false};
bool useECS{false};
public:
static bool parseSourceParameter(const std::string& source, Config& config);
- static std::optional<DownstreamState::Availability> getAvailabilityFromStr(const std::string& mode);
+ static bool parseAvailabilityConfigFromStr(DownstreamState::Config& config, const std::string str);
void updateStatisticsInfo()
{
bool isUp() const
{
- if (d_config.availability == Availability::Down) {
+ if (d_config.d_availability == Availability::Down) {
return false;
}
- else if (d_config.availability == Availability::Up) {
+ else if (d_config.d_availability == Availability::Up) {
return true;
}
return upStatus.load(std::memory_order_relaxed);
void setUp()
{
- d_config.availability = Availability::Up;
+ d_config.d_availability = Availability::Up;
}
void setUpStatus(bool newStatus)
}
void setDown()
{
- d_config.availability = Availability::Down;
+ d_config.d_availability = Availability::Down;
latencyUsec = 0.0;
latencyUsecTCP = 0.0;
}
void setAuto()
{
- d_config.availability = Availability::Auto;
+ d_config.d_availability = Availability::Auto;
+ }
+ void setActiveAuto()
+ {
+ d_config.d_availability = Availability::Auto;
+ d_config.d_healthCheckMode = HealthCheckMode::Active;
}
void setLazyAuto()
{
- d_config.availability = Availability::Lazy;
+ d_config.d_availability = Availability::Auto;
+ d_config.d_healthCheckMode = HealthCheckMode::Lazy;
d_lazyHealthCheckStats.lock()->d_lastResults.set_capacity(d_config.d_lazyHealthCheckSampleSize);
}
bool healthCheckRequired(std::optional<time_t> currentTime = std::nullopt);
string getStatus() const
{
string status;
- if (d_config.availability == DownstreamState::Availability::Up) {
+ if (d_config.d_availability == DownstreamState::Availability::Up) {
status = "UP";
}
- else if (d_config.availability == DownstreamState::Availability::Down) {
+ else if (d_config.d_availability == DownstreamState::Availability::Down) {
status = "DOWN";
}
else {
:returns: The number of dropped queries
+ .. method:: Server:getHealthCheckMode() -> str
+
+ .. versionadded:: 2.0.0
+
+ Get the current health-check mode, ``active`` or ``lazy``. Note that health-checks might be disabled because :meth:`Server:setUp` or :meth:`Server:setDown`
+ were called, in which case this method will return the health-check more that will be restored ud :meth:`Server:setAuto` is called.
+
+ :returns: The current health-check mode
+
.. method:: Server:getOutstanding() -> int
Get the number of outstanding queries for this server.
Returns the up status of the server.
Result is based on the administrative status of the server (as set by either :meth:`Server:setDown` or :meth:`Server:setUp`).
- If no administrative status is set (see :meth:`Server:setAuto` and :meth:`Server:setLazyAuto`), result is based on :attr:`Server.upStatus`
+ If no administrative status is set (see :meth:`Server:setAuto`, :meth:`Server:setActiveAuto` and :meth:`Server:setLazyAuto`), result is based on :attr:`Server.upStatus`
:returns: true when the server is up, false otherwise
:param str pool: The pool to remove the server from
+ .. method:: Server:setActiveAuto([status])
+
+ .. versionadded:: 2.0.0
+
+ Set the server in the 'active' health-check mode, which will send health-check queries to the backend every ``checkInterval`` seconds.
+ See also :meth:`Server:setLazyAuto` for a passive mode where health-check queries are only sent after a configurable threshold of regular queries failing,
+ and :ref:`Healthcheck` for a more detailed explanation.
+
+ :param bool status: Set the initial status of the server to ``up`` (true) or ``down`` (false) instead of using the last known status
+
.. method:: Server:setAuto([status])
- Set the server in the default ``auto`` state, regularly sending health-check queries to the backend. See also :meth:`Server:setLazyAuto` for a
- passive mode where health-check queries are only sent after a configurable threshold of regular queries failing.
- This will enable health check queries that will set the server ``up`` and ``down`` appropriately.
+ .. versionchanged:: 2.0.0
+ Before 2.0.0 this option forced the health-check mode to ``active`` (see :meth:`Server:setActiveAuto`). After 2.0.0 it restores the previous health-check mode instead.
+
+ Set the server in the default ``auto`` state, enabling health check queries that will set the server ``up`` and ``down`` appropriately.
+ See :meth:`Server:setActiveAuto`, :meth:`Server:setLazyAuto` and :ref:`Healthcheck` to understand the different health-check modes.
:param bool status: Set the initial status of the server to ``up`` (true) or ``down`` (false) instead of using the last known status
XPF support has been removed.
+:meth:`Server:setAuto` used to reset the health-check mode to ``active`` even if it had previously been set to ``lazy`` via :meth:`Server:setLazyAuto`. This is no longer the case, and :meth:`Server:setActiveAuto` should be used instead to set the health-check mode to ``Active``.
+
1.8.x to 1.9.0
--------------
{
DownstreamState::Config config;
DownstreamState ds(std::move(config), nullptr, false);
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Active);
BOOST_CHECK_EQUAL(ds.isUp(), false);
BOOST_CHECK_EQUAL(ds.getStatus(), "down");
BOOST_CHECK_EQUAL(ds.healthCheckRequired(), true);
ds.setUp();
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Up);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Up);
BOOST_CHECK_EQUAL(ds.isUp(), true);
BOOST_CHECK_EQUAL(ds.getStatus(), "UP");
BOOST_CHECK_EQUAL(ds.healthCheckRequired(), false);
ds.setDown();
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Down);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Down);
BOOST_CHECK_EQUAL(ds.isUp(), false);
BOOST_CHECK_EQUAL(ds.getStatus(), "DOWN");
BOOST_CHECK_EQUAL(ds.healthCheckRequired(), false);
ds.setAuto();
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
BOOST_CHECK_EQUAL(ds.isUp(), false);
BOOST_CHECK_EQUAL(ds.getStatus(), "down");
BOOST_CHECK_EQUAL(ds.healthCheckRequired(), true);
ds.submitHealthCheckResult(true, true);
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
BOOST_CHECK_EQUAL(ds.isUp(), true);
BOOST_CHECK_EQUAL(ds.getStatus(), "up");
BOOST_CHECK_EQUAL(ds.healthCheckRequired(), true);
config.remote = ComboAddress("0.0.0.0");
DownstreamState ds(std::move(config), nullptr, false);
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Active);
ds.setUpStatus(true);
BOOST_CHECK_EQUAL(ds.isUp(), true);
BOOST_CHECK_EQUAL(ds.getStatus(), "up");
}
/* four failed checks is not enough */
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
BOOST_CHECK_EQUAL(ds.isUp(), true);
BOOST_CHECK_EQUAL(ds.getStatus(), "up");
/* but five is */
ds.submitHealthCheckResult(false, false);
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
BOOST_CHECK_EQUAL(ds.isUp(), false);
BOOST_CHECK_EQUAL(ds.getStatus(), "down");
/* only one successful check is needed to go back up */
ds.submitHealthCheckResult(false, true);
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
BOOST_CHECK_EQUAL(ds.isUp(), true);
BOOST_CHECK_EQUAL(ds.getStatus(), "up");
}
config.remote = ComboAddress("0.0.0.0");
DownstreamState ds(std::move(config), nullptr, false);
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Active);
BOOST_CHECK_EQUAL(ds.isUp(), false);
BOOST_CHECK_EQUAL(ds.getStatus(), "down");
}
/* four successful checks is not enough */
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
BOOST_CHECK_EQUAL(ds.isUp(), false);
BOOST_CHECK_EQUAL(ds.getStatus(), "down");
/* but five is */
ds.submitHealthCheckResult(false, true);
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
BOOST_CHECK_EQUAL(ds.isUp(), true);
BOOST_CHECK_EQUAL(ds.getStatus(), "up");
/* only one failed check is needed to go back down */
ds.submitHealthCheckResult(false, false);
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
BOOST_CHECK_EQUAL(ds.isUp(), false);
BOOST_CHECK_EQUAL(ds.getStatus(), "down");
}
config.d_lazyHealthCheckMinSampleCount = 11;
config.d_lazyHealthCheckThreshold = 20;
config.d_lazyHealthCheckUseExponentialBackOff = false;
- config.availability = DownstreamState::Availability::Lazy;
+ config.d_availability = DownstreamState::Availability::Auto;
+ config.d_healthCheckMode = DownstreamState::HealthCheckMode::Lazy;
/* prevents a re-connection */
config.remote = ComboAddress("0.0.0.0");
DownstreamState ds(std::move(config), nullptr, false);
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Lazy);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
BOOST_CHECK_EQUAL(ds.isUp(), true);
BOOST_CHECK_EQUAL(ds.getStatus(), "up");
BOOST_CHECK_EQUAL(ds.healthCheckRequired(), false);
config.d_lazyHealthCheckUseExponentialBackOff = true;
config.d_lazyHealthCheckMaxBackOff = 600;
config.d_lazyHealthCheckFailedInterval = 15;
- config.availability = DownstreamState::Availability::Lazy;
+ DownstreamState::parseAvailabilityConfigFromStr(config, "lazy");
+
/* prevents a re-connection */
config.remote = ComboAddress("0.0.0.0");
DownstreamState ds(std::move(config), nullptr, false);
- BOOST_CHECK(ds.d_config.availability == DownstreamState::Availability::Lazy);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Lazy);
BOOST_CHECK_EQUAL(ds.isUp(), true);
BOOST_CHECK_EQUAL(ds.getStatus(), "up");
BOOST_CHECK_EQUAL(ds.healthCheckRequired(), false);
BOOST_CHECK_EQUAL(ds.healthCheckRequired(), false);
}
+BOOST_AUTO_TEST_CASE(test_CheckAutoRestorePreviousHealthCheckMode)
+{
+ DownstreamState::Config config;
+ DownstreamState::parseAvailabilityConfigFromStr(config, "lazy");
+ /* prevents a re-connection */
+ config.remote = ComboAddress("0.0.0.0");
+
+ DownstreamState ds(std::move(config), nullptr, false);
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Lazy);
+ ds.setUp();
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Up);
+ ds.setAuto();
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Lazy);
+ ds.setActiveAuto();
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Active);
+ ds.setUp();
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Up);
+ ds.setAuto();
+ BOOST_CHECK(ds.d_config.d_availability == DownstreamState::Availability::Auto);
+ BOOST_CHECK(ds.d_config.d_healthCheckMode == DownstreamState::HealthCheckMode::Active);
+}
+
BOOST_AUTO_TEST_SUITE_END()
self.sendConsoleCommand("getServer(0):setUp()")
self.assertEqual(self.getBackendStatus(), 'up')
+ self.assertEqual(self.sendConsoleCommand("getServer(0):getHealthCheckMode()").rstrip(), "active")
before = TestDefaultHealthCheck._healthCheckCounter
time.sleep(1.5)
self.sendConsoleCommand("getServer(0):setAuto()")
# we get back the previous state, which was up
self.assertEqual(self.getBackendStatus(), 'up')
+ self.assertEqual(self.sendConsoleCommand("getServer(0):getHealthCheckMode()").rstrip(), "active")
before = TestDefaultHealthCheck._healthCheckCounter
time.sleep(1.5)
self.sendConsoleCommand("getServer(0):setDown()")
self.assertEqual(self.getBackendStatus(), 'down')
+ self.assertEqual(self.sendConsoleCommand("getServer(0):getHealthCheckMode()").rstrip(), "active")
self.sendConsoleCommand("getServer(0):setAuto(false)")
before = TestDefaultHealthCheck._healthCheckCounter
self.assertGreater(TestDefaultHealthCheck._healthCheckCounter, before)
self.assertEqual(self.getBackendStatus(), 'up')
self.assertEqual(self.getBackendMetric(0, 'healthCheckFailures'), 0)
+ self.assertEqual(self.sendConsoleCommand("getServer(0):getHealthCheckMode()").rstrip(), "active")
+
+ self.sendConsoleCommand("getServer(0):setLazyAuto()")
+ self.assertEqual(self.sendConsoleCommand("getServer(0):getHealthCheckMode()").rstrip(), "lazy")
+ self.sendConsoleCommand("getServer(0):setDown()")
+ self.sendConsoleCommand("getServer(0):setAuto()")
+ self.assertEqual(self.sendConsoleCommand("getServer(0):getHealthCheckMode()").rstrip(), "lazy")
+ self.sendConsoleCommand("getServer(0):setActiveAuto()")
+ self.assertEqual(self.sendConsoleCommand("getServer(0):getHealthCheckMode()").rstrip(), "active")
class TestHealthCheckForcedUP(HealthCheckTest):
# this test suite uses a different responder port