summaryrefslogtreecommitdiffstats
path: root/test/icinga-checkable-flapping.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/icinga-checkable-flapping.cpp')
-rw-r--r--test/icinga-checkable-flapping.cpp248
1 files changed, 248 insertions, 0 deletions
diff --git a/test/icinga-checkable-flapping.cpp b/test/icinga-checkable-flapping.cpp
new file mode 100644
index 0000000..bc30564
--- /dev/null
+++ b/test/icinga-checkable-flapping.cpp
@@ -0,0 +1,248 @@
+/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
+
+#include "icinga/host.hpp"
+#include <bitset>
+#include <iostream>
+#include <BoostTestTargetConfig.h>
+
+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;
+
+ std::cout << "Flapping: " << obj->IsFlapping() << "\nHT: " << obj->GetFlappingThresholdHigh() << " LT: "
+ << obj->GetFlappingThresholdLow() << "\nOur value: " << obj->GetFlappingCurrent() << "\nPtr: " << oldestIndex
+ << " Buf: " << stateChangeBuf.to_ulong() << '\n';
+}
+
+
+static void LogHostStatus(const Host::Ptr &host)
+{
+ std::cout << "Current status: state: " << host->GetState() << " state_type: " << host->GetStateType()
+ << " check attempt: " << host->GetCheckAttempt() << "/" << host->GetMaxCheckAttempts() << " Active: " << host->IsActive() << std::endl;
+}
+#endif /* I2_DEBUG */
+
+BOOST_AUTO_TEST_SUITE(icinga_checkable_flapping)
+
+BOOST_AUTO_TEST_CASE(host_not_flapping)
+{
+#ifndef I2_DEBUG
+ BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
+#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);
+ host->SetActive(true);
+
+ // 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
+ BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
+#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);
+ host->SetActive(true);
+
+ 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
+ BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
+#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);
+ host->SetActive(true);
+
+ // Host otherwise is soft down
+ host->SetState(HostUp);
+ host->SetStateType(StateTypeHard);
+
+ Utility::SetTime(0);
+
+ // A few warning
+ 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
+ BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!");
+#else /* I2_DEBUG */
+ std::cout << "Simulating the documentation example...\n";
+
+ Host::Ptr host = new Host();
+ host->SetName("test");
+ host->SetEnableFlapping(true);
+ host->SetMaxCheckAttempts(5);
+ host->SetActive(true);
+
+ // 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()