From f66ab8dae2f3d0418759f81a3a64dc9517a62449 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 14 Apr 2024 15:17:31 +0200 Subject: Adding upstream version 1.10.2. Signed-off-by: Daniel Baumann --- .../Director/IcingaConfig/AssignRendererTest.php | 126 +++++++++++++++ .../Director/IcingaConfig/ExtensibleSetTest.php | 162 +++++++++++++++++++ .../IcingaConfig/IcingaConfigHelperTest.php | 130 ++++++++++++++++ .../Director/IcingaConfig/StateFilterTest.php | 171 +++++++++++++++++++++ .../Director/IcingaConfig/rendered/dict1.out | 6 + 5 files changed, 595 insertions(+) create mode 100644 test/php/library/Director/IcingaConfig/AssignRendererTest.php create mode 100644 test/php/library/Director/IcingaConfig/ExtensibleSetTest.php create mode 100644 test/php/library/Director/IcingaConfig/IcingaConfigHelperTest.php create mode 100644 test/php/library/Director/IcingaConfig/StateFilterTest.php create mode 100644 test/php/library/Director/IcingaConfig/rendered/dict1.out (limited to 'test/php/library/Director/IcingaConfig') diff --git a/test/php/library/Director/IcingaConfig/AssignRendererTest.php b/test/php/library/Director/IcingaConfig/AssignRendererTest.php new file mode 100644 index 0000000..b9f574e --- /dev/null +++ b/test/php/library/Director/IcingaConfig/AssignRendererTest.php @@ -0,0 +1,126 @@ +assertEquals( + $expected, + $this->renderer($string)->renderAssign() + ); + } + + public function testNegationIsRenderedCorrectlyOnRootLevel() + { + $string = '!(host.name="one"&host.name="two")'; + $expected = 'assign where !(host.name == "one" && host.name == "two")'; + $this->assertEquals( + $expected, + $this->renderer($string)->renderAssign() + ); + } + + public function testNegationIsRenderedCorrectlyOnDeeperLevel() + { + $string = 'host.address="127.*"&!host.name="localhost"'; + $expected = 'assign where match("127.*", host.address) && !(host.name == "localhost")'; + $this->assertEquals( + $expected, + $this->renderer($string)->renderAssign() + ); + } + + public function testWildcardsRenderAMatchMethod() + { + $string = 'host.address="127.0.0.*"'; + $expected = 'assign where match("127.0.0.*", host.address)'; + $this->assertEquals( + $expected, + $this->renderer($string)->renderAssign() + ); + } + + public function testACombinedFilterRendersCorrectly() + { + $string = 'host.name="*internal"|(service.vars.priority<2' + . '&host.vars.is_clustered=true)'; + + $expected = 'assign where match("*internal", host.name) ||' + . ' (service.vars.priority < 2 && host.vars.is_clustered)'; + + $this->assertEquals( + $expected, + $this->renderer($string)->renderAssign() + ); + } + + public function testSlashesAreNotEscaped() + { + $string = 'host.name=' . json_encode('a/b'); + + $expected = 'assign where host.name == "a/b"'; + + $this->assertEquals( + $expected, + $this->renderer($string)->renderAssign() + ); + } + + public function testFakeContainsOperatorRendersCorrectly() + { + $string = json_encode('member') . '=host.groups'; + + $expected = 'assign where "member" in host.groups'; + + $this->assertEquals( + $expected, + $this->renderer($string)->renderAssign() + ); + + $string = json_encode('member') . '=host.vars.some_array'; + + $expected = 'assign where "member" in host.vars.some_array'; + + $this->assertEquals( + $expected, + $this->renderer($string)->renderAssign() + ); + } + + public function testInArrayIsRenderedCorrectly() + { + $string = 'host.name=' . json_encode(array('a' ,'b')); + + $expected = 'assign where host.name in [ "a", "b" ]'; + + $this->assertEquals( + $expected, + $this->renderer($string)->renderAssign() + ); + } + + public function testWhetherSlashesAreNotEscaped() + { + $string = 'host.name=' . json_encode('a/b'); + + $expected = 'assign where host.name == "a/b"'; + + $this->assertEquals( + $expected, + $this->renderer($string)->renderAssign() + ); + } + + protected function renderer($string) + { + return AssignRenderer::forFilter(Filter::fromQueryString($string)); + } +} diff --git a/test/php/library/Director/IcingaConfig/ExtensibleSetTest.php b/test/php/library/Director/IcingaConfig/ExtensibleSetTest.php new file mode 100644 index 0000000..34bd83a --- /dev/null +++ b/test/php/library/Director/IcingaConfig/ExtensibleSetTest.php @@ -0,0 +1,162 @@ +assertEquals( + array(), + $set->getResolvedValues() + ); + } + + public function testValuesPassedToConstructorAreAccepted() + { + $values = array('Val1', 'Val2', 'Val4'); + $set = new ExtensibleSet($values); + + $this->assertEquals( + $values, + $set->getResolvedValues() + ); + } + + public function testConstructorAcceptsSingleValues() + { + $set = new ExtensibleSet('Bla'); + + $this->assertEquals( + array('Bla'), + $set->getResolvedValues() + ); + } + + public function testSingleValuesCanBeBlacklisted() + { + $values = array('Val1', 'Val2', 'Val4'); + $set = new ExtensibleSet($values); + $set->blacklist('Val2'); + + $this->assertEquals( + array('Val1', 'Val4'), + $set->getResolvedValues() + ); + } + + public function testMultipleValuesCanBeBlacklisted() + { + $values = array('Val1', 'Val2', 'Val4'); + $set = new ExtensibleSet($values); + $set->blacklist(array('Val4', 'Val1')); + + $this->assertEquals( + array('Val2'), + $set->getResolvedValues() + ); + } + + public function testSimpleInheritanceWorksFine() + { + $values = array('Val1', 'Val2', 'Val4'); + $parent = new ExtensibleSet($values); + $child = new ExtensibleSet(); + $child->inheritFrom($parent); + + $this->assertEquals( + $values, + $child->getResolvedValues() + ); + } + + public function testWeCanInheritFromMultipleParents() + { + $p1set = array('p1a', 'p1c'); + $p2set = array('p2a', 'p2d'); + $parent1 = new ExtensibleSet($p1set); + $parent2 = new ExtensibleSet($p2set); + $child = new ExtensibleSet(); + $child->inheritFrom($parent1)->inheritFrom($parent2); + + $this->assertEquals( + $p2set, + $child->getResolvedValues() + ); + } + + public function testOwnValuesOverrideParents() + { + $cset = array('p1a', 'p1c'); + $pset = array('p2a', 'p2d'); + $child = new ExtensibleSet($cset); + $parent = new ExtensibleSet($pset); + $child->inheritFrom($parent); + + $this->assertEquals( + $cset, + $child->getResolvedValues() + ); + } + + public function testInheritedValuesCanBeBlacklisted() + { + $child = new ExtensibleSet(); + $child->blacklist('p2'); + + $pset = array('p1', 'p2', 'p3'); + $parent = new ExtensibleSet($pset); + + $child->inheritFrom($parent); + $child->blacklist(array('not', 'yet', 'p1')); + + $this->assertEquals( + array('p3'), + $child->getResolvedValues() + ); + + $child->blacklist(array('p3')); + $this->assertEquals( + array(), + $child->getResolvedValues() + ); + } + + public function testInheritedValuesCanBeExtended() + { + $pset = array('p1', 'p2', 'p3'); + + $child = new ExtensibleSet(); + $child->extend('p5'); + + $parent = new ExtensibleSet($pset); + $child->inheritFrom($parent); + + $this->assertEquals( + array('p1', 'p2', 'p3', 'p5'), + $child->getResolvedValues() + ); + } + + public function testCombinedDefinitionRendersCorrectly() + { + $set = new ExtensibleSet(array('Pre', 'Def', 'Ined')); + $set->blacklist(array('And', 'Not', 'Those')); + $set->extend('PlusThis'); + + $out = ' key_name = [ Pre, Def, Ined ]' . "\n" + . ' key_name += [ PlusThis ]' . "\n" + . ' key_name -= [ And, Not, Those ]' . "\n"; + + $this->assertEquals( + $out, + $set->renderAs('key_name') + ); + } +} diff --git a/test/php/library/Director/IcingaConfig/IcingaConfigHelperTest.php b/test/php/library/Director/IcingaConfig/IcingaConfigHelperTest.php new file mode 100644 index 0000000..506f3b8 --- /dev/null +++ b/test/php/library/Director/IcingaConfig/IcingaConfigHelperTest.php @@ -0,0 +1,130 @@ +assertEquals(c::parseInterval('0'), 0); + $this->assertEquals(c::parseInterval('0s'), 0); + $this->assertEquals(c::parseInterval('10'), 10); + $this->assertEquals(c::parseInterval('70s'), 70); + $this->assertEquals(c::parseInterval('5m 10s'), 310); + $this->assertEquals(c::parseInterval('5m 60s'), 360); + $this->assertEquals(c::parseInterval('1h 5m 60s'), 3960); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testWhetherInvalidIntervalStringRaisesException() + { + c::parseInterval('1h 5m 60x'); + } + + public function testWhetherAnEmptyValueGivesNull() + { + $this->assertNull(c::parseInterval('')); + $this->assertNull(c::parseInterval(null)); + } + + public function testWhetherIntervalStringIsCorrectlyRendered() + { + $this->assertEquals(c::renderInterval(10), '10s'); + $this->assertEquals(c::renderInterval(60), '1m'); + $this->assertEquals(c::renderInterval(121), '121s'); + $this->assertEquals(c::renderInterval(3600), '1h'); + $this->assertEquals(c::renderInterval(86400), '1d'); + $this->assertEquals(c::renderInterval(86459), '86459s'); + } + + public function testCorrectlyIdentifiesReservedWords() + { + $this->assertTrue(c::isReserved('include'), 'include is a reserved word'); + $this->assertFalse(c::isReserved(0), '(int) 0 is not a reserved word'); + $this->assertFalse(c::isReserved(1), '(int) 1 is not a reserved word'); + $this->assertFalse(c::isReserved(true), '(boolean) true is not a reserved word'); + $this->assertTrue(c::isReserved('true'), '(string) true is a reserved word'); + } + + public function testWhetherDictionaryRendersCorrectly() + { + $dict = (object) [ + 'key1' => 'bla', + 'include' => 'reserved', + 'spe cial' => 'value', + '0' => 'numeric', + ]; + $this->assertEquals( + c::renderDictionary($dict), + rtrim($this->loadRendered('dict1')) + ); + } + + protected function loadRendered($name) + { + return file_get_contents(__DIR__ . '/rendered/' . $name . '.out'); + } + + public function testRenderStringIsCorrectlyRendered() + { + $this->assertEquals(c::renderString('val1\\\val2'), '"val1\\\\\\\\val2"'); + $this->assertEquals(c::renderString('"val1"'), '"\"val1\""'); + $this->assertEquals(c::renderString('\$val\$'), '"\\\\$val\\\\$"'); + $this->assertEquals(c::renderString('\t'), '"\\\\t"'); + $this->assertEquals(c::renderString('\r'), '"\\\\r"'); + $this->assertEquals(c::renderString('\n'), '"\\\\n"'); + $this->assertEquals(c::renderString('\f'), '"\\\\f"'); + } + + public function testMacrosAreDetected() + { + $this->assertFalse(c::stringHasMacro('$$vars$')); + $this->assertFalse(c::stringHasMacro('$$')); + $this->assertTrue(c::stringHasMacro('$vars$$')); + $this->assertTrue(c::stringHasMacro('$multiple$$vars.nested.name$$vars$ is here')); + $this->assertTrue(c::stringHasMacro('some $vars.nested.name$ is here')); + $this->assertTrue(c::stringHasMacro('some $vars.nested.name$$vars.even.more$')); + $this->assertTrue(c::stringHasMacro('$vars.nested.name$$a$$$$not$')); + $this->assertTrue(c::stringHasMacro('MSSQL$$$config$')); + $this->assertTrue(c::stringHasMacro('MSSQL$$$config$', 'config')); + $this->assertTrue(c::stringHasMacro('MSSQL$$$nix$ and $config$', 'config')); + $this->assertFalse(c::stringHasMacro('MSSQL$$$nix$config$ and $$', 'config')); + $this->assertFalse(c::stringHasMacro('MSSQL$$$nix$ and $$config$', 'config')); + $this->assertFalse(c::stringHasMacro('MSSQL$$$config$', 'conf')); + } + + public function testRenderStringWithVariables() + { + $this->assertEquals('"Before " + var', c::renderStringWithVariables('Before $var$')); + $this->assertEquals(c::renderStringWithVariables('$var$ After'), 'var + " After"'); + $this->assertEquals(c::renderStringWithVariables('$var$'), 'var'); + $this->assertEquals(c::renderStringWithVariables('$$var$$'), '"$$var$$"'); + $this->assertEquals(c::renderStringWithVariables('Before $$var$$ After'), '"Before $$var$$ After"'); + $this->assertEquals( + '"Before " + name1 + " " + name2 + " After"', + c::renderStringWithVariables('Before $name1$ $name2$ After') + ); + } + + public function testRenderStringWithVariablesX() + { + $this->assertEquals( + '"Before " + var1 + " " + var2 + " After"', + c::renderStringWithVariables('Before $var1$ $var2$ After') + ); + $this->assertEquals( + 'host.vars.custom', + c::renderStringWithVariables('$host.vars.custom$') + ); + $this->assertEquals('"$var\"$"', c::renderStringWithVariables('$var"$')); + $this->assertEquals( + '"\\\\tI am\\\\rrendering\\\\nproperly\\\\fand I " + support + " \"multiple\" " + variables + "\\\\$"', + c::renderStringWithVariables('\tI am\rrendering\nproperly\fand I $support$ "multiple" $variables$\$') + ); + } +} diff --git a/test/php/library/Director/IcingaConfig/StateFilterTest.php b/test/php/library/Director/IcingaConfig/StateFilterTest.php new file mode 100644 index 0000000..82e94d8 --- /dev/null +++ b/test/php/library/Director/IcingaConfig/StateFilterTest.php @@ -0,0 +1,171 @@ +assertEquals( + array(), + StateFilterSet::forIcingaObject( + IcingaUser::create(), + 'states' + )->getResolvedValues() + ); + } + + /** + * @expectedException \Icinga\Exception\InvalidPropertyException + */ + public function testFailsForInvalidProperties() + { + $set = new StateFilterSet('bla'); + } + + /** + * @expectedException \Icinga\Exception\ProgrammingError + */ + public function testCannotBeStoredForAnUnstoredUser() + { + StateFilterSet::forIcingaObject( + $this->user1(), + 'states' + )->override( + array('OK', 'Down') + )->store(); + } + + public function testCanBeStored() + { + if ($this->skipForMissingDb()) { + return; + } + + $states = $this->simpleUnstoredSetForStoredUser(); + + $this->assertTrue($states->store()); + $states->getObject()->delete(); + } + + public function testWillNotBeStoredTwice() + { + if ($this->skipForMissingDb()) { + return; + } + + $states = $this->simpleUnstoredSetForStoredUser(); + + $this->assertTrue($states->store()); + $this->assertFalse($states->store()); + $this->assertFalse($states->store()); + $states->getObject()->delete(); + } + + public function testComplexDefinitionsCanBeStored() + { + if ($this->skipForMissingDb()) { + return; + } + + $states = $this->complexUnstoredSetForStoredUser(); + + $this->assertTrue($states->store()); + $states->getObject()->delete(); + } + + public function testComplexDefinitionsCanBeLoadedAndRenderCorrectly() + { + if ($this->skipForMissingDb()) { + return; + } + + $states = $this->complexUnstoredSetForStoredUser(); + $user = $states->getObject(); + + $this->assertTrue($states->store()); + + $states = StateFilterSet::forIcingaObject($user, 'states'); + $expected = ' states = [ Down, OK, Up ]' . "\n" + . ' states += [ Warning ]' . "\n" + . ' states -= [ Up ]' . "\n"; + + $this->assertEquals( + $expected, + $states->renderAs('states') + ); + + $states->getObject()->delete(); + } + + protected function simpleUnstoredSetForStoredUser() + { + $user = $this->user1(); + $user->store($this->getDb()); + + $states = StateFilterSet::forIcingaObject( + $user, + 'states' + )->override( + array('OK', 'Down') + ); + + return $states; + } + + protected function complexUnstoredSetForStoredUser() + { + $user = $this->user2(); + $user->store($this->getDb()); + + $states = StateFilterSet::forIcingaObject( + $user, + 'states' + )->override( + array('OK', 'Down', 'Up') + )->blacklist('Up')->extend('Warning'); + + return $states; + } + + protected function user1() + { + return IcingaUser::create(array( + 'object_type' => 'object', + 'object_name' => $this->testUserName1 + )); + } + + protected function user2() + { + return IcingaUser::create(array( + 'object_type' => 'object', + 'object_name' => $this->testUserName2 + )); + } + + public function tearDown() + { + if ($this->hasDb()) { + $users = array( + $this->testUserName1, + $this->testUserName2 + ); + + $db = $this->getDb(); + foreach ($users as $user) { + if (IcingaUser::exists($user, $db)) { + IcingaUser::load($user, $db)->delete(); + } + } + } + } +} diff --git a/test/php/library/Director/IcingaConfig/rendered/dict1.out b/test/php/library/Director/IcingaConfig/rendered/dict1.out new file mode 100644 index 0000000..9f4e6bf --- /dev/null +++ b/test/php/library/Director/IcingaConfig/rendered/dict1.out @@ -0,0 +1,6 @@ +{ + "0" = numeric + @include = reserved + key1 = bla + "spe cial" = value +} -- cgit v1.2.3