From: Michael Friedrich Date: Thu, 10 Nov 2016 13:02:02 +0000 (+0100) Subject: Fix Flapping{Start,End} notifications in SOFT states or downtimes X-Git-Tag: v2.6.0~66 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7e0c48643b3f6985ed584648dfab1ec485678bc2;p=icinga2 Fix Flapping{Start,End} notifications in SOFT states or downtimes fixes #12560 fixes #12892 --- diff --git a/lib/icinga/checkable-check.cpp b/lib/icinga/checkable-check.cpp index 372829b4c..7741e2d81 100644 --- a/lib/icinga/checkable-check.cpp +++ b/lib/icinga/checkable-check.cpp @@ -368,7 +368,8 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig ExecuteEventHandler(); /* Flapping start/end notifications */ - if (!was_flapping && is_flapping) { + if (send_notification && !was_flapping && is_flapping) { + /* FlappingStart notifications happen on state changes, not in downtimes */ if (!IsPaused()) OnNotificationsRequested(this, NotificationFlappingStart, cr, "", "", MessageOrigin::Ptr()); @@ -376,7 +377,8 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig << "Flapping: Checkable " << GetName() << " started flapping (" << GetFlappingThreshold() << "% < " << GetFlappingCurrent() << "%)."; NotifyFlapping(origin); - } else if (was_flapping && !is_flapping) { + } else if (!in_downtime && was_flapping && !is_flapping) { + /* FlappingEnd notifications are independent from state changes, must not happen in downtine */ if (!IsPaused()) OnNotificationsRequested(this, NotificationFlappingEnd, cr, "", "", MessageOrigin::Ptr()); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e577d0358..5a36e892d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -97,6 +97,8 @@ add_boost_test(base icinga_checkresult/service_1attempt icinga_checkresult/service_2attempts icinga_checkresult/service_3attempts + icinga_checkresult/host_flapping_notification + icinga_checkresult/service_flapping_notification icinga_macros/simple icinga_perfdata/empty icinga_perfdata/simple diff --git a/test/icinga-checkresult.cpp b/test/icinga-checkresult.cpp index 703602d99..e3bd78b50 100644 --- a/test/icinga-checkresult.cpp +++ b/test/icinga-checkresult.cpp @@ -387,4 +387,99 @@ BOOST_AUTO_TEST_CASE(service_3attempts) c.disconnect(); } +BOOST_AUTO_TEST_CASE(host_flapping_notification) +{ +#ifndef I2_DEBUG + BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!"); +#else /* I2_DEBUG */ + boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(boost::bind(&NotificationHandler, _1, _2)); + + int softStateCount = 20; + int timeStepInterval = 60; + + Host::Ptr host = new Host(); + host->SetMaxCheckAttempts(softStateCount); + host->Activate(); + host->SetAuthority(true); + host->SetStateRaw(ServiceOK); + host->SetStateType(StateTypeHard); + host->SetEnableFlapping(true); + + /* Initialize start time */ + Utility::SetTime(0); + + std::cout << "Before first check result (ok, hard)" << std::endl; + BOOST_CHECK(host->GetState() == HostUp); + BOOST_CHECK(host->GetStateType() == StateTypeHard); + BOOST_CHECK(host->GetCheckAttempt() == 1); + + Utility::IncrementTime(timeStepInterval); + + std::cout << "Inserting flapping check results" << std::endl; + + for (int i = 0; i < softStateCount; i++) { + ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical); + host->ProcessCheckResult(MakeCheckResult(state)); + Utility::IncrementTime(timeStepInterval); + } + + std::cout << "Checking host state (must be flapping in SOFT state)" << std::endl; + BOOST_CHECK(host->GetStateType() == StateTypeSoft); + BOOST_CHECK(host->IsFlapping() == true); + + std::cout << "No FlappingStart notification type must have been triggered in a SOFT state" << std::endl; + CheckNotification(host, false, NotificationFlappingStart); + + c.disconnect(); + +#endif /* I2_DEBUG */ +} + +BOOST_AUTO_TEST_CASE(service_flapping_notification) +{ +#ifndef I2_DEBUG + BOOST_WARN_MESSAGE(false, "This test can only be run in a debug build!"); +#else /* I2_DEBUG */ + boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(boost::bind(&NotificationHandler, _1, _2)); + + int softStateCount = 20; + int timeStepInterval = 60; + + Host::Ptr service = new Host(); + service->SetMaxCheckAttempts(softStateCount); + service->Activate(); + service->SetAuthority(true); + service->SetStateRaw(ServiceOK); + service->SetStateType(StateTypeHard); + service->SetEnableFlapping(true); + + /* Initialize start time */ + Utility::SetTime(0); + + std::cout << "Before first check result (ok, hard)" << std::endl; + BOOST_CHECK(service->GetState() == HostUp); + BOOST_CHECK(service->GetStateType() == StateTypeHard); + BOOST_CHECK(service->GetCheckAttempt() == 1); + + Utility::IncrementTime(timeStepInterval); + + std::cout << "Inserting flapping check results" << std::endl; + + for (int i = 0; i < softStateCount; i++) { + ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical); + service->ProcessCheckResult(MakeCheckResult(state)); + Utility::IncrementTime(timeStepInterval); + } + + std::cout << "Checking service state (must be flapping in SOFT state)" << std::endl; + BOOST_CHECK(service->GetStateType() == StateTypeSoft); + BOOST_CHECK(service->IsFlapping() == true); + + std::cout << "No FlappingStart notification type must have been triggered in a SOFT state" << std::endl; + CheckNotification(service, false, NotificationFlappingStart); + + c.disconnect(); + +#endif /* I2_DEBUG */ +} BOOST_AUTO_TEST_SUITE_END()