X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=test%2Ficinga-checkresult.cpp;h=7db7fffb3756b2c5e8618093dd25fdaa68a94c6c;hb=438da67209fd48a70a22aabafb2a6695c37aa9b4;hp=a128e9519c1d9b77e6bd37356a1db94619544c1c;hpb=9d68ae9f1f95db055ab50b1c2e7f18b240ce7554;p=icinga2 diff --git a/test/icinga-checkresult.cpp b/test/icinga-checkresult.cpp index a128e9519..7db7fffb3 100644 --- a/test/icinga-checkresult.cpp +++ b/test/icinga-checkresult.cpp @@ -1,21 +1,4 @@ -/****************************************************************************** - * Icinga 2 * - * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License * - * as published by the Free Software Foundation; either version 2 * - * of the License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the Free Software Foundation * - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * - ******************************************************************************/ +/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ #include "icinga/host.hpp" #include @@ -60,9 +43,10 @@ static void CheckNotification(const Checkable::Ptr& checkable, bool expected, No BOOST_AUTO_TEST_CASE(host_1attempt) { - boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(boost::bind(&NotificationHandler, _1, _2)); + boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2)); Host::Ptr host = new Host(); + host->SetActive(true); host->SetMaxCheckAttempts(1); host->Activate(); host->SetAuthority(true); @@ -108,9 +92,10 @@ BOOST_AUTO_TEST_CASE(host_1attempt) BOOST_AUTO_TEST_CASE(host_2attempts) { - boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(boost::bind(&NotificationHandler, _1, _2)); + boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2)); Host::Ptr host = new Host(); + host->SetActive(true); host->SetMaxCheckAttempts(2); host->Activate(); host->SetAuthority(true); @@ -163,9 +148,10 @@ BOOST_AUTO_TEST_CASE(host_2attempts) BOOST_AUTO_TEST_CASE(host_3attempts) { - boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(boost::bind(&NotificationHandler, _1, _2)); + boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2)); Host::Ptr host = new Host(); + host->SetActive(true); host->SetMaxCheckAttempts(3); host->Activate(); host->SetAuthority(true); @@ -225,9 +211,10 @@ BOOST_AUTO_TEST_CASE(host_3attempts) BOOST_AUTO_TEST_CASE(service_1attempt) { - boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(boost::bind(&NotificationHandler, _1, _2)); + boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2)); Service::Ptr service = new Service(); + service->SetActive(true); service->SetMaxCheckAttempts(1); service->Activate(); service->SetAuthority(true); @@ -273,9 +260,10 @@ BOOST_AUTO_TEST_CASE(service_1attempt) BOOST_AUTO_TEST_CASE(service_2attempts) { - boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(boost::bind(&NotificationHandler, _1, _2)); + boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2)); Service::Ptr service = new Service(); + service->SetActive(true); service->SetMaxCheckAttempts(2); service->Activate(); service->SetAuthority(true); @@ -328,9 +316,10 @@ BOOST_AUTO_TEST_CASE(service_2attempts) BOOST_AUTO_TEST_CASE(service_3attempts) { - boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(boost::bind(&NotificationHandler, _1, _2)); + boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2)); Service::Ptr service = new Service(); + service->SetActive(true); service->SetMaxCheckAttempts(3); service->Activate(); service->SetAuthority(true); @@ -393,13 +382,12 @@ 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)); + boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2)); - int softStateCount = 20; int timeStepInterval = 60; Host::Ptr host = new Host(); - host->SetMaxCheckAttempts(softStateCount); + host->SetActive(true); host->Activate(); host->SetAuthority(true); host->SetStateRaw(ServiceOK); @@ -418,18 +406,25 @@ BOOST_AUTO_TEST_CASE(host_flapping_notification) std::cout << "Inserting flapping check results" << std::endl; - for (int i = 0; i < softStateCount; i++) { + for (int i = 0; i < 10; 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); + CheckNotification(host, true, NotificationFlappingStart); + + std::cout << "Now calm down..." << std::endl; + + for (int i = 0; i < 20; i++) { + host->ProcessCheckResult(MakeCheckResult(ServiceOK)); + Utility::IncrementTime(timeStepInterval); + } + + CheckNotification(host, true, NotificationFlappingEnd); + c.disconnect(); @@ -441,13 +436,12 @@ 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)); + boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(std::bind(&NotificationHandler, _1, _2)); - int softStateCount = 20; int timeStepInterval = 60; - Host::Ptr service = new Host(); - service->SetMaxCheckAttempts(softStateCount); + Service::Ptr service = new Service(); + service->SetActive(true); service->Activate(); service->SetAuthority(true); service->SetStateRaw(ServiceOK); @@ -458,7 +452,7 @@ BOOST_AUTO_TEST_CASE(service_flapping_notification) Utility::SetTime(0); std::cout << "Before first check result (ok, hard)" << std::endl; - BOOST_CHECK(service->GetState() == HostUp); + BOOST_CHECK(service->GetState() == ServiceOK); BOOST_CHECK(service->GetStateType() == StateTypeHard); BOOST_CHECK(service->GetCheckAttempt() == 1); @@ -466,18 +460,281 @@ BOOST_AUTO_TEST_CASE(service_flapping_notification) std::cout << "Inserting flapping check results" << std::endl; - for (int i = 0; i < softStateCount; i++) { + for (int i = 0; i < 10; i++) { + ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical); + service->ProcessCheckResult(MakeCheckResult(state)); + Utility::IncrementTime(timeStepInterval); + } + + BOOST_CHECK(service->IsFlapping() == true); + + CheckNotification(service, true, NotificationFlappingStart); + + + + std::cout << "Now calm down..." << std::endl; + + for (int i = 0; i < 20; i++) { + service->ProcessCheckResult(MakeCheckResult(ServiceOK)); + Utility::IncrementTime(timeStepInterval); + } + + CheckNotification(service, true, NotificationFlappingEnd); + + c.disconnect(); + +#endif /* I2_DEBUG */ +} + +BOOST_AUTO_TEST_CASE(service_flapping_problem_notifications) +{ +#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(std::bind(&NotificationHandler, _1, _2)); + + int timeStepInterval = 60; + + Service::Ptr service = new Service(); + service->Activate(); + service->SetAuthority(true); + service->SetStateRaw(ServiceOK); + service->SetStateType(StateTypeHard); + service->SetEnableFlapping(true); + service->SetMaxCheckAttempts(3); + + /* Initialize start time */ + Utility::SetTime(0); + + std::cout << "Before first check result (ok, hard)" << std::endl; + BOOST_CHECK(service->GetState() == ServiceOK); + 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 < 10; 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); + CheckNotification(service, true, NotificationFlappingStart); + + //Insert enough check results to get into hard problem state but staying flapping + + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + + + BOOST_CHECK(service->IsFlapping() == true); + BOOST_CHECK(service->GetStateType() == StateTypeHard); + BOOST_CHECK(service->GetState() == ServiceCritical); + + CheckNotification(service, false, NotificationProblem); + + // Calm down + while (service->IsFlapping()) { + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + } + + CheckNotification(service, true, NotificationFlappingEnd); + + /* Intended behaviour is a Problem notification being sent as well, but there are is a Problem: + * We don't know whether the Object was Critical before we started flapping and sent out a Notification. + * A notification will not be sent, no matter how many criticals follow. + * + * service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + * CheckNotification(service, true, NotificationProblem); + * ^ This fails, no notification will be sent + * + * There is also a different issue, when we receive a OK check result, a Recovery Notification will be sent + * since the service went from hard critical into soft ok. Yet there is no fitting critical notification. + * This should not happen: + * + * service->ProcessCheckResult(MakeCheckResult(ServiceOK)); + * CheckNotification(service, false, NotificationRecovery); + * ^ This fails, recovery is sent + */ + + BOOST_CHECK(service->IsFlapping() == false); + BOOST_CHECK(service->GetStateType() == StateTypeHard); + BOOST_CHECK(service->GetState() == ServiceCritical); + + // Known failure, see #5713 + // CheckNotification(service, true, NotificationProblem); + + service->ProcessCheckResult(MakeCheckResult(ServiceOK)); + Utility::IncrementTime(timeStepInterval); + + // Known failure, see #5713 + // CheckNotification(service, true, NotificationRecovery); + + c.disconnect(); + +#endif /* I2_DEBUG */ +} + +BOOST_AUTO_TEST_CASE(service_flapping_ok_into_bad) +{ +#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(std::bind(&NotificationHandler, _1, _2)); + + int timeStepInterval = 60; + + Service::Ptr service = new Service(); + service->Activate(); + service->SetAuthority(true); + service->SetStateRaw(ServiceOK); + service->SetStateType(StateTypeHard); + service->SetEnableFlapping(true); + service->SetMaxCheckAttempts(3); + + /* Initialize start time */ + Utility::SetTime(0); + + std::cout << "Before first check result (ok, hard)" << std::endl; + BOOST_CHECK(service->GetState() == ServiceOK); + 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 < 10; i++) { + ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical); + service->ProcessCheckResult(MakeCheckResult(state)); + Utility::IncrementTime(timeStepInterval); + } + + BOOST_CHECK(service->IsFlapping() == true); + + CheckNotification(service, true, NotificationFlappingStart); + + //Insert enough check results to get into hard problem state but staying flapping + + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + + + BOOST_CHECK(service->IsFlapping() == true); + BOOST_CHECK(service->GetStateType() == StateTypeHard); + BOOST_CHECK(service->GetState() == ServiceCritical); + + CheckNotification(service, false, NotificationProblem); + + // Calm down + while (service->IsFlapping()) { + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + } + + CheckNotification(service, true, NotificationFlappingEnd); + + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + + BOOST_CHECK(service->IsFlapping() == false); + BOOST_CHECK(service->GetStateType() == StateTypeHard); + BOOST_CHECK(service->GetState() == ServiceCritical); + + // We expect a problem notification here + // Known failure, see #5713 + // CheckNotification(service, true, NotificationProblem); + + c.disconnect(); + +#endif /* I2_DEBUG */ +} +BOOST_AUTO_TEST_CASE(service_flapping_ok_over_bad_into_ok) +{ +#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(std::bind(&NotificationHandler, _1, _2)); + + int timeStepInterval = 60; + + Service::Ptr service = new Service(); + service->Activate(); + service->SetAuthority(true); + service->SetStateRaw(ServiceOK); + service->SetStateType(StateTypeHard); + service->SetEnableFlapping(true); + service->SetMaxCheckAttempts(3); + + /* Initialize start time */ + Utility::SetTime(0); + + std::cout << "Before first check result (ok, hard)" << std::endl; + BOOST_CHECK(service->GetState() == ServiceOK); + 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 < 10; i++) { + ServiceState state = (i % 2 == 0 ? ServiceOK : ServiceCritical); + service->ProcessCheckResult(MakeCheckResult(state)); + Utility::IncrementTime(timeStepInterval); + } + + BOOST_CHECK(service->IsFlapping() == true); + + CheckNotification(service, true, NotificationFlappingStart); + + //Insert enough check results to get into hard problem state but staying flapping + + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + + + BOOST_CHECK(service->IsFlapping() == true); + BOOST_CHECK(service->GetStateType() == StateTypeHard); + BOOST_CHECK(service->GetState() == ServiceCritical); + + CheckNotification(service, false, NotificationProblem); + + // Calm down + while (service->IsFlapping()) { + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + Utility::IncrementTime(timeStepInterval); + } + + CheckNotification(service, true, NotificationFlappingEnd); + + service->ProcessCheckResult(MakeCheckResult(ServiceOK)); + Utility::IncrementTime(timeStepInterval); + + BOOST_CHECK(service->IsFlapping() == false); + BOOST_CHECK(service->GetStateType() == StateTypeHard); + BOOST_CHECK(service->GetState() == ServiceOK); + + // There should be no recovery + // Known failure, see #5713 + // CheckNotification(service, false, NotificationRecovery); c.disconnect();