summaryrefslogtreecommitdiffstats
path: root/test/config
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 11:32:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 11:32:39 +0000
commit56ae875861ab260b80a030f50c4aff9f9dc8fff0 (patch)
tree531412110fc901a5918c7f7442202804a83cada9 /test/config
parentInitial commit. (diff)
downloadicinga2-56ae875861ab260b80a030f50c4aff9f9dc8fff0.tar.xz
icinga2-56ae875861ab260b80a030f50c4aff9f9dc8fff0.zip
Adding upstream version 2.14.2.upstream/2.14.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--test/config-apply.cpp251
-rw-r--r--test/config-ops.cpp246
-rw-r--r--test/config/2742.conf21
-rw-r--r--test/config/5872.conf72
-rw-r--r--test/config/5912.conf.dis14
-rw-r--r--test/config/5926.conf23
-rw-r--r--test/config/5927.conf44
-rw-r--r--test/config/5980.conf58
-rw-r--r--test/config/6105.conf25
-rw-r--r--test/config/6479.conf44
-rw-r--r--test/config/6608.conf16
-rw-r--r--test/config/6968.conf27
-rw-r--r--test/config/7560.conf41
-rw-r--r--test/config/7683.conf27
-rw-r--r--test/config/8063.conf73
-rw-r--r--test/config/README2
-rw-r--r--test/config/templates.conf80
17 files changed, 1064 insertions, 0 deletions
diff --git a/test/config-apply.cpp b/test/config-apply.cpp
new file mode 100644
index 0000000..c207ddd
--- /dev/null
+++ b/test/config-apply.cpp
@@ -0,0 +1,251 @@
+/* Icinga 2 | (c) 2023 Icinga GmbH | GPLv2+ */
+
+#include "config/applyrule.hpp"
+#include "config/configcompiler.hpp"
+#include <BoostTestTargetConfig.h>
+
+using namespace icinga;
+
+static Expression* RequireActualExpression(const std::unique_ptr<Expression>& compiledExpression)
+{
+ BOOST_REQUIRE_NE(compiledExpression.get(), nullptr);
+
+ auto dict (dynamic_cast<DictExpression*>(compiledExpression.get()));
+ BOOST_REQUIRE_NE(dict, nullptr);
+
+ auto& subex (dict->GetExpressions());
+ BOOST_REQUIRE_EQUAL(subex.size(), 1u);
+
+ auto sub0 (subex.at(0).get());
+ BOOST_REQUIRE_NE(sub0, nullptr);
+
+ return sub0;
+}
+
+template<>
+struct boost::test_tools::tt_detail::print_log_value<std::pair<String, String>>
+{
+ inline void operator()(std::ostream& os, const std::pair<String, String>& hs)
+ {
+ os << hs.first << "!" << hs.second;
+ }
+};
+
+static void GetTargetHostsHelper(
+ const String& filter, const Dictionary::Ptr& constants, bool targeted, const std::vector<String>& hosts = {}
+)
+{
+ auto compiled (ConfigCompiler::CompileText("<test>", filter));
+ auto expr (RequireActualExpression(compiled));
+ std::vector<const String*> actualHosts;
+
+ BOOST_CHECK_EQUAL(ApplyRule::GetTargetHosts(expr, actualHosts, constants), targeted);
+
+ if (targeted) {
+ std::vector<String> actualHostNames;
+
+ actualHostNames.reserve(actualHosts.size());
+
+ for (auto h : actualHosts) {
+ actualHostNames.emplace_back(*h);
+ }
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(actualHostNames.begin(), actualHostNames.end(), hosts.begin(), hosts.end());
+ }
+}
+
+static void GetTargetServicesHelper(
+ const String& filter, const Dictionary::Ptr& constants, bool targeted, const std::vector<std::pair<String, String>>& services = {}
+)
+{
+ auto compiled (ConfigCompiler::CompileText("<test>", filter));
+ auto expr (RequireActualExpression(compiled));
+ std::vector<std::pair<const String*, const String*>> actualServices;
+
+ BOOST_CHECK_EQUAL(ApplyRule::GetTargetServices(expr, actualServices, constants), targeted);
+
+ if (targeted) {
+ std::vector<std::pair<String, String>> actualServiceNames;
+
+ actualServiceNames.reserve(actualServices.size());
+
+ for (auto s : actualServices) {
+ actualServiceNames.emplace_back(*s.first, *s.second);
+ }
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(actualServiceNames.begin(), actualServiceNames.end(), services.begin(), services.end());
+ }
+}
+
+BOOST_AUTO_TEST_SUITE(config_apply)
+
+BOOST_AUTO_TEST_CASE(gettargethosts_literal)
+{
+ GetTargetHostsHelper("host.name == \"foo\"", nullptr, true, {"foo"});
+}
+
+BOOST_AUTO_TEST_CASE(gettargethosts_const)
+{
+ GetTargetHostsHelper("host.name == x", new Dictionary({{"x", "foo"}}), true, {"foo"});
+}
+
+BOOST_AUTO_TEST_CASE(gettargethosts_swapped)
+{
+ GetTargetHostsHelper("\"foo\" == host.name", nullptr, true, {"foo"});
+}
+
+BOOST_AUTO_TEST_CASE(gettargethosts_two)
+{
+ GetTargetHostsHelper("host.name == \"foo\" || host.name == \"bar\"", nullptr, true, {"foo", "bar"});
+}
+
+BOOST_AUTO_TEST_CASE(gettargethosts_three)
+{
+ GetTargetHostsHelper(
+ "host.name == \"foo\" || host.name == \"bar\" || host.name == \"foobar\"",
+ nullptr, true, {"foo", "bar", "foobar"}
+ );
+}
+
+BOOST_AUTO_TEST_CASE(gettargethosts_mixed)
+{
+ GetTargetHostsHelper("host.name == x || \"bar\" == host.name", new Dictionary({{"x", "foo"}}), true, {"foo", "bar"});
+}
+
+BOOST_AUTO_TEST_CASE(gettargethosts_redundant)
+{
+ GetTargetHostsHelper("host.name == \"foo\" && 1", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargethosts_badconst)
+{
+ GetTargetHostsHelper("host.name == NodeName", new Dictionary({{"x", "foo"}}), false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargethosts_notliteral)
+{
+ GetTargetHostsHelper("host.name == \"foo\" + \"bar\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargethosts_wrongop)
+{
+ GetTargetHostsHelper("host.name != \"foo\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargethosts_wrongattr)
+{
+ GetTargetHostsHelper("host.__name == \"foo\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargethosts_wrongvar)
+{
+ GetTargetHostsHelper("service.name == \"foo\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargethosts_noindexer)
+{
+ GetTargetHostsHelper("name == \"foo\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_literal)
+{
+ GetTargetServicesHelper("host.name == \"foo\" && service.name == \"bar\"", nullptr, true, {{"foo", "bar"}});
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_const)
+{
+ GetTargetServicesHelper("host.name == x && service.name == y", new Dictionary({{"x", "foo"}, {"y", "bar"}}), true, {{"foo", "bar"}});
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_swapped_outer)
+{
+ GetTargetServicesHelper("service.name == \"bar\" && host.name == \"foo\"", nullptr, true, {{"foo", "bar"}});
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_swapped_inner)
+{
+ GetTargetServicesHelper("\"foo\" == host.name && \"bar\" == service.name", nullptr, true, {{"foo", "bar"}});
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_two)
+{
+ GetTargetServicesHelper(
+ "host.name == \"foo\" && service.name == \"bar\" || host.name == \"oof\" && service.name == \"rab\"",
+ nullptr, true, {{"foo", "bar"}, {"oof", "rab"}}
+ );
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_three)
+{
+ GetTargetServicesHelper(
+ "host.name == \"foo\" && service.name == \"bar\" || host.name == \"oof\" && service.name == \"rab\" || host.name == \"ofo\" && service.name == \"rba\"",
+ nullptr, true, {{"foo", "bar"}, {"oof", "rab"}, {"ofo", "rba"}}
+ );
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_mixed)
+{
+ GetTargetServicesHelper("\"bar\" == service.name && x == host.name", new Dictionary({{"x", "foo"}}), true, {{"foo", "bar"}});
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_redundant)
+{
+ GetTargetServicesHelper("host.name == \"foo\" && service.name == \"bar\" && 1", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_badconst)
+{
+ GetTargetServicesHelper("host.name == NodeName && service.name == \"bar\"", new Dictionary({{"x", "foo"}}), false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_notliteral)
+{
+ GetTargetServicesHelper("host.name == \"foo\" && service.name == \"b\" + \"ar\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_wrongop_outer)
+{
+ GetTargetServicesHelper("host.name == \"foo\" & service.name == \"bar\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_wrongop_host)
+{
+ GetTargetServicesHelper("host.name != \"foo\" && service.name == \"bar\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_wrongop_service)
+{
+ GetTargetServicesHelper("host.name == \"foo\" && service.name != \"bar\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_wrongattr_host)
+{
+ GetTargetServicesHelper("host.__name == \"foo\" && service.name == \"bar\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_wrongattr_service)
+{
+ GetTargetServicesHelper("host.name == \"foo\" && service.__name == \"bar\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_wrongvar_host)
+{
+ GetTargetServicesHelper("horst.name == \"foo\" && service.name == \"bar\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_wrongvar_service)
+{
+ GetTargetServicesHelper("host.name == \"foo\" && sehrvice.name == \"bar\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_noindexer_host)
+{
+ GetTargetServicesHelper("name == \"foo\" && service.name == \"bar\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_CASE(gettargetservices_noindexer_service)
+{
+ GetTargetServicesHelper("host.name == \"foo\" && name == \"bar\"", nullptr, false);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/config-ops.cpp b/test/config-ops.cpp
new file mode 100644
index 0000000..dfbef25
--- /dev/null
+++ b/test/config-ops.cpp
@@ -0,0 +1,246 @@
+/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
+
+#include "config/configcompiler.hpp"
+#include "base/exception.hpp"
+#include <BoostTestTargetConfig.h>
+
+using namespace icinga;
+
+BOOST_AUTO_TEST_SUITE(config_ops)
+
+BOOST_AUTO_TEST_CASE(simple)
+{
+ ScriptFrame frame(true);
+ std::unique_ptr<Expression> expr;
+ Dictionary::Ptr dict;
+
+ expr = ConfigCompiler::CompileText("<test>", "");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == Empty);
+
+ expr = ConfigCompiler::CompileText("<test>", "\n3");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
+
+ expr = ConfigCompiler::CompileText("<test>", "{ 3\n\n5 }");
+ BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
+
+ expr = ConfigCompiler::CompileText("<test>", "1 + 3");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 4);
+
+ expr = ConfigCompiler::CompileText("<test>", "3 - 1");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 2);
+
+ expr = ConfigCompiler::CompileText("<test>", "5m * 10");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3000);
+
+ expr = ConfigCompiler::CompileText("<test>", "5m / 5");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 60);
+
+ expr = ConfigCompiler::CompileText("<test>", "7 & 3");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
+
+ expr = ConfigCompiler::CompileText("<test>", "2 | 3");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
+
+ expr = ConfigCompiler::CompileText("<test>", "true && false");
+ BOOST_CHECK(!expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "true || false");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "3 < 5");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "3 > 5");
+ BOOST_CHECK(!expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "3 <= 3");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "3 >= 3");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "2 + 3 * 4");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 14);
+
+ expr = ConfigCompiler::CompileText("<test>", "(2 + 3) * 4");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 20);
+
+ expr = ConfigCompiler::CompileText("<test>", "2 * - 3");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == -6);
+
+ expr = ConfigCompiler::CompileText("<test>", "-(2 + 3)");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == -5);
+
+ expr = ConfigCompiler::CompileText("<test>", "- 2 * 2 - 2 * 3 - 4 * - 5");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 10);
+
+ expr = ConfigCompiler::CompileText("<test>", "!0 == true");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "~0");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == (double)~(long)0);
+
+ expr = ConfigCompiler::CompileText("<test>", "4 << 8");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 1024);
+
+ expr = ConfigCompiler::CompileText("<test>", "1024 >> 4");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 64);
+
+ expr = ConfigCompiler::CompileText("<test>", "2 << 3 << 4");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 256);
+
+ expr = ConfigCompiler::CompileText("<test>", "256 >> 4 >> 3");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 2);
+
+ expr = ConfigCompiler::CompileText("<test>", R"("hello" == "hello")");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", R"("hello" != "hello")");
+ BOOST_CHECK(!expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", R"("foo" in [ "foo", "bar" ])");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", R"("foo" in [ "bar", "baz" ])");
+ BOOST_CHECK(!expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "\"foo\" in null");
+ BOOST_CHECK(!expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", R"("foo" in "bar")");
+ BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
+
+ expr = ConfigCompiler::CompileText("<test>", R"("foo" !in [ "bar", "baz" ])");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", R"("foo" !in [ "foo", "bar" ])");
+ BOOST_CHECK(!expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "\"foo\" !in null");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", R"("foo" !in "bar")");
+ BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
+
+ expr = ConfigCompiler::CompileText("<test>", "{ a += 3 }");
+ dict = expr->Evaluate(frame).GetValue();
+ BOOST_CHECK(dict->GetLength() == 1);
+ BOOST_CHECK(dict->Get("a") == 3);
+
+ expr = ConfigCompiler::CompileText("<test>", "test");
+ BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
+
+ expr = ConfigCompiler::CompileText("<test>", "null + 3");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
+
+ expr = ConfigCompiler::CompileText("<test>", "3 + null");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
+
+ expr = ConfigCompiler::CompileText("<test>", "\"test\" + 3");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == "test3");
+
+ expr = ConfigCompiler::CompileText("<test>", R"("\"te\\st")");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == "\"te\\st");
+
+ expr = ConfigCompiler::CompileText("<test>", R"("\'test")");
+ BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
+
+ expr = ConfigCompiler::CompileText("<test>", "({ a = 3\nb = 3 })");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue().IsObjectType<Dictionary>());
+}
+
+BOOST_AUTO_TEST_CASE(advanced)
+{
+ ScriptFrame frame(true);
+ std::unique_ptr<Expression> expr;
+ Function::Ptr func;
+
+ expr = ConfigCompiler::CompileText("<test>", R"(regex("^Hello", "Hello World"))");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "__boost_test()");
+ BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
+
+ Object::Ptr self = new Object();
+ ScriptFrame frame2(true, self);
+ expr = ConfigCompiler::CompileText("<test>", "this");
+ BOOST_CHECK(expr->Evaluate(frame2).GetValue() == Value(self));
+
+ expr = ConfigCompiler::CompileText("<test>", "var v = 7; v");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "{ a = 3 }.a");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
+
+ expr = ConfigCompiler::CompileText("<test>", "[ 2, 3 ][1]");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
+
+ expr = ConfigCompiler::CompileText("<test>", "var v = { a = 3}; v.a");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
+
+ expr = ConfigCompiler::CompileText("<test>", "a = 3 b = 3");
+ BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
+
+ expr = ConfigCompiler::CompileText("<test>", "function() { 3 }()");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
+
+ expr = ConfigCompiler::CompileText("<test>", "function() { return 3, 5 }()");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
+
+ expr = ConfigCompiler::CompileText("<test>", "typeof([]) == Array");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "typeof({}) == Dictionary");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "typeof(3) == Number");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "typeof(\"test\") == String");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "(7 | 8) == 15");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "(7 ^ 8) == 15");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "(7 & 15) == 7");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "7 in [7] == true");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "7 !in [7] == false");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "(7 | 8) > 14");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "(7 ^ 8) > 14");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "(7 & 15) > 6");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue());
+
+ expr = ConfigCompiler::CompileText("<test>", "\"a\" = 3");
+ BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
+
+ expr = ConfigCompiler::CompileText("<test>", "3 = 3");
+ BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
+
+ expr = ConfigCompiler::CompileText("<test>", "var e; e");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue().IsEmpty());
+
+ expr = ConfigCompiler::CompileText("<test>", "var e = 3; e");
+ BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
+
+ expr = ConfigCompiler::CompileText("<test>", "Array.x");
+ BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
+
+ expr = ConfigCompiler::CompileText("<test>", "{{ 3 }}");
+ func = expr->Evaluate(frame).GetValue();
+ BOOST_CHECK(func->Invoke() == 3);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/config/2742.conf b/test/config/2742.conf
new file mode 100644
index 0000000..555e714
--- /dev/null
+++ b/test/config/2742.conf
@@ -0,0 +1,21 @@
+
+object CheckCommand "2742-macro-command" {
+ command = "echo UPTIME: $icinga.uptime$ SERVICES warn: $icinga.num_services_warning$ crit: $icinga.num_services_critical$ unknown: $icinga.num_services_unknown$ ackd: $icinga.num_services_acknowledged$ HOST: down: $icinga.num_hosts_down$ unreachable: $icinga.num_hosts_unreachable$"
+}
+
+object HostGroup "2742-windows-servers"{
+ display_name = "2742-windows-servers"
+ assign where match("2742-*", host.name)
+}
+
+apply Service "2742-macro-test" {
+ import "test-generic-service"
+ check_command = "2742-macro-command"
+ assign where match("2742-*", host.name)
+}
+
+object Host "2742-server" {
+ import "test-generic-host"
+ address = "192.168.1.5",
+}
+
diff --git a/test/config/5872.conf b/test/config/5872.conf
new file mode 100644
index 0000000..0405516
--- /dev/null
+++ b/test/config/5872.conf
@@ -0,0 +1,72 @@
+
+object HostGroup "5872-windows-servers"{
+ display_name = "5872-windows-servers"
+ assign where match("5872-*", host.name)
+}
+
+apply Service "5872-ping4" {
+ import "test-generic-service"
+ check_command = "ping4"
+ assign where match("5872-*", host.name)
+}
+
+object Host "5872-server" {
+ import "test-generic-host"
+ address = "192.168.1.5",
+}
+
+object Host "5872-pc" {
+ import "test-generic-host"
+ address = "192.168.1.101",
+}
+
+object Host "5872-router" {
+ import "test-generic-host"
+ address = "192.168.1.1",
+}
+
+object Host "5872-switch" {
+ import "test-generic-host"
+ address = "192.168.1.2",
+}
+
+apply Dependency "5872-host-switch" to Host {
+ parent_host_name = "5872-router"
+ disable_checks = true
+ assign where host.name == "5872-switch"
+}
+
+apply Dependency "5872-host-pc" to Host {
+ parent_host_name = "5872-switch"
+ disable_checks = true
+ assign where host.name == "5872-pc"
+}
+
+apply Dependency "5872-host-server" to Host {
+ parent_host_name = "5872-switch"
+ disable_checks = true
+ assign where host.name == "5872-server"
+}
+
+apply Dependency "5872-service-switch" to Service {
+ parent_host_name = "5872-router"
+ parent_service_name = "5872-ping4"
+ disable_checks = true
+ assign where host.name == "5872-switch"
+}
+
+apply Dependency "5872-service-pc" to Service {
+ parent_host_name = "5872-switch"
+ parent_service_name = "5872-ping4"
+ disable_checks = true
+ assign where host.name == "5872-pc"
+}
+
+apply Dependency "5872-service-server" to Service {
+ parent_host_name = "5872-switch"
+ parent_service_name = "5872-ping4"
+ states = [ Warning, Critical ]
+ disable_checks = true
+ assign where host.name == "5872-server"
+}
+
diff --git a/test/config/5912.conf.dis b/test/config/5912.conf.dis
new file mode 100644
index 0000000..0366b06
--- /dev/null
+++ b/test/config/5912.conf.dis
@@ -0,0 +1,14 @@
+
+apply Service "5912-ping4" {
+ import "test-generic-service"
+ check_command = "ping4"
+ host_name = "foo"
+ service_name = "bar"
+ assign where match("5912-*", host.name)
+}
+
+object Host "5912-server" {
+ import "test-generic-host"
+ address = "192.168.1.5",
+}
+
diff --git a/test/config/5926.conf b/test/config/5926.conf
new file mode 100644
index 0000000..e4060a6
--- /dev/null
+++ b/test/config/5926.conf
@@ -0,0 +1,23 @@
+
+
+object CheckCommand "5926-macro-test" {
+ command = "echo \"address: $address$ address_service: $service.vars.address$ foo: $foo$ keks: $keks$ god: $god$\""
+ //command = "echo \"address: $address$ address_service: $service.vars.address$\""
+}
+
+object Host "5926-macro-test-host" {
+ import "test-generic-host"
+ check_command = "5926-macro-test"
+ address = "1.2.3.4"
+ vars.god = "father"
+}
+
+apply Service "5926-macro-test-service" {
+ import "test-generic-service"
+ check_command = "5926-macro-test"
+ vars.address = "5.6.7.8"
+ vars.foo = "bar"
+ vars.keks = "schaschlik"
+
+ assign where host.name == "5926-macro-test-host"
+}
diff --git a/test/config/5927.conf b/test/config/5927.conf
new file mode 100644
index 0000000..b7041b6
--- /dev/null
+++ b/test/config/5927.conf
@@ -0,0 +1,44 @@
+
+object EventCommand "5927-handle" {
+ command = "echo \"event handler triggered.\""
+}
+
+object NotificationCommand "5927-notification" {
+ command = "echo \"notification triggered.\""
+}
+
+object HostGroup "5927-bar" {
+ assign where match("5927-keks*", host.name)
+}
+
+object Host "5927-keks" {
+ import "test-generic-host"
+ event_command = "5927-handle"
+ address = "1.2.3.4"
+}
+
+apply Service "5927-foo" {
+ import "test-generic-service"
+ check_command = "ping4"
+ event_command = "5927-handle"
+ assign where "5927-bar" in host.groups
+}
+
+apply Notification "5927-host-notification" to Host {
+ import "test-mail-host-notification"
+ command = "5927-notification"
+ assign where "5927-bar" in host.groups
+}
+
+apply Notification "5927-service-notification" to Service {
+ import "test-mail-service-notification"
+ command = "5927-notification"
+ assign where "5927-bar" in host.groups
+}
+
+object ServiceGroup "5927-bar" {
+ assign where service.name == "5927-foo"
+}
+
+
+
diff --git a/test/config/5980.conf b/test/config/5980.conf
new file mode 100644
index 0000000..494b5bd
--- /dev/null
+++ b/test/config/5980.conf
@@ -0,0 +1,58 @@
+
+
+object Host "5980-host" {
+ import "test-generic-host"
+ address = "127.0.0.1"
+}
+
+object Service "5980-service1" {
+ import "test-generic-service"
+ host_name = "5980-host"
+ check_command = "dummy"
+}
+
+object Service "5980-service2" {
+ import "test-generic-service"
+ host_name = "5980-host"
+ check_command = "dummy"
+}
+
+
+template ScheduledDowntime "5980-test-downtime" {
+ author = "icingaadmin"
+ comment = "Scheduled downtime for tests"
+
+ ranges = {
+ monday = "02:00-03:00"
+ tuesday = "02:00-03:00"
+ wednesday = "02:00-03:00"
+ thursday = "02:00-03:00"
+ friday = "02:00-03:00"
+ saturday = "02:00-03:00"
+ sunday = "02:00-03:00"
+ }
+}
+
+
+apply ScheduledDowntime "5980-test-service-downtime" to Host {
+ import "5980-test-downtime"
+ comment = "Scheduled host downtime for tests"
+
+ ranges = {
+ tuesday = "09:37-09:40"
+ }
+
+ assign where host.name == "5980-host"
+}
+
+apply ScheduledDowntime "5980-test-service-downtime" to Service {
+ import "5980-test-downtime"
+ comment = "Scheduled service downtime for tests"
+
+ ranges = {
+ tuesday = "09:37-09:40"
+ }
+
+ assign where host.name == "5980-host"
+}
+
diff --git a/test/config/6105.conf b/test/config/6105.conf
new file mode 100644
index 0000000..6bfccff
--- /dev/null
+++ b/test/config/6105.conf
@@ -0,0 +1,25 @@
+
+
+object HostGroup "6105-bar" {
+ assign where match("6105-keks*", host.name)
+ vars.foo = "bar"
+}
+
+object Host "6105-keks" {
+ import "test-generic-host"
+ address = "12.3.4"
+}
+
+apply Service "6105-foo" {
+ import "test-generic-service"
+ check_command = "ping4"
+ assign where "6105-bar" in host.groups
+}
+
+object ServiceGroup "6105-bar" {
+ assign where service.name == "6105-foo"
+ vars.bar = "foo"
+}
+
+
+
diff --git a/test/config/6479.conf b/test/config/6479.conf
new file mode 100644
index 0000000..68b08a3
--- /dev/null
+++ b/test/config/6479.conf
@@ -0,0 +1,44 @@
+
+object EventCommand "6479-handle" {
+ command = "echo \"event handler triggered.\""
+}
+
+object NotificationCommand "6479-notification" {
+ command = "echo \"notification triggered.\""
+}
+
+object HostGroup "6479-bar" {
+ assign where match("6479-keks*", host.name)
+}
+
+object Host "6479-keks" {
+ import "test-generic-host"
+ event_command = "6479-handle"
+ address = "1.2.3.4"
+}
+
+apply Service "6479-foo" {
+ import "test-generic-service"
+ check_command = "ping4"
+ event_command = "6479-handle"
+ assign where "6479-bar" in host.groups
+}
+
+apply Notification "6479-host-notification" to Host {
+ import "test-mail-host-notification"
+ command = "6479-notification"
+ assign where "6479-bar" in host.groups
+}
+
+apply Notification "6479-service-notification" to Service {
+ import "test-mail-service-notification"
+ command = "6479-notification"
+ assign where "6479-bar" in host.groups
+}
+
+object ServiceGroup "6479-bar" {
+ assign where service.name == "6479-foo"
+}
+
+
+
diff --git a/test/config/6608.conf b/test/config/6608.conf
new file mode 100644
index 0000000..e24d4c8
--- /dev/null
+++ b/test/config/6608.conf
@@ -0,0 +1,16 @@
+
+
+object Host "6608-host" {
+ import "test-generic-host"
+ vars.BUMSTI = "keks"
+ vars.bumsti = "schaschlik"
+}
+
+object Service "6608-service" {
+ import "test-generic-service"
+ check_command = "dummy"
+ host_name = "6608-host"
+ vars.DINGDONG = "$BUMSTI$"
+ vars.dingdong = "$bumsti$"
+}
+
diff --git a/test/config/6968.conf b/test/config/6968.conf
new file mode 100644
index 0000000..9882727
--- /dev/null
+++ b/test/config/6968.conf
@@ -0,0 +1,27 @@
+object Host "6968-server" {
+ import "test-generic-host"
+ address = "127.0.0.1"
+}
+
+object Service "6968-test" {
+ import "test-generic-service"
+
+ host_name = "6968-server"
+ check_command = "6968-check_vmware"
+ vars.vmware_check = "vCenter_License_Status"
+}
+
+object CheckCommand "6968-check_vmware" {
+ command = [ PluginDir + "/check_vmware.pl" ]
+
+ arguments = {
+ "--server" = "$address$"
+ "--username" = "***"
+ "--password" = "***"
+ "--check" = {
+ set_if = "$vmware_check$"
+ }
+ }
+}
+
+
diff --git a/test/config/7560.conf b/test/config/7560.conf
new file mode 100644
index 0000000..422cc04
--- /dev/null
+++ b/test/config/7560.conf
@@ -0,0 +1,41 @@
+object Host "7560-server" {
+ import "test-generic-host"
+ address = "127.0.0.1"
+ check_command = "hostalive"
+
+ vars.interfaces += {
+ eth0 = {
+ port = 1
+ vlan = "internal"
+ address = "127.0.0.2"
+ qos = "enabled"
+ }
+ eth1 = {
+ port = 2
+ vlan = "mgmt"
+ address = "127.0.1.2"
+ }
+ eth2 = {
+ port = 3
+ vlan = "remote"
+ address = "127.0.2.2"
+ }
+ }
+}
+
+apply Service "if-" for (if_name => config in host.vars.interfaces) {
+ import "test-generic-service"
+ check_command = "ping4"
+
+ vars.qos = "disabled"
+ vars += config
+
+ display_name = "if-" + if_name + "-" + vars.vlan
+
+ notes = "Interface check for Port " + string(vars.port) + " in VLAN " + vars.vlan + " on Address " + vars.address + " QoS " + vars.qos
+ notes_url = "http://foreman.company.com/hosts/" + host.name
+ action_url = "http://snmp.checker.company.com/" + host.name + "if-" + if_name
+
+ assign where match("7560-*", host.name) && typeof(host.vars.interfaces) == typeof({})
+}
+
diff --git a/test/config/7683.conf b/test/config/7683.conf
new file mode 100644
index 0000000..4e1a986
--- /dev/null
+++ b/test/config/7683.conf
@@ -0,0 +1,27 @@
+object Host "7683-parent" {
+ check_command = "dummy"
+ vars.dummy_state = 0
+}
+
+
+object Host "7683-child1" {
+ check_command = "dummy"
+ vars.dummy_state = 0
+}
+
+object Host "7683-child2" {
+ check_command = "dummy"
+ vars.dummy_state = 0
+}
+
+object Service "7683-service" {
+ check_command = "dummy"
+ host_name = "7683-parent"
+ vars.dummy_state = 0
+}
+
+apply Dependency "test-host" to Host {
+ parent_host_name = "7683-parent"
+ assign where match("7683-child*", host.name)
+}
+
diff --git a/test/config/8063.conf b/test/config/8063.conf
new file mode 100644
index 0000000..75676d1
--- /dev/null
+++ b/test/config/8063.conf
@@ -0,0 +1,73 @@
+object CheckCommand "8063-my-disk" {
+ command = [ PluginDir + "/check_disk" ]
+
+ arguments = {
+ "-w" = {
+ value = "$disk_wfree$"
+ description = "Exit with WARNING status if less than INTEGER units of disk are free or Exit with WARNING status if less than PERCENT of disk space is free"
+ required = true
+ }
+ "-c" = {
+ value = "$disk_cfree$"
+ description = "Exit with CRITICAL status if less than INTEGER units of disk are free or Exit with CRITCAL status if less than PERCENT of disk space is free"
+ required = true
+ }
+ "-W" = {
+ value = "$disk_inode_wfree$"
+ description = "Exit with WARNING status if less than PERCENT of inode space is free"
+ }
+ "-K" = {
+ value = "$disk_inode_cfree$"
+ description = "Exit with CRITICAL status if less than PERCENT of inode space is free"
+ }
+ "-p" = {
+ value = "$disk_partitions$"
+ description = "Path or partition (may be repeated)"
+ repeat_key = true
+ order = 1
+ }
+ "-x" = {
+ value = "$disk_partitions_excluded$"
+ description = "Ignore device (only works if -p unspecified)"
+ }
+ }
+
+ vars.disk_wfree = "20%"
+ vars.disk_cfree = "10%"
+}
+
+object Host "8063-my-server" {
+ import "generic-host"
+ address = "127.0.0.1"
+ address6 = "::1"
+
+ vars.local_disks["basic-partitions"] = {
+ disk_partitions = [ "/", "/tmp", "/var", "/home", "/run/user/1000/gvfs" ]
+ }
+}
+
+apply Service "8063-" for (disk => config in host.vars.local_disks) {
+ import "generic-service"
+ check_command = "8063-my-disk"
+ check_interval = 5s
+ retry_interval = 5s
+
+ volatile = true
+ vars.volatile_check = true
+
+ vars += config
+
+ vars.disk_wfree = "10%"
+ vars.disk_cfree = "5%"
+
+ assign where host.vars.local_disks
+}
+
+apply Notification "disk-notification" to Service {
+ import "test-mail-service-notification"
+
+ users = [ "test-icingaadmin" ]
+
+ assign where service.vars.volatile_check == true
+}
+
diff --git a/test/config/README b/test/config/README
new file mode 100644
index 0000000..5e8385f
--- /dev/null
+++ b/test/config/README
@@ -0,0 +1,2 @@
+Contains various test configuration for fixed issues.
+May be used for regression tests too.
diff --git a/test/config/templates.conf b/test/config/templates.conf
new file mode 100644
index 0000000..4a15bb8
--- /dev/null
+++ b/test/config/templates.conf
@@ -0,0 +1,80 @@
+/**
+ * test templates
+ */
+
+template Service "test-generic-service" {
+ max_check_attempts = 3
+ check_interval = 5m
+ retry_interval = 1m
+}
+
+template Host "test-generic-host" {
+ check_command = "hostalive"
+}
+
+template User "test-generic-user" {
+
+}
+
+template Notification "test-mail-host-notification" {
+ command = "mail-host-notification"
+
+ states = [ Up, Down ]
+ types = [ Problem, Acknowledgement, Recovery, Custom,
+ FlappingStart, FlappingEnd,
+ DowntimeStart, DowntimeEnd, DowntimeRemoved ]
+
+ period = "test-24x7"
+
+ user_groups = [ "test-icingaadmins" ]
+}
+
+/**
+ * Provides default settings for service notifications.
+ * By convention all service notifications should import
+ * this template.
+ */
+template Notification "test-mail-service-notification" {
+ command = "mail-service-notification"
+
+ states = [ OK, Warning, Critical, Unknown ]
+ types = [ Problem, Acknowledgement, Recovery, Custom,
+ FlappingStart, FlappingEnd,
+ DowntimeStart, DowntimeEnd, DowntimeRemoved ]
+
+ period = "test-24x7"
+
+ user_groups = [ "test-icingaadmins" ]
+}
+
+
+/* users */
+
+object User "test-icingaadmin" {
+ import "test-generic-user"
+
+ display_name = "Test Icinga 2 Admin"
+ groups = [ "test-icingaadmins" ]
+
+ email = "icinga@localhost"
+}
+
+object UserGroup "test-icingaadmins" {
+ display_name = "Test Icinga 2 Admin Group"
+}
+
+/* timeperiods */
+object TimePeriod "test-24x7" {
+ display_name = "Test Icinga 2 24x7 TimePeriod"
+
+ ranges = {
+ "monday" = "00:00-24:00"
+ "tuesday" = "00:00-24:00"
+ "wednesday" = "00:00-24:00"
+ "thursday" = "00:00-24:00"
+ "friday" = "00:00-24:00"
+ "saturday" = "00:00-24:00"
+ "sunday" = "00:00-24:00"
+ }
+}
+