2019-02-25 14:48:22 +01:00
|
|
|
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
2017-10-19 17:32:52 +02:00
|
|
|
|
|
|
|
#include "icinga/host.hpp"
|
2017-12-13 11:35:38 +01:00
|
|
|
#include <bitset>
|
2017-10-19 17:32:52 +02:00
|
|
|
#include <iostream>
|
2017-12-13 11:35:38 +01:00
|
|
|
#include <BoostTestTargetConfig.h>
|
2017-10-19 17:32:52 +02:00
|
|
|
|
|
|
|
using namespace icinga;
|
|
|
|
|
|
|
|
#ifdef I2_DEBUG
|
|
|
|
static CheckResult::Ptr MakeCheckResult(ServiceState state)
|
|
|
|
{
|
|
|
|
CheckResult::Ptr cr = new CheckResult();
|
|
|
|
|
|
|
|
cr->SetState(state);
|
|
|
|
|
|
|
|
double now = Utility::GetTime();
|
|
|
|
cr->SetScheduleStart(now);
|
|
|
|
cr->SetScheduleEnd(now);
|
|
|
|
cr->SetExecutionStart(now);
|
|
|
|
cr->SetExecutionEnd(now);
|
|
|
|
|
|
|
|
Utility::IncrementTime(60);
|
|
|
|
|
|
|
|
return cr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void LogFlapping(const Checkable::Ptr& obj)
|
|
|
|
{
|
|
|
|
std::bitset<20> stateChangeBuf = obj->GetFlappingBuffer();
|
|
|
|
int oldestIndex = (obj->GetFlappingBuffer() & 0xFF00000) >> 20;
|
|
|
|
|
2017-12-19 15:50:05 +01:00
|
|
|
std::cout << "Flapping: " << obj->IsFlapping() << "\nHT: " << obj->GetFlappingThresholdHigh() << " LT: "
|
|
|
|
<< obj->GetFlappingThresholdLow() << "\nOur value: " << obj->GetFlappingCurrent() << "\nPtr: " << oldestIndex
|
|
|
|
<< " Buf: " << stateChangeBuf.to_ulong() << '\n';
|
2017-10-19 17:32:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void LogHostStatus(const Host::Ptr &host)
|
|
|
|
{
|
|
|
|
std::cout << "Current status: state: " << host->GetState() << " state_type: " << host->GetStateType()
|
2018-04-10 18:11:26 +02:00
|
|
|
<< " check attempt: " << host->GetCheckAttempt() << "/" << host->GetMaxCheckAttempts() << " Active: " << host->IsActive() << std::endl;
|
2017-10-19 17:32:52 +02:00
|
|
|
}
|
|
|
|
#endif /* I2_DEBUG */
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE(icinga_checkable_flapping)
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(host_not_flapping)
|
|
|
|
{
|
|
|
|
#ifndef I2_DEBUG
|
2017-12-19 15:50:05 +01:00
|
|
|
BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
|
2017-10-19 17:32:52 +02:00
|
|
|
#else /* I2_DEBUG */
|
|
|
|
std::cout << "Running test with a non-flapping host...\n";
|
|
|
|
|
|
|
|
Host::Ptr host = new Host();
|
|
|
|
host->SetName("test");
|
|
|
|
host->SetEnableFlapping(true);
|
|
|
|
host->SetMaxCheckAttempts(5);
|
2018-04-10 18:11:26 +02:00
|
|
|
host->SetActive(true);
|
2017-10-19 17:32:52 +02:00
|
|
|
|
|
|
|
// Host otherwise is soft down
|
|
|
|
host->SetState(HostUp);
|
|
|
|
host->SetStateType(StateTypeHard);
|
|
|
|
|
|
|
|
Utility::SetTime(0);
|
|
|
|
|
|
|
|
BOOST_CHECK(host->GetFlappingCurrent() == 0);
|
|
|
|
|
|
|
|
LogFlapping(host);
|
|
|
|
LogHostStatus(host);
|
|
|
|
|
|
|
|
// watch the state being stable
|
|
|
|
int i = 0;
|
|
|
|
while (i++ < 10) {
|
|
|
|
// For some reason, elusive to me, the first check is a state change
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceOK));
|
|
|
|
|
|
|
|
LogFlapping(host);
|
|
|
|
LogHostStatus(host);
|
|
|
|
|
|
|
|
BOOST_CHECK(host->GetState() == 0);
|
|
|
|
BOOST_CHECK(host->GetCheckAttempt() == 1);
|
|
|
|
BOOST_CHECK(host->GetStateType() == StateTypeHard);
|
|
|
|
|
|
|
|
//Should not be flapping
|
|
|
|
BOOST_CHECK(!host->IsFlapping());
|
|
|
|
BOOST_CHECK(host->GetFlappingCurrent() < 30.0);
|
|
|
|
}
|
|
|
|
#endif /* I2_DEBUG */
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(host_flapping)
|
|
|
|
{
|
|
|
|
#ifndef I2_DEBUG
|
2017-12-19 15:50:05 +01:00
|
|
|
BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
|
2017-10-19 17:32:52 +02:00
|
|
|
#else /* I2_DEBUG */
|
|
|
|
std::cout << "Running test with host changing state with every check...\n";
|
|
|
|
|
|
|
|
Host::Ptr host = new Host();
|
|
|
|
host->SetName("test");
|
|
|
|
host->SetEnableFlapping(true);
|
|
|
|
host->SetMaxCheckAttempts(5);
|
2018-04-10 18:11:26 +02:00
|
|
|
host->SetActive(true);
|
2017-10-19 17:32:52 +02:00
|
|
|
|
|
|
|
Utility::SetTime(0);
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
while (i++ < 25) {
|
|
|
|
if (i % 2)
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceOK));
|
|
|
|
else
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
|
|
|
|
LogFlapping(host);
|
|
|
|
LogHostStatus(host);
|
|
|
|
|
|
|
|
//30 Percent is our high Threshold
|
|
|
|
if (i >= 6) {
|
|
|
|
BOOST_CHECK(host->IsFlapping());
|
|
|
|
} else {
|
|
|
|
BOOST_CHECK(!host->IsFlapping());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* I2_DEBUG */
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(host_flapping_recover)
|
|
|
|
{
|
|
|
|
#ifndef I2_DEBUG
|
2017-12-19 15:50:05 +01:00
|
|
|
BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
|
2017-10-19 17:32:52 +02:00
|
|
|
#else /* I2_DEBUG */
|
|
|
|
std::cout << "Running test with flapping recovery...\n";
|
|
|
|
|
|
|
|
Host::Ptr host = new Host();
|
|
|
|
host->SetName("test");
|
|
|
|
host->SetEnableFlapping(true);
|
|
|
|
host->SetMaxCheckAttempts(5);
|
2018-04-10 18:11:26 +02:00
|
|
|
host->SetActive(true);
|
2017-10-19 17:32:52 +02:00
|
|
|
|
|
|
|
// Host otherwise is soft down
|
|
|
|
host->SetState(HostUp);
|
|
|
|
host->SetStateType(StateTypeHard);
|
|
|
|
|
|
|
|
Utility::SetTime(0);
|
|
|
|
|
2017-12-19 15:50:05 +01:00
|
|
|
// A few warning
|
2017-10-19 17:32:52 +02:00
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
|
|
|
|
LogFlapping(host);
|
|
|
|
LogHostStatus(host);
|
|
|
|
for (int i = 0; i <= 7; i++) {
|
|
|
|
if (i % 2)
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceOK));
|
|
|
|
else
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
}
|
|
|
|
|
|
|
|
LogFlapping(host);
|
|
|
|
LogHostStatus(host);
|
|
|
|
|
|
|
|
// We should be flapping now
|
|
|
|
BOOST_CHECK(host->GetFlappingCurrent() > 30.0);
|
|
|
|
BOOST_CHECK(host->IsFlapping());
|
|
|
|
|
|
|
|
// Now recover from flapping
|
|
|
|
int count = 0;
|
|
|
|
while (host->IsFlapping()) {
|
|
|
|
BOOST_CHECK(host->GetFlappingCurrent() > 25.0);
|
|
|
|
BOOST_CHECK(host->IsFlapping());
|
|
|
|
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
LogFlapping(host);
|
|
|
|
LogHostStatus(host);
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cout << "Recovered from flapping after " << count << " Warning results.\n";
|
|
|
|
|
|
|
|
BOOST_CHECK(host->GetFlappingCurrent() < 25.0);
|
|
|
|
BOOST_CHECK(!host->IsFlapping());
|
|
|
|
#endif /* I2_DEBUG */
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(host_flapping_docs_example)
|
|
|
|
{
|
|
|
|
#ifndef I2_DEBUG
|
2017-12-19 15:50:05 +01:00
|
|
|
BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
|
2017-10-19 17:32:52 +02:00
|
|
|
#else /* I2_DEBUG */
|
|
|
|
std::cout << "Simulating the documentation example...\n";
|
|
|
|
|
|
|
|
Host::Ptr host = new Host();
|
|
|
|
host->SetName("test");
|
|
|
|
host->SetEnableFlapping(true);
|
|
|
|
host->SetMaxCheckAttempts(5);
|
2018-04-10 18:11:26 +02:00
|
|
|
host->SetActive(true);
|
2017-10-19 17:32:52 +02:00
|
|
|
|
|
|
|
// Host otherwise is soft down
|
|
|
|
host->SetState(HostUp);
|
|
|
|
host->SetStateType(StateTypeHard);
|
|
|
|
|
|
|
|
Utility::SetTime(0);
|
|
|
|
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceOK));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceOK));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceOK));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceOK));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceOK));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceOK));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceOK));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceWarning));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
|
|
|
|
|
|
|
|
LogFlapping(host);
|
|
|
|
LogHostStatus(host);
|
|
|
|
BOOST_CHECK(host->GetFlappingCurrent() == 39.1);
|
|
|
|
BOOST_CHECK(host->IsFlapping());
|
|
|
|
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
|
|
|
|
host->ProcessCheckResult(MakeCheckResult(ServiceCritical));
|
|
|
|
|
|
|
|
LogFlapping(host);
|
|
|
|
LogHostStatus(host);
|
|
|
|
BOOST_CHECK(host->GetFlappingCurrent() < 25.0);
|
|
|
|
BOOST_CHECK(!host->IsFlapping());
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|