diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e3772886abd..dd9724f0bf0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,6 +2,59 @@ include(BoostTestTargets) +set(types_test_SOURCES + icingaapplication-fixture.cpp + base-type.cpp + ${base_OBJS} + $ + $ + $ + $ +) + +if(ICINGA2_WITH_CHECKER) + list(APPEND types_test_SOURCES $) +endif() + +if(ICINGA2_WITH_MYSQL) + list(APPEND types_test_SOURCES $ $) +endif() + +if(ICINGA2_WITH_PGSQL) + list(APPEND types_test_SOURCES $ $) +endif() + +if(ICINGA2_WITH_ICINGADB) + list(APPEND types_test_SOURCES $) +endif() + +if(ICINGA2_WITH_NOTIFICATION) + list(APPEND types_test_SOURCES $) +endif() + +if(ICINGA2_WITH_PERFDATA) + list(APPEND types_test_SOURCES $) +endif() + +if(ICINGA2_UNITY_BUILD) + mkunity_target(types test types_test_SOURCES) +endif() + +# In order to test the order of all Icinga 2 config type load dependencies, we need to link against all the libraries, +# but this results in boost signals e.g. in dbevents.cpp being triggered by icinga-checkresult.cpp test cases that +# only pass partially initialised objects. Therefore, the types test cases are decoupled from base and moved to a +# separate executable to not crash the base test cases. +add_boost_test(types + SOURCES test-runner.cpp ${types_test_SOURCES} + LIBRARIES ${base_DEPS} + TESTS + types/gettype + types/assign + types/byname + types/instantiate + types/sort_by_load_after +) + set(base_test_SOURCES icingaapplication-fixture.cpp base-array.cpp @@ -21,7 +74,6 @@ set(base_test_SOURCES base-string.cpp base-timer.cpp base-tlsutility.cpp - base-type.cpp base-utility.cpp base-value.cpp config-apply.cpp @@ -117,10 +169,6 @@ add_boost_test(base base_tlsutility/iscertuptodate_ok base_tlsutility/iscertuptodate_expiring base_tlsutility/iscertuptodate_old - base_type/gettype - base_type/assign - base_type/byname - base_type/instantiate base_utility/parse_version base_utility/compare_version base_utility/comparepasswords_works diff --git a/test/base-type.cpp b/test/base-type.cpp index 21bcf439d35..4a8d0deb4b7 100644 --- a/test/base-type.cpp +++ b/test/base-type.cpp @@ -5,11 +5,13 @@ #include "base/objectlock.hpp" #include "base/application.hpp" #include "base/type.hpp" +#include "icinga/host.hpp" +#include "icinga/service.hpp" #include using namespace icinga; -BOOST_AUTO_TEST_SUITE(base_type) +BOOST_AUTO_TEST_SUITE(types) BOOST_AUTO_TEST_CASE(gettype) { @@ -44,4 +46,33 @@ BOOST_AUTO_TEST_CASE(instantiate) BOOST_CHECK(p); } +BOOST_AUTO_TEST_CASE(sort_by_load_after) +{ + int totalDependencies{0}; + std::unordered_set previousTypes; + for (auto type : Type::GetConfigTypesSortedByLoadDependencies()) { + BOOST_CHECK_EQUAL(true, ConfigObject::TypeInstance->IsAssignableFrom(type)); + + totalDependencies += type->GetLoadDependencies().size(); + for (Type* dependency : type->GetLoadDependencies()) { + // Note, Type::GetConfigTypesSortedByLoadDependencies() does not detect any cyclic load dependencies, + // instead, it relies on this test case to fail. + BOOST_CHECK_MESSAGE(previousTypes.find(dependency) != previousTypes.end(), "type '" << type->GetName() + << "' depends on '"<< dependency->GetName() << "' type, but it's not loaded before"); + } + + previousTypes.emplace(type.get()); + } + + // The magic number 12 is the sum of host,service,comment,downtime and endpoint load_after dependencies. + BOOST_CHECK_MESSAGE(totalDependencies >= 12, "total size of load dependency must be at least 12"); + BOOST_CHECK_MESSAGE(previousTypes.find(Host::TypeInstance.get()) != previousTypes.end(), "Host type should be in the list"); + BOOST_CHECK_MESSAGE(previousTypes.find(Service::TypeInstance.get()) != previousTypes.end(), "Service type should be in the list"); + BOOST_CHECK_MESSAGE(previousTypes.find(Downtime::TypeInstance.get()) != previousTypes.end(), "Downtime type should be in the list"); + BOOST_CHECK_MESSAGE(previousTypes.find(Comment::TypeInstance.get()) != previousTypes.end(), "Comment type should be in the list"); + BOOST_CHECK_MESSAGE(previousTypes.find(Notification::TypeInstance.get()) != previousTypes.end(), "Notification type should be in the list"); + BOOST_CHECK_MESSAGE(previousTypes.find(Zone::TypeInstance.get()) != previousTypes.end(), "Zone type should be in the list"); + BOOST_CHECK_MESSAGE(previousTypes.find(Endpoint::TypeInstance.get()) != previousTypes.end(), "Endpoint type should be in the list"); +} + BOOST_AUTO_TEST_SUITE_END()