From ae1ab5f86574db90aa229465dbed7d63ae526102 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Wed, 24 Aug 2016 11:11:20 +0200 Subject: [PATCH] Implement unit tests for state changes fixes #12530 --- lib/base/CMakeLists.txt | 2 +- lib/checker/CMakeLists.txt | 2 +- lib/cli/CMakeLists.txt | 2 +- lib/compat/CMakeLists.txt | 2 +- lib/config/CMakeLists.txt | 2 +- lib/db_ido/CMakeLists.txt | 2 +- lib/db_ido_mysql/CMakeLists.txt | 2 +- lib/db_ido_pgsql/CMakeLists.txt | 2 +- lib/demo/CMakeLists.txt | 2 +- lib/hello/CMakeLists.txt | 2 +- lib/icinga/CMakeLists.txt | 2 +- lib/livestatus/CMakeLists.txt | 2 +- lib/methods/CMakeLists.txt | 2 +- lib/notification/CMakeLists.txt | 2 +- lib/perfdata/CMakeLists.txt | 2 +- lib/remote/CMakeLists.txt | 2 +- test/CMakeLists.txt | 24 +++-- test/base-test.cpp | 6 ++ test/icinga-checkresult.cpp | 184 ++++++++++++++++++++++++++++++++ tools/mkunity/CMakeLists.txt | 4 +- 20 files changed, 221 insertions(+), 29 deletions(-) create mode 100644 test/icinga-checkresult.cpp diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt index ea0bb807f..fed2c5632 100644 --- a/lib/base/CMakeLists.txt +++ b/lib/base/CMakeLists.txt @@ -44,7 +44,7 @@ set(base_SOURCES set_property(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/application-version.cpp PROPERTY EXCLUDE_UNITY_BUILD TRUE) if(ICINGA2_UNITY_BUILD) - mkunity_target(base base_SOURCES) + mkunity_target(base base base_SOURCES) endif() add_library(base SHARED ${base_SOURCES}) diff --git a/lib/checker/CMakeLists.txt b/lib/checker/CMakeLists.txt index cdbf1a9a5..0ba4cf0a9 100644 --- a/lib/checker/CMakeLists.txt +++ b/lib/checker/CMakeLists.txt @@ -22,7 +22,7 @@ set(checker_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(checker checker_SOURCES) + mkunity_target(checker checker checker_SOURCES) endif() add_library(checker SHARED ${checker_SOURCES}) diff --git a/lib/cli/CMakeLists.txt b/lib/cli/CMakeLists.txt index 6a7f6d2b2..74156d5dc 100644 --- a/lib/cli/CMakeLists.txt +++ b/lib/cli/CMakeLists.txt @@ -32,7 +32,7 @@ set(cli_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(cli cli_SOURCES) + mkunity_target(cli cli cli_SOURCES) endif() add_library(cli SHARED ${cli_SOURCES}) diff --git a/lib/compat/CMakeLists.txt b/lib/compat/CMakeLists.txt index dbcb26da4..a3a3675da 100644 --- a/lib/compat/CMakeLists.txt +++ b/lib/compat/CMakeLists.txt @@ -27,7 +27,7 @@ set(compat_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(compat compat_SOURCES) + mkunity_target(compat compat compat_SOURCES) endif() add_library(compat SHARED ${compat_SOURCES}) diff --git a/lib/config/CMakeLists.txt b/lib/config/CMakeLists.txt index e31df13ea..c687ba214 100644 --- a/lib/config/CMakeLists.txt +++ b/lib/config/CMakeLists.txt @@ -41,7 +41,7 @@ set(config_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(config config_SOURCES) + mkunity_target(config config config_SOURCES) endif() add_library(config SHARED ${config_SOURCES}) diff --git a/lib/db_ido/CMakeLists.txt b/lib/db_ido/CMakeLists.txt index 31aef0d37..25d295262 100644 --- a/lib/db_ido/CMakeLists.txt +++ b/lib/db_ido/CMakeLists.txt @@ -29,7 +29,7 @@ set(db_ido_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(db_ido db_ido_SOURCES) + mkunity_target(db_ido db_ido db_ido_SOURCES) endif() add_library(db_ido SHARED ${db_ido_SOURCES}) diff --git a/lib/db_ido_mysql/CMakeLists.txt b/lib/db_ido_mysql/CMakeLists.txt index 254c5dc1f..4f45eb7d5 100644 --- a/lib/db_ido_mysql/CMakeLists.txt +++ b/lib/db_ido_mysql/CMakeLists.txt @@ -25,7 +25,7 @@ if(MYSQL_FOUND) ) if(ICINGA2_UNITY_BUILD) - mkunity_target(db_ido_mysql db_ido_mysql_SOURCES) + mkunity_target(db_ido_mysql db_ido_mysql db_ido_mysql_SOURCES) endif() add_library(db_ido_mysql SHARED ${db_ido_mysql_SOURCES}) diff --git a/lib/db_ido_pgsql/CMakeLists.txt b/lib/db_ido_pgsql/CMakeLists.txt index 40f47c43b..fd792b190 100644 --- a/lib/db_ido_pgsql/CMakeLists.txt +++ b/lib/db_ido_pgsql/CMakeLists.txt @@ -28,7 +28,7 @@ if(PostgreSQL_FOUND) ) if(ICINGA2_UNITY_BUILD) - mkunity_target(db_ido_pgsql db_ido_pgsql_SOURCES) + mkunity_target(db_ido_pgsql db_ido_pgsql db_ido_pgsql_SOURCES) endif() add_library(db_ido_pgsql SHARED ${db_ido_pgsql_SOURCES}) diff --git a/lib/demo/CMakeLists.txt b/lib/demo/CMakeLists.txt index 8a2666dc4..ab8533d39 100644 --- a/lib/demo/CMakeLists.txt +++ b/lib/demo/CMakeLists.txt @@ -22,7 +22,7 @@ set(demo_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(demo demo_SOURCES) + mkunity_target(demo demo demo_SOURCES) endif() add_library(demo SHARED ${demo_SOURCES}) diff --git a/lib/hello/CMakeLists.txt b/lib/hello/CMakeLists.txt index c5719dae9..fb40ad354 100644 --- a/lib/hello/CMakeLists.txt +++ b/lib/hello/CMakeLists.txt @@ -22,7 +22,7 @@ set(hello_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(hello hello_SOURCES) + mkunity_target(hello hello hello_SOURCES) endif() add_library(hello SHARED ${hello_SOURCES}) diff --git a/lib/icinga/CMakeLists.txt b/lib/icinga/CMakeLists.txt index 401792e0c..8ef9e97e3 100644 --- a/lib/icinga/CMakeLists.txt +++ b/lib/icinga/CMakeLists.txt @@ -54,7 +54,7 @@ set(icinga_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(icinga icinga_SOURCES) + mkunity_target(icinga icinga icinga_SOURCES) endif() add_library(icinga SHARED ${icinga_SOURCES}) diff --git a/lib/livestatus/CMakeLists.txt b/lib/livestatus/CMakeLists.txt index 202c125e6..40d56b928 100644 --- a/lib/livestatus/CMakeLists.txt +++ b/lib/livestatus/CMakeLists.txt @@ -32,7 +32,7 @@ set(livestatus_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(livestatus livestatus_SOURCES) + mkunity_target(livestatus livestatus livestatus_SOURCES) endif() add_library(livestatus SHARED ${livestatus_SOURCES}) diff --git a/lib/methods/CMakeLists.txt b/lib/methods/CMakeLists.txt index 6666ab474..e0c6d5e2d 100644 --- a/lib/methods/CMakeLists.txt +++ b/lib/methods/CMakeLists.txt @@ -31,7 +31,7 @@ set(methods_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(methods methods_SOURCES) + mkunity_target(methods methods methods_SOURCES) endif() add_library(methods SHARED ${methods_SOURCES}) diff --git a/lib/notification/CMakeLists.txt b/lib/notification/CMakeLists.txt index 22ebb482b..b94408317 100644 --- a/lib/notification/CMakeLists.txt +++ b/lib/notification/CMakeLists.txt @@ -22,7 +22,7 @@ set(notification_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(notification notification_SOURCES) + mkunity_target(notification notification notification_SOURCES) endif() add_library(notification SHARED ${notification_SOURCES}) diff --git a/lib/perfdata/CMakeLists.txt b/lib/perfdata/CMakeLists.txt index 98e554433..91cc5fa3c 100644 --- a/lib/perfdata/CMakeLists.txt +++ b/lib/perfdata/CMakeLists.txt @@ -26,7 +26,7 @@ set(perfdata_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(perfdata perfdata_SOURCES) + mkunity_target(perfdata perfdata perfdata_SOURCES) endif() add_library(perfdata SHARED ${perfdata_SOURCES}) diff --git a/lib/remote/CMakeLists.txt b/lib/remote/CMakeLists.txt index dd8a215cf..1d557a7a7 100644 --- a/lib/remote/CMakeLists.txt +++ b/lib/remote/CMakeLists.txt @@ -34,7 +34,7 @@ set(remote_SOURCES ) if(ICINGA2_UNITY_BUILD) - mkunity_target(remote remote_SOURCES) + mkunity_target(remote remote remote_SOURCES) endif() add_library(remote SHARED ${remote_SOURCES}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e68bdf581..df9bf3235 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -22,20 +22,12 @@ set(base_test_SOURCES base-json.cpp base-match.cpp base-netstring.cpp base-object.cpp base-serialize.cpp base-shellescape.cpp base-stacktrace.cpp base-stream.cpp base-string.cpp base-timer.cpp base-type.cpp - base-value.cpp config-ops.cpp icinga-macros.cpp - icinga-perfdata.cpp base-test.cpp - remote-base64.cpp remote-url.cpp + base-value.cpp config-ops.cpp icinga-checkresult.cpp icinga-macros.cpp + icinga-perfdata.cpp remote-base64.cpp remote-url.cpp ) -set(livestatus_test_SOURCES - livestatus.cpp - livestatus-test.cpp -) - -set_property(SOURCE test.cpp PROPERTY EXCLUDE_UNITY_BUILD TRUE) - if(ICINGA2_UNITY_BUILD) - mkunity_target(test base_test_SOURCES) + mkunity_target(base test base_test_SOURCES) endif() add_boost_test(base @@ -97,6 +89,8 @@ add_boost_test(base base_value/format config_ops/simple config_ops/advanced + icinga_checkresult/host + icinga_checkresult/service icinga_macros/simple icinga_perfdata/empty icinga_perfdata/simple @@ -116,6 +110,14 @@ add_boost_test(base ) if(ICINGA2_WITH_LIVESTATUS) + set(livestatus_test_SOURCES + livestatus.cpp + ) + + if(ICINGA2_UNITY_BUILD) + mkunity_target(livestatus test livestatus_test_SOURCES) + endif() + add_boost_test(livestatus SOURCES livestatus-test.cpp ${livestatus_test_SOURCES} LIBRARIES base config icinga cli livestatus diff --git a/test/base-test.cpp b/test/base-test.cpp index 77a5a7135..0ed1d89a3 100644 --- a/test/base-test.cpp +++ b/test/base-test.cpp @@ -20,6 +20,7 @@ #define BOOST_TEST_MAIN #define BOOST_TEST_MODULE icinga2_test +#include "icinga/icingaapplication.hpp" #include "base/application.hpp" #include "base/timer.hpp" #include @@ -28,9 +29,14 @@ using namespace icinga; struct InitLibBase { + IcingaApplication::Ptr appInst; + InitLibBase(void) { Application::InitializeBase(); + + appInst = new IcingaApplication(); + static_pointer_cast(appInst)->OnConfigLoaded(); } ~InitLibBase(void) diff --git a/test/icinga-checkresult.cpp b/test/icinga-checkresult.cpp new file mode 100644 index 000000000..db6494fbd --- /dev/null +++ b/test/icinga-checkresult.cpp @@ -0,0 +1,184 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2016 Icinga Development Team (https://www.icinga.org/) * + * * + * 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. * + ******************************************************************************/ + +#include "icinga/host.hpp" +#include + +using namespace icinga; + +BOOST_AUTO_TEST_SUITE(icinga_checkresult) + +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); + + return cr; +} + +static void NotificationHandler(const Checkable::Ptr& checkable, NotificationType type) +{ + std::cout << "Notification triggered: " << Notification::NotificationTypeToString(type) << std::endl; + + checkable->SetExtension("requested_notifications", true); + checkable->SetExtension("notification_type", type); +} + +static void CheckNotification(const Checkable::Ptr& checkable, bool expected, NotificationType type = NotificationRecovery) +{ + BOOST_CHECK((expected && checkable->GetExtension("requested_notifications").ToBool()) || (!expected && !checkable->GetExtension("requested_notifications").ToBool())); + + if (expected && checkable->GetExtension("requested_notifications").ToBool()) + BOOST_CHECK(checkable->GetExtension("notification_type") == type); + + checkable->SetExtension("requested_notifications", false); +} + +BOOST_AUTO_TEST_CASE(host) +{ + boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(boost::bind(&NotificationHandler, _1, _2)); + + Host::Ptr host = new Host(); + host->SetMaxCheckAttempts(3); + host->Activate(); + host->SetAuthority(true); + host->SetStateRaw(ServiceOK); + host->SetStateType(StateTypeHard); + + 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); + CheckNotification(host, false); + + std::cout << "First check result (unknown)" << std::endl; + host->ProcessCheckResult(MakeCheckResult(ServiceUnknown)); + BOOST_CHECK(host->GetState() == HostDown); + BOOST_CHECK(host->GetStateType() == StateTypeSoft); + BOOST_CHECK(host->GetCheckAttempt() == 1); + CheckNotification(host, false); + + std::cout << "Second check result (critical)" << std::endl; + host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + BOOST_CHECK(host->GetState() == HostDown); + BOOST_CHECK(host->GetStateType() == StateTypeSoft); + BOOST_CHECK(host->GetCheckAttempt() == 2); + CheckNotification(host, false); + + std::cout << "Third check result (critical)" << std::endl; + host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + BOOST_CHECK(host->GetState() == HostDown); + BOOST_CHECK(host->GetStateType() == StateTypeHard); + BOOST_CHECK(host->GetCheckAttempt() == 1); + CheckNotification(host, true, NotificationProblem); + + std::cout << "Fourth check result (ok)" << std::endl; + host->ProcessCheckResult(MakeCheckResult(ServiceOK)); + BOOST_CHECK(host->GetState() == HostUp); + BOOST_CHECK(host->GetStateType() == StateTypeHard); + BOOST_CHECK(host->GetCheckAttempt() == 1); + CheckNotification(host, true, NotificationRecovery); + + std::cout << "Fifth check result (critical)" << std::endl; + host->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + BOOST_CHECK(host->GetState() == HostDown); + BOOST_CHECK(host->GetStateType() == StateTypeSoft); + BOOST_CHECK(host->GetCheckAttempt() == 1); + CheckNotification(host, false); + + std::cout << "Sixth check result (ok)" << std::endl; + host->ProcessCheckResult(MakeCheckResult(ServiceOK)); + BOOST_CHECK(host->GetState() == HostUp); + BOOST_CHECK(host->GetStateType() == StateTypeHard); + BOOST_CHECK(host->GetCheckAttempt() == 1); + CheckNotification(host, false); + + c.disconnect(); +} + +BOOST_AUTO_TEST_CASE(service) +{ + boost::signals2::connection c = Checkable::OnNotificationsRequested.connect(boost::bind(&NotificationHandler, _1, _2)); + + Service::Ptr service = new Service(); + service->SetMaxCheckAttempts(3); + service->Activate(); + service->SetAuthority(true); + service->SetStateRaw(ServiceOK); + service->SetStateType(StateTypeHard); + + 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); + CheckNotification(service, false); + + std::cout << "First check result (unknown)" << std::endl; + service->ProcessCheckResult(MakeCheckResult(ServiceUnknown)); + BOOST_CHECK(service->GetState() == ServiceUnknown); + BOOST_CHECK(service->GetStateType() == StateTypeSoft); + BOOST_CHECK(service->GetCheckAttempt() == 1); + CheckNotification(service, false); + + std::cout << "Second check result (critical)" << std::endl; + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + BOOST_CHECK(service->GetState() == ServiceCritical); + BOOST_CHECK(service->GetStateType() == StateTypeSoft); + BOOST_CHECK(service->GetCheckAttempt() == 2); + CheckNotification(service, false); + + std::cout << "Third check result (critical)" << std::endl; + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + BOOST_CHECK(service->GetState() == ServiceCritical); + BOOST_CHECK(service->GetStateType() == StateTypeHard); + BOOST_CHECK(service->GetCheckAttempt() == 1); + CheckNotification(service, true, NotificationProblem); + + std::cout << "Fourth check result (ok)" << std::endl; + service->ProcessCheckResult(MakeCheckResult(ServiceOK)); + BOOST_CHECK(service->GetState() == ServiceOK); + BOOST_CHECK(service->GetStateType() == StateTypeHard); + BOOST_CHECK(service->GetCheckAttempt() == 1); + CheckNotification(service, true, NotificationRecovery); + + std::cout << "Fifth check result (critical)" << std::endl; + service->ProcessCheckResult(MakeCheckResult(ServiceCritical)); + BOOST_CHECK(service->GetState() == ServiceCritical); + BOOST_CHECK(service->GetStateType() == StateTypeSoft); + BOOST_CHECK(service->GetCheckAttempt() == 1); + CheckNotification(service, false); + + std::cout << "Sixth check result (ok)" << std::endl; + service->ProcessCheckResult(MakeCheckResult(ServiceOK)); + BOOST_CHECK(service->GetState() == ServiceOK); + BOOST_CHECK(service->GetStateType() == StateTypeHard); + BOOST_CHECK(service->GetCheckAttempt() == 1); + CheckNotification(service, false); + + c.disconnect(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tools/mkunity/CMakeLists.txt b/tools/mkunity/CMakeLists.txt index cfb9b1466..c35f02178 100644 --- a/tools/mkunity/CMakeLists.txt +++ b/tools/mkunity/CMakeLists.txt @@ -30,9 +30,9 @@ if(ICINGA2_UNITY_BUILD) FOLDER Bin ) - function(MKUNITY_TARGET Prefix UnityInputRef) + function(MKUNITY_TARGET Target Prefix UnityInputRef) set(UnityInput ${${UnityInputRef}}) - set(UnityOutput ${CMAKE_CURRENT_BINARY_DIR}/${Prefix}_unity.cpp) + set(UnityOutput ${CMAKE_CURRENT_BINARY_DIR}/${Target}_unity.cpp) set(RealSources "") set(UnitySources "") foreach(UnitySource ${UnityInput})