summaryrefslogtreecommitdiffstats
path: root/test/php/library/Director/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'test/php/library/Director/Objects')
-rw-r--r--test/php/library/Director/Objects/HostApplyMatchesTest.php93
-rw-r--r--test/php/library/Director/Objects/HostGroupMembershipResolverTest.php353
-rw-r--r--test/php/library/Director/Objects/IcingaCommandTest.php216
-rw-r--r--test/php/library/Director/Objects/IcingaHostTest.php771
-rw-r--r--test/php/library/Director/Objects/IcingaNotificationTest.php248
-rw-r--r--test/php/library/Director/Objects/IcingaServiceSetTest.php183
-rw-r--r--test/php/library/Director/Objects/IcingaServiceTest.php293
-rw-r--r--test/php/library/Director/Objects/IcingaTemplateResolverTest.php158
-rw-r--r--test/php/library/Director/Objects/IcingaTimePeriodTest.php184
-rw-r--r--test/php/library/Director/Objects/rendered/command1.out4
-rw-r--r--test/php/library/Director/Objects/rendered/command2.out4
-rw-r--r--test/php/library/Director/Objects/rendered/command3.out4
-rw-r--r--test/php/library/Director/Objects/rendered/command4.out4
-rw-r--r--test/php/library/Director/Objects/rendered/command5.out4
-rw-r--r--test/php/library/Director/Objects/rendered/command6.out4
-rw-r--r--test/php/library/Director/Objects/rendered/command7.out9
-rw-r--r--test/php/library/Director/Objects/rendered/host1.out12
-rw-r--r--test/php/library/Director/Objects/rendered/host2.out17
-rw-r--r--test/php/library/Director/Objects/rendered/host3.out14
-rw-r--r--test/php/library/Director/Objects/rendered/notification1.out4
-rw-r--r--test/php/library/Director/Objects/rendered/service1.out14
-rw-r--r--test/php/library/Director/Objects/rendered/service2.out16
-rw-r--r--test/php/library/Director/Objects/rendered/service3.out15
-rw-r--r--test/php/library/Director/Objects/rendered/service4.out13
-rw-r--r--test/php/library/Director/Objects/rendered/service5.out14
-rw-r--r--test/php/library/Director/Objects/rendered/service6.out15
-rw-r--r--test/php/library/Director/Objects/rendered/service7.out14
27 files changed, 2680 insertions, 0 deletions
diff --git a/test/php/library/Director/Objects/HostApplyMatchesTest.php b/test/php/library/Director/Objects/HostApplyMatchesTest.php
new file mode 100644
index 0000000..b9f22ca
--- /dev/null
+++ b/test/php/library/Director/Objects/HostApplyMatchesTest.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Tests\Icinga\Module\Director\Objects;
+
+use Icinga\Data\Filter\Filter;
+use Icinga\Module\Director\Objects\HostApplyMatches;
+use Icinga\Module\Director\Objects\IcingaHost;
+use Icinga\Module\Director\Test\BaseTestCase;
+
+class HostApplyMatchesTest extends BaseTestCase
+{
+ public function testExactMatches()
+ {
+ $matcher = HostApplyMatches::prepare($this->sampleHost());
+ $this->assertTrue(
+ $matcher->matchesFilter(
+ Filter::fromQueryString('host.name=%22aha%22')
+ )
+ );
+ $this->assertFalse(
+ $matcher->matchesFilter(
+ Filter::fromQueryString('host.name=%22ahaa%22')
+ )
+ );
+ }
+
+ public function testWildcardMatches()
+ {
+ $matcher = HostApplyMatches::prepare($this->sampleHost());
+ $this->assertTrue(
+ $matcher->matchesFilter(
+ Filter::fromQueryString('host.name=%22ah*%22')
+ )
+ );
+ $this->assertTrue(
+ $matcher->matchesFilter(
+ Filter::fromQueryString('host.name=%22*h*%22')
+ )
+ );
+ $this->assertFalse(
+ $matcher->matchesFilter(
+ Filter::fromQueryString('host.name=%22*g*%22')
+ )
+ );
+ }
+
+ public function testStringVariableMatches()
+ {
+ $matcher = HostApplyMatches::prepare($this->sampleHost());
+ $this->assertTrue(
+ $matcher->matchesFilter(
+ Filter::fromQueryString('host.vars.location=%22*urem*%22')
+ )
+ );
+ $this->assertTrue(
+ $matcher->matchesFilter(
+ Filter::fromQueryString('host.vars.location=%22Nuremberg%22')
+ )
+ );
+ $this->assertFalse(
+ $matcher->matchesFilter(
+ Filter::fromQueryString('host.vars.location=%22Nurembergg%22')
+ )
+ );
+ }
+
+ public function testArrayVariableMatches()
+ {
+ $matcher = HostApplyMatches::prepare($this->sampleHost());
+ $this->assertTrue(
+ $matcher->matchesFilter(
+ Filter::fromQueryString('%22Amazing%22=host.vars.tags')
+ )
+ );
+ $this->assertFalse(
+ $matcher->matchesFilter(
+ Filter::fromQueryString('%22Amazingg%22=host.vars.tags')
+ )
+ );
+ }
+
+ protected function sampleHost()
+ {
+ return IcingaHost::create(array(
+ 'object_type' => 'object',
+ 'object_name' => 'aha',
+ 'vars' => array(
+ 'location' => 'Nuremberg',
+ 'tags' => array('Special', 'Amazing'),
+ )
+ ), $this->getDb());
+ }
+}
diff --git a/test/php/library/Director/Objects/HostGroupMembershipResolverTest.php b/test/php/library/Director/Objects/HostGroupMembershipResolverTest.php
new file mode 100644
index 0000000..cf2fb36
--- /dev/null
+++ b/test/php/library/Director/Objects/HostGroupMembershipResolverTest.php
@@ -0,0 +1,353 @@
+<?php
+
+namespace Tests\Icinga\Module\Director\Objects;
+
+use Icinga\Exception\NotFoundError;
+use Icinga\Module\Director\Data\Db\DbObjectTypeRegistry;
+use Icinga\Module\Director\Exception\DuplicateKeyException;
+use Icinga\Module\Director\Objects\HostGroupMembershipResolver;
+use Icinga\Module\Director\Objects\IcingaObject;
+use Icinga\Module\Director\Repository\IcingaTemplateRepository;
+use Icinga\Module\Director\Test\BaseTestCase;
+
+class HostGroupMembershipResolverTest extends BaseTestCase
+{
+ const PREFIX = '__groupmembership';
+ const TYPE = 'host';
+
+ public function setUp()
+ {
+ IcingaTemplateRepository::clear();
+ }
+
+ public static function cleanArtifacts()
+ {
+ $db = static::getDb()->getDbAdapter();
+
+ $where = sprintf("object_name LIKE '%s%%'", self::PREFIX);
+
+ $db->delete('icinga_' . self::TYPE . 'group', $where);
+
+ $db->delete('icinga_' . self::TYPE, $where . " AND object_type = 'object'");
+ $db->delete('icinga_' . self::TYPE, $where);
+ }
+
+ public static function setUpBeforeClass()
+ {
+ static::cleanArtifacts();
+ }
+
+ public static function tearDownAfterClass()
+ {
+ static::cleanArtifacts();
+ }
+
+ /**
+ * @param string $type
+ * @param string $name
+ * @param array $props
+ *
+ * @return IcingaObject
+ * @throws DuplicateKeyException
+ * @throws \Icinga\Exception\ConfigurationError
+ */
+ protected function object($type, $name, $props = [])
+ {
+ $db = $this->getDb();
+ $fullName = self::PREFIX . $name;
+ $object = null;
+
+ try {
+ $object = IcingaObject::loadByType($type, $fullName, $db);
+
+ foreach ($props as $k => $v) {
+ $object->set($k, $v);
+ }
+
+ $object->store();
+ } catch (NotFoundError $e) {
+ $object = null;
+ }
+
+ if ($object === null) {
+ $object = IcingaObject::createByType($type, array_merge([
+ 'object_name' => $fullName,
+ 'object_type' => 'object',
+ ], $props), $this->getDb());
+
+ $object->store();
+ }
+
+ return $object;
+ }
+
+ protected function objects($type)
+ {
+ $dummy = DbObjectTypeRegistry::newObject($type);
+
+ $table = $dummy->getTableName();
+ $query = $this->getDb()->getDbAdapter()->select()
+ ->from($table)
+ ->where('object_name LIKE ?', self::PREFIX . '%');
+
+ $objects = [];
+ $l = strlen(self::PREFIX);
+
+ foreach ($dummy::loadAll($this->getDb(), $query) as $object) {
+ $key = substr($object->getObjectName(), $l);
+ $objects[$key] = $object;
+ }
+
+ return $objects;
+ }
+
+ protected function resolved()
+ {
+ $db = $this->getDb()->getDbAdapter();
+
+ $select = $db->select()
+ ->from(
+ ['r' => 'icinga_' . self::TYPE . 'group_' . self::TYPE . '_resolved'],
+ []
+ )->join(
+ ['o' => 'icinga_' . self::TYPE],
+ 'o.id = r.' . self::TYPE . '_id',
+ ['object' => 'object_name']
+ )->join(
+ ['g' => 'icinga_' . self::TYPE . 'group'],
+ 'g.id = r.' . self::TYPE . 'group_id',
+ ['groupname' => 'object_name']
+ );
+
+ $map = [];
+ $l = strlen(self::PREFIX);
+
+ foreach ($db->fetchAll($select) as $row) {
+ $o = $row->object;
+ $g = $row->groupname;
+
+ if (! substr($o, 0, $l) === self::PREFIX) {
+ continue;
+ }
+ $o = substr($o, $l);
+
+ if (! substr($g, 0, $l) === self::PREFIX) {
+ continue;
+ }
+ $g = substr($g, $l);
+
+ if (! array_key_exists($o, $map)) {
+ $map[$o] = [];
+ }
+
+ $map[$o][] = $g;
+ }
+
+ return $map;
+ }
+
+ /**
+ * Creates:
+ *
+ * - 1 template
+ * - 10 hosts importing the template with a var match_var=magic
+ *
+ * @throws DuplicateKeyException
+ * @throws \Icinga\Exception\ConfigurationError
+ */
+ public function testCreateHosts()
+ {
+ // template that sets a group later
+ $template = $this->object('host', 'template', [
+ 'object_type' => 'template',
+ ]);
+ $this->assertTrue($template->hasBeenLoadedFromDb());
+
+ // hosts to assign groups
+ for ($i = 1; $i <= 10; $i++) {
+ $host = $this->object('host', $i, [
+ 'imports' => self::PREFIX . 'template',
+ 'vars.match_var' => 'magic'
+ ]);
+ $this->assertTrue($host->hasBeenLoadedFromDb());
+ }
+ }
+
+ /**
+ * Creates:
+ *
+ * - 10 hostgroups applying on hosts with match_var=magic
+ * - 2 static hostgroups
+ *
+ * @throws DuplicateKeyException
+ * @throws \Icinga\Exception\ConfigurationError
+ */
+ public function testCreateHostgroups()
+ {
+ $filter = 'host.vars.match_var=%22magic%22';
+ for ($i = 1; $i <= 10; $i++) {
+ $hostgroup = $this->object('hostgroup', 'apply' . $i, [
+ 'assign_filter' => $filter
+ ]);
+ $this->assertTrue($hostgroup->hasBeenLoadedFromDb());
+ }
+
+ // static groups
+ for ($i = 1; $i <= 2; $i++) {
+ $hostgroup = $this->object('hostgroup', 'static' . $i);
+ $this->assertTrue($hostgroup->hasBeenLoadedFromDb());
+ }
+ }
+
+ /**
+ * Assigns static groups to:
+ *
+ * - the template
+ * - the first host
+ *
+ * @throws DuplicateKeyException
+ * @throws \Icinga\Exception\ConfigurationError
+ *
+ * @depends testCreateHosts
+ * @depends testCreateHostgroups
+ */
+ public function testAddStaticGroups()
+ {
+ // add group to template
+ $template = $this->object('host', 'template');
+ $template->setGroups(self::PREFIX . 'static1');
+ $template->store();
+ $this->assertFalse($template->hasBeenModified());
+
+ // add group to first host
+ $host = $this->object('host', 1);
+ $host->setGroups(self::PREFIX . 'static2');
+ $host->store();
+ $this->assertFalse($host->hasBeenModified());
+ }
+
+ /**
+ * Asserts that static groups are resolved for hosts:
+ *
+ * - all but first should have static1
+ * - first should have static2
+ *
+ * @depends testAddStaticGroups
+ */
+ public function testStaticResolvedMappings()
+ {
+ $resolved = $this->resolved();
+
+ $this->assertArrayHasKey(
+ 1,
+ $resolved,
+ 'Host 1 must have groups resolved'
+ );
+
+ $this->assertContains(
+ 'static2',
+ $resolved[1],
+ 'Host template must have static group 1'
+ );
+
+ $hosts = $this->objects('host');
+ $this->assertNotEmpty($hosts, 'Must have hosts found in DB');
+
+ foreach ($hosts as $name => $host) {
+ if ($host->object_type === 'template') {
+ continue;
+ }
+
+ $this->assertArrayHasKey(
+ $name,
+ $resolved,
+ 'All hosts must have groups resolved'
+ );
+
+ if ($name === 1) {
+ $this->assertNotContains(
+ 'static1',
+ $resolved[$name],
+ 'First host must not have static group 1'
+ );
+ } else {
+ $this->assertContains(
+ 'static1',
+ $resolved[$name],
+ 'All hosts but the first must have static group 1'
+ );
+ }
+ }
+ }
+
+ /**
+ * @depends testCreateHostgroups
+ */
+ public function testApplyResolvedMappings()
+ {
+ $resolved = $this->resolved();
+
+ $hosts = $this->objects('host');
+ $this->assertNotEmpty($hosts, 'Must have hosts found in DB');
+
+ foreach ($hosts as $name => $host) {
+ if ($host->object_type === 'template') {
+ continue;
+ }
+
+ $this->assertArrayHasKey($name, $resolved, 'Host must have groups resolved');
+
+ for ($i = 1; $i <= 10; $i++) {
+ $this->assertContains(
+ 'apply' . $i,
+ $resolved[$name],
+ 'All Host objects must have all applied groups'
+ );
+ }
+ }
+ }
+
+ /**
+ * @throws DuplicateKeyException
+ * @throws \Icinga\Exception\ConfigurationError
+ *
+ * @depends testAddStaticGroups
+ */
+ public function testChangeAppliedGroupsAfterStatic()
+ {
+ $filter = 'host.vars.match_var=%22magic*%22';
+
+ $hostgroup = $this->object('hostgroup', 'apply1', [
+ 'assign_filter' => $filter
+ ]);
+ $this->assertTrue($hostgroup->hasBeenLoadedFromDb());
+ $this->assertFalse($hostgroup->hasBeenModified());
+
+ $resolved = $this->resolved();
+
+ for ($i = 1; $i <= 10; $i++) {
+ $this->assertContains(
+ 'apply1',
+ $resolved[$i],
+ 'All Host objects must have apply1 group'
+ );
+ }
+ }
+
+ /**
+ * @throws \Icinga\Exception\ConfigurationError
+ * @throws \Zend_Db_Adapter_Exception
+ *
+ * @depends testStaticResolvedMappings
+ * @depends testApplyResolvedMappings
+ * @depends testChangeAppliedGroupsAfterStatic
+ */
+ public function testFullRecheck()
+ {
+ $resolver = new HostGroupMembershipResolver($this->getDb());
+
+ $resolver->checkDb();
+ $this->assertEmpty($resolver->getNewMappings(), 'There should not be any new mappings');
+ $this->assertEmpty($resolver->getOutdatedMappings(), 'There should not be any outdated mappings');
+ }
+}
diff --git a/test/php/library/Director/Objects/IcingaCommandTest.php b/test/php/library/Director/Objects/IcingaCommandTest.php
new file mode 100644
index 0000000..8e564d8
--- /dev/null
+++ b/test/php/library/Director/Objects/IcingaCommandTest.php
@@ -0,0 +1,216 @@
+<?php
+
+namespace Tests\Icinga\Module\Director\Objects;
+
+use Icinga\Module\Director\Objects\IcingaCommand;
+use Icinga\Module\Director\Test\BaseTestCase;
+
+class IcingaCommandTest extends BaseTestCase
+{
+ protected $testCommandName = '___TEST___command';
+
+ public function testCommandsWithArgumentsCanBeCreated()
+ {
+ $command = $this->command();
+ $command->arguments = array(
+ '-H' => '$host$'
+ );
+
+ $this->assertEquals(
+ '-H',
+ $command->arguments()->get('-H')->argument_name
+ );
+
+ $this->assertEquals(
+ '$host$',
+ $command->toPlainObject()->arguments['-H']
+ );
+
+ $command->arguments()->get('-H')->required = true;
+ }
+
+ public function testCommandsWithArgumentsCanBeModified()
+ {
+ $command = $this->command();
+ $command->arguments = array(
+ '-H' => '$host$'
+ );
+
+ $command->arguments = array(
+ '-x' => (object) array(
+ 'required' => true
+ )
+ );
+
+ $this->assertEquals(
+ null,
+ $command->arguments()->get('-H')
+ );
+
+ $this->assertEquals(
+ 'y',
+ $command->arguments()->get('-x')->get('required')
+ );
+
+ $this->assertEquals(
+ true,
+ $command->toPlainObject()->arguments['-x']->required
+ );
+ }
+
+ public function testCanBePersistedToDb()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ $command = $this->newCommandWithArguments();
+
+ $this->assertEquals(
+ $command->store($db),
+ true
+ );
+
+
+ $command->delete();
+ }
+
+ public function testCanBeLoadedFromDb()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ $name = $this->testCommandName;
+ $command = $this->newCommandWithArguments($db);
+ $command->store($db);
+
+ $command = IcingaCommand::load($name, $db);
+ $this->assertEquals(
+ $command->object_name,
+ $name
+ );
+
+ $command->delete();
+ }
+
+ public function testArgumentMotificationsAreDetected()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ $command = $this->newCommandWithArguments($db);
+ $command->store($db);
+ $command->arguments()->set('-H', 'no-host');
+ $this->assertTrue($command->hasBeenModified());
+ $this->assertTrue($command->store());
+ $command->delete();
+ }
+
+ protected function newCommandWithArguments()
+ {
+ $command = $this->command();
+ $command->arguments = array(
+ '-H' => '$host$',
+ '-x' => (object) array(
+ 'required' => true,
+ 'value' => 'bal'
+ )
+ );
+
+ return $command;
+ }
+
+ public function testAbsolutePathsAreDetected()
+ {
+ $command = $this->command();
+ $command->command = 'C:\\test.exe';
+
+ $this->assertEquals(
+ $this->loadRendered('command1'),
+ (string) $command
+ );
+
+ $command->command = '/tmp/bla';
+
+ $this->assertEquals(
+ $this->loadRendered('command2'),
+ (string) $command
+ );
+
+ $command->command = 'tmp/bla';
+
+ $this->assertEquals(
+ $this->loadRendered('command3'),
+ (string) $command
+ );
+
+ $command->command = '\\\\network\\share\\bla.exe';
+
+ $this->assertEquals(
+ $this->loadRendered('command4'),
+ (string) $command
+ );
+
+ $command->command = 'BlahDir + \\network\\share\\bla.exe';
+
+ $this->assertEquals(
+ $this->loadRendered('command5'),
+ (string) $command
+ );
+
+ $command->command = 'network\\share\\bla.exe';
+
+ $this->assertEquals(
+ $this->loadRendered('command6'),
+ (string) $command
+ );
+ }
+
+ public function testSimpleSetIfIsRendered()
+ {
+ $command = $this->command();
+ $command->command = 'bla';
+ $command->arguments = array(
+ '-a' => (object) array(
+ 'set_if' => '$a$',
+ )
+ );
+
+ $this->assertEquals(
+ $this->loadRendered('command7'),
+ (string) $command
+ );
+ }
+
+ protected function command()
+ {
+ return IcingaCommand::create(
+ array(
+ 'object_name' => $this->testCommandName,
+ 'object_type' => 'object'
+ ),
+ $this->getDb()
+ );
+ }
+
+ protected function loadRendered($name)
+ {
+ return file_get_contents(__DIR__ . '/rendered/' . $name . '.out');
+ }
+
+ public function tearDown()
+ {
+ $db = $this->getDb();
+ if (IcingaCommand::exists($this->testCommandName, $db)) {
+ IcingaCommand::load($this->testCommandName, $db)->delete();
+ }
+ }
+}
diff --git a/test/php/library/Director/Objects/IcingaHostTest.php b/test/php/library/Director/Objects/IcingaHostTest.php
new file mode 100644
index 0000000..b4902bf
--- /dev/null
+++ b/test/php/library/Director/Objects/IcingaHostTest.php
@@ -0,0 +1,771 @@
+<?php
+
+namespace Tests\Icinga\Module\Director\Objects;
+
+use Icinga\Module\Director\Data\PropertiesFilter\ArrayCustomVariablesFilter;
+use Icinga\Module\Director\Data\PropertiesFilter\CustomVariablesFilter;
+use Icinga\Module\Director\IcingaConfig\IcingaConfig;
+use Icinga\Module\Director\Objects\DirectorDatafield;
+use Icinga\Module\Director\Objects\IcingaHost;
+use Icinga\Module\Director\Objects\IcingaHostGroup;
+use Icinga\Module\Director\Objects\IcingaZone;
+use Icinga\Module\Director\Test\BaseTestCase;
+use Icinga\Exception\IcingaException;
+
+class IcingaHostTest extends BaseTestCase
+{
+ protected $testHostName = '___TEST___host';
+ protected $testDatafieldName = 'test5';
+
+ public function testPropertiesCanBeSet()
+ {
+ $host = $this->host();
+ $host->display_name = 'Something else';
+ $this->assertEquals(
+ $host->display_name,
+ 'Something else'
+ );
+ }
+
+ public function testCanBeReplaced()
+ {
+ $host = $this->host();
+ $newHost = IcingaHost::create(
+ array('display_name' => 'Replaced display'),
+ $this->getDb()
+ );
+
+ $this->assertEquals(
+ count($host->vars()),
+ 4
+ );
+ $this->assertEquals(
+ $host->address,
+ '127.0.0.127'
+ );
+
+ $host->replaceWith($newHost);
+ $this->assertEquals(
+ $host->display_name,
+ 'Replaced display'
+ );
+ $this->assertEquals(
+ $host->address,
+ null
+ );
+
+ $this->assertEquals(
+ count($host->vars()),
+ 0
+ );
+ }
+
+ public function testCanBeMerged()
+ {
+ $host = $this->host();
+ $newHost = IcingaHost::create(
+ array('display_name' => 'Replaced display'),
+ $this->getDb()
+ );
+
+ $this->assertEquals(
+ count($host->vars()),
+ 4
+ );
+ $this->assertEquals(
+ $host->address,
+ '127.0.0.127'
+ );
+
+ $host->merge($newHost);
+ $this->assertEquals(
+ $host->display_name,
+ 'Replaced display'
+ );
+ $this->assertEquals(
+ $host->address,
+ '127.0.0.127'
+ );
+ $this->assertEquals(
+ count($host->vars()),
+ 4
+ );
+ }
+
+ public function testPropertiesCanBePreservedWhenBeingReplaced()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+ $this->host()->store($db);
+ $host = IcingaHost::load($this->testHostName, $db);
+
+ $newHost = IcingaHost::create(
+ array(
+ 'display_name' => 'Replaced display',
+ 'address' => '1.2.2.3',
+ 'vars' => array(
+ 'test1' => 'newstring',
+ 'test2' => 18,
+ 'initially' => 'set and then preserved',
+ )
+ ),
+ $this->getDb()
+ );
+
+ $preserve = array('address', 'vars.test1', 'vars.initially');
+ $host->replaceWith($newHost, $preserve);
+ $this->assertEquals(
+ $host->address,
+ '127.0.0.127'
+ );
+
+ $this->assertEquals(
+ $host->{'vars.test2'},
+ 18
+ );
+
+ $this->assertEquals(
+ $host->vars()->test2->getValue(),
+ 18
+ );
+
+ $this->assertEquals(
+ $host->{'vars.initially'},
+ 'set and then preserved'
+ );
+
+ $this->assertFalse(
+ array_key_exists('address', $host->getModifiedProperties()),
+ 'Preserved property stays unmodified'
+ );
+
+ $newHost->set('vars.initially', 'changed later on');
+ $newHost->set('vars.test2', 19);
+
+ $host->replaceWith($newHost, $preserve);
+ $this->assertEquals(
+ $host->{'vars.initially'},
+ 'set and then preserved'
+ );
+
+ $this->assertEquals(
+ $host->get('vars.test2'),
+ 19
+ );
+
+
+ $host->delete();
+ }
+
+ public function testDistinctCustomVarsCanBeSetWithoutSideEffects()
+ {
+ $host = $this->host();
+ $host->set('vars.test2', 18);
+ $this->assertEquals(
+ $host->vars()->test1->getValue(),
+ 'string'
+ );
+ $this->assertEquals(
+ $host->vars()->test2->getValue(),
+ 18
+ );
+ $this->assertEquals(
+ $host->vars()->test3->getValue(),
+ false
+ );
+ }
+
+ public function testVarsArePersisted()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+ $this->host()->store($db);
+ $host = IcingaHost::load($this->testHostName, $db);
+ $this->assertEquals(
+ $host->vars()->test1->getValue(),
+ 'string'
+ );
+ $this->assertEquals(
+ $host->vars()->test2->getValue(),
+ 17
+ );
+ $this->assertEquals(
+ $host->vars()->test3->getValue(),
+ false
+ );
+ $this->assertEquals(
+ $host->vars()->test4->getValue(),
+ (object) array(
+ 'this' => 'is',
+ 'a' => array(
+ 'dict',
+ 'ionary'
+ )
+ )
+ );
+ }
+
+ public function testRendersCorrectly()
+ {
+ $this->assertEquals(
+ (string) $this->host(),
+ $this->loadRendered('host1')
+ );
+ }
+
+ public function testGivesPlainObjectWithInvalidUnresolvedDependencies()
+ {
+ $props = $this->getDummyRelatedProperties();
+
+ $host = $this->host();
+ foreach ($props as $k => $v) {
+ $host->$k = $v;
+ }
+
+ $plain = $host->toPlainObject();
+ foreach ($props as $k => $v) {
+ $this->assertEquals($plain->$k, $v);
+ }
+ }
+
+ public function testCorrectlyStoresLazyRelations()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+ $db = $this->getDb();
+ $host = $this->host();
+ $host->zone = '___TEST___zone';
+ $this->assertEquals(
+ '___TEST___zone',
+ $host->zone
+ );
+
+ $zone = $this->newObject('zone', '___TEST___zone');
+ $zone->store($db);
+
+ $host->store($db);
+ $host->delete();
+ $zone->delete();
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testFailsToStoreWithMissingLazyRelations()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+ $db = $this->getDb();
+ $host = $this->host();
+ $host->zone = '___TEST___zone';
+ $host->store($db);
+ }
+
+ public function testHandlesUnmodifiedProperties()
+ {
+ $this->markTestSkipped('Currently broken, needs to be fixed');
+
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+ $host = $this->host();
+ $host->store($db);
+
+ $parent = $this->newObject('host', '___TEST___parent');
+ $parent->store($db);
+ $host->imports = '___TEST___parent';
+
+ $host->store($db);
+
+ $plain = $host->getPlainUnmodifiedObject();
+ $this->assertEquals(
+ 'string',
+ $plain->vars->test1
+ );
+ $host->vars()->set('test1', 'nada');
+
+ $host->store();
+
+ $plain = $host->getPlainUnmodifiedObject();
+ $this->assertEquals(
+ 'nada',
+ $plain->vars->test1
+ );
+
+ $host->vars()->set('test1', 'string');
+ $plain = $host->getPlainUnmodifiedObject();
+ $this->assertEquals(
+ 'nada',
+ $plain->vars->test1
+ );
+
+ $plain = $host->getPlainUnmodifiedObject();
+ $test = IcingaHost::create((array) $plain);
+
+ $this->assertEquals(
+ $this->loadRendered('host3'),
+ (string) $test
+ );
+
+ $host->delete();
+ $parent->delete();
+ }
+
+ public function testRendersWithInvalidUnresolvedDependencies()
+ {
+ $newHost = $this->host();
+ $newHost->zone = 'invalid';
+ $newHost->check_command = 'unknown';
+ $newHost->event_command = 'What event?';
+ $newHost->check_period = 'Not time is a good time @ nite';
+ $newHost->command_endpoint = 'nirvana';
+
+ $this->assertEquals(
+ (string) $newHost,
+ $this->loadRendered('host2')
+ );
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testFailsToStoreWithInvalidUnresolvedDependencies()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $host = $this->host();
+ $host->zone = 'invalid';
+ $host->store($this->getDb());
+ }
+
+ public function testRendersToTheCorrectZone()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+ $host = $this->host()->setConnection($db);
+ $masterzone = $db->getMasterZoneName();
+
+ $config = new IcingaConfig($db);
+ $host->renderToConfig($config);
+ $this->assertEquals(
+ array('zones.d/' . $masterzone . '/hosts.conf'),
+ $config->getFileNames()
+ );
+
+ $zone = $this->newObject('zone', '___TEST___zone');
+ $zone->store($db);
+
+ $config = new IcingaConfig($db);
+ $host->zone = '___TEST___zone';
+ $host->renderToConfig($config);
+ $this->assertEquals(
+ array('zones.d/___TEST___zone/hosts.conf'),
+ $config->getFileNames()
+ );
+
+ $host->has_agent = true;
+ $host->master_should_connect = true;
+ $host->accept_config = true;
+
+ $config = new IcingaConfig($db);
+ $host->renderToConfig($config);
+ $this->assertEquals(
+ array(
+ 'zones.d/___TEST___zone/hosts.conf',
+ 'zones.d/___TEST___zone/agent_endpoints.conf',
+ 'zones.d/___TEST___zone/agent_zones.conf'
+ ),
+ $config->getFileNames()
+ );
+
+ $host->object_type = 'template';
+ $host->zone_id = null;
+
+ $config = new IcingaConfig($db);
+ $host->renderToConfig($config);
+ $this->assertEquals(
+ array('zones.d/director-global/host_templates.conf'),
+ $config->getFileNames()
+ );
+ }
+
+ public function testWhetherTwoHostsCannotBeStoredWithTheSameApiKey()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+ $a = IcingaHost::create(array(
+ 'object_name' => '___TEST___a',
+ 'object_type' => 'object',
+ 'api_key' => 'a'
+ ), $db);
+ $b = IcingaHost::create(array(
+ 'object_name' => '___TEST___b',
+ 'object_type' => 'object',
+ 'api_key' => 'a'
+ ), $db);
+
+ $a->store();
+ try {
+ $b->store();
+ } catch (\RuntimeException $e) {
+ $msg = $e->getMessage();
+ $matchMysql = strpos(
+ $msg,
+ "Duplicate entry 'a' for key 'api_key'"
+ ) !== false;
+
+ $matchPostgres = strpos(
+ $msg,
+ 'Unique violation'
+ ) !== false;
+
+ $this->assertTrue(
+ $matchMysql || $matchPostgres,
+ 'Exception message does not tell about unique constraint violation'
+ );
+ $a->delete();
+ }
+ }
+
+ public function testWhetherHostCanBeLoadedWithValidApiKey()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+ $a = IcingaHost::create(array(
+ 'object_name' => '___TEST___a',
+ 'object_type' => 'object',
+ 'api_key' => 'a1a1a1'
+ ), $db);
+ $b = IcingaHost::create(array(
+ 'object_name' => '___TEST___b',
+ 'object_type' => 'object',
+ 'api_key' => 'b1b1b1'
+ ), $db);
+ $a->store();
+ $b->store();
+
+ $this->assertEquals(
+ IcingaHost::loadWithApiKey('b1b1b1', $db)->object_name,
+ '___TEST___b'
+ );
+
+ $a->delete();
+ $b->delete();
+ }
+
+ /**
+ * @expectedException \Icinga\Exception\NotFoundError
+ */
+ public function testWhetherInvalidApiKeyThrows404()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+ IcingaHost::loadWithApiKey('No___such___key', $db);
+ }
+
+ public function testEnumProperties()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+ $properties = IcingaHost::enumProperties($db);
+
+ $this->assertEquals(
+ array(
+ 'Host properties' => $this->getDefaultHostProperties()
+ ),
+ $properties
+ );
+ }
+
+ public function testEnumPropertiesWithCustomVars()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ $host = $this->host();
+ $host->store($db);
+
+ $properties = IcingaHost::enumProperties($db);
+ $this->assertEquals(
+ array(
+ 'Host properties' => $this->getDefaultHostProperties(),
+ 'Custom variables' => array(
+ 'vars.test1' => 'test1',
+ 'vars.test2' => 'test2',
+ 'vars.test3' => 'test3',
+ 'vars.test4' => 'test4'
+ )
+ ),
+ $properties
+ );
+ }
+
+ public function testEnumPropertiesWithPrefix()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ $host = $this->host();
+ $host->store($db);
+
+ $properties = IcingaHost::enumProperties($db, 'host.');
+ $this->assertEquals(
+ array(
+ 'Host properties' => $this->getDefaultHostProperties('host.'),
+ 'Custom variables' => array(
+ 'host.vars.test1' => 'test1',
+ 'host.vars.test2' => 'test2',
+ 'host.vars.test3' => 'test3',
+ 'host.vars.test4' => 'test4'
+ )
+ ),
+ $properties
+ );
+ }
+
+ public function testEnumPropertiesWithFilter()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ DirectorDatafield::create(array(
+ 'varname' => $this->testDatafieldName,
+ 'caption' => 'Blah',
+ 'description' => '',
+ 'datatype' => 'Icinga\Module\Director\DataType\DataTypeArray',
+ 'format' => 'json'
+ ))->store($db);
+
+ $host = $this->host();
+ $host->{'vars.test5'} = array('a', '1');
+ $host->store($db);
+
+ $properties = IcingaHost::enumProperties($db, '', new CustomVariablesFilter());
+ $this->assertEquals(
+ array(
+ 'Custom variables' => array(
+ 'vars.test1' => 'test1',
+ 'vars.test2' => 'test2',
+ 'vars.test3' => 'test3',
+ 'vars.test4' => 'test4',
+ 'vars.test5' => 'test5 (Blah)'
+ )
+ ),
+ $properties
+ );
+ }
+
+ public function testEnumPropertiesWithArrayFilter()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ DirectorDatafield::create(array(
+ 'varname' => $this->testDatafieldName,
+ 'caption' => 'Blah',
+ 'description' => '',
+ 'datatype' => 'Icinga\Module\Director\DataType\DataTypeArray',
+ 'format' => 'json'
+ ))->store($db);
+
+ $host = $this->host();
+ $host->{'vars.test5'} = array('a', '1');
+ $host->store($db);
+
+ $properties = IcingaHost::enumProperties($db, '', new ArrayCustomVariablesFilter());
+ $this->assertEquals(
+ array(
+ 'Custom variables' => array(
+ 'vars.test5' => 'test5 (Blah)'
+ )
+ ),
+ $properties
+ );
+ }
+
+ public function testMergingObjectKeepsGroupsIfNotGiven()
+ {
+ $one = IcingaHostGroup::create([
+ 'object_name' => 'one',
+ 'object_type' => 'object',
+ ]);
+ $two = IcingaHostGroup::create([
+ 'object_name' => 'two',
+ 'object_type' => 'object',
+ ]);
+ $a = IcingaHost::create([
+ 'object_name' => 'one',
+ 'object_type' => 'object',
+ 'imports' => [],
+ 'address' => '127.0.0.2',
+ 'groups' => [$one, $two]
+ ]);
+
+ $b = IcingaHost::create([
+ 'object_name' => 'one',
+ 'object_type' => 'object',
+ 'imports' => [],
+ 'address' => '127.0.0.42',
+ ]);
+
+ $a->merge($b);
+ $this->assertEquals(
+ '127.0.0.42',
+ $a->get('address')
+ );
+ $this->assertEquals(
+ ['one', 'two'],
+ $a->getGroups()
+ );
+ }
+
+ protected function getDummyRelatedProperties()
+ {
+ return array(
+ 'zone' => 'invalid',
+ 'check_command' => 'unknown',
+ 'event_command' => 'What event?',
+ 'check_period' => 'Not time is a good time @ nite',
+ 'command_endpoint' => 'nirvana',
+ );
+ }
+
+ protected function host()
+ {
+ return IcingaHost::create(array(
+ 'object_name' => $this->testHostName,
+ 'object_type' => 'object',
+ 'address' => '127.0.0.127',
+ 'display_name' => 'Whatever',
+ 'vars' => array(
+ 'test1' => 'string',
+ 'test2' => 17,
+ 'test3' => false,
+ 'test4' => (object) array(
+ 'this' => 'is',
+ 'a' => array(
+ 'dict',
+ 'ionary'
+ )
+ )
+ )
+ ), $this->getDb());
+ }
+
+ protected function getDefaultHostProperties($prefix = '')
+ {
+ return array(
+ "${prefix}name" => "name",
+ "${prefix}action_url" => "action_url",
+ "${prefix}address" => "address",
+ "${prefix}address6" => "address6",
+ "${prefix}api_key" => "api_key",
+ "${prefix}check_command" => "check_command",
+ "${prefix}check_interval" => "check_interval",
+ "${prefix}check_period" => "check_period",
+ "${prefix}check_timeout" => "check_timeout",
+ "${prefix}command_endpoint" => "command_endpoint",
+ "${prefix}display_name" => "display_name",
+ "${prefix}enable_active_checks" => "enable_active_checks",
+ "${prefix}enable_event_handler" => "enable_event_handler",
+ "${prefix}enable_flapping" => "enable_flapping",
+ "${prefix}enable_notifications" => "enable_notifications",
+ "${prefix}enable_passive_checks" => "enable_passive_checks",
+ "${prefix}enable_perfdata" => "enable_perfdata",
+ "${prefix}event_command" => "event_command",
+ "${prefix}flapping_threshold_high" => "flapping_threshold_high",
+ "${prefix}flapping_threshold_low" => "flapping_threshold_low",
+ "${prefix}icon_image" => "icon_image",
+ "${prefix}icon_image_alt" => "icon_image_alt",
+ "${prefix}max_check_attempts" => "max_check_attempts",
+ "${prefix}notes" => "notes",
+ "${prefix}notes_url" => "notes_url",
+ "${prefix}retry_interval" => "retry_interval",
+ "${prefix}volatile" => "volatile",
+ "${prefix}zone" => "zone",
+ "${prefix}groups" => "Groups",
+ "${prefix}templates" => "templates"
+ );
+ }
+ protected function loadRendered($name)
+ {
+ return file_get_contents(__DIR__ . '/rendered/' . $name . '.out');
+ }
+
+ public function tearDown()
+ {
+ if ($this->hasDb()) {
+ $db = $this->getDb();
+ $kill = array($this->testHostName, '___TEST___parent', '___TEST___a', '___TEST___b');
+ foreach ($kill as $name) {
+ if (IcingaHost::exists($name, $db)) {
+ IcingaHost::load($name, $db)->delete();
+ }
+ }
+
+ $kill = array('___TEST___zone');
+ foreach ($kill as $name) {
+ if (IcingaZone::exists($name, $db)) {
+ IcingaZone::load($name, $db)->delete();
+ }
+ }
+
+ $this->deleteDatafields();
+ }
+ }
+
+ protected function deleteDatafields()
+ {
+ $db = $this->getDb();
+ $dbAdapter = $db->getDbAdapter();
+ $kill = array($this->testDatafieldName);
+
+ foreach ($kill as $name) {
+ $query = $dbAdapter->select()
+ ->from('director_datafield')
+ ->where('varname = ?', $name);
+ foreach (DirectorDatafield::loadAll($db, $query, 'id') as $datafield) {
+ $datafield->delete();
+ }
+ }
+ }
+}
diff --git a/test/php/library/Director/Objects/IcingaNotificationTest.php b/test/php/library/Director/Objects/IcingaNotificationTest.php
new file mode 100644
index 0000000..9d9436a
--- /dev/null
+++ b/test/php/library/Director/Objects/IcingaNotificationTest.php
@@ -0,0 +1,248 @@
+<?php
+
+namespace Tests\Icinga\Module\Director\Objects;
+
+use Icinga\Module\Director\Objects\IcingaHost;
+use Icinga\Module\Director\Objects\IcingaService;
+use Icinga\Module\Director\Objects\IcingaNotification;
+use Icinga\Module\Director\Objects\IcingaUser;
+use Icinga\Module\Director\Objects\IcingaUsergroup;
+use Icinga\Module\Director\Test\BaseTestCase;
+
+class IcingaNotificationTest extends BaseTestCase
+{
+ protected $testUserName1 = '___TEST___user1';
+
+ protected $testUserName2 = '___TEST___user2';
+
+ protected $testNotificationName = '___TEST___notification';
+
+ public function testPropertiesCanBeSet()
+ {
+ $n = $this->notification();
+ $n->notification_interval = '10m';
+ $this->assertEquals(
+ $n->notification_interval,
+ 600
+ );
+ }
+
+ public function testCanBeStoredAndDeletedWithRelatedUserPassedAsString()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+ $db = $this->getDb();
+
+ $user = $this->user1();
+ $user->store($db);
+
+ $n = $this->notification();
+ $n->users = $user->object_name;
+ $this->assertTrue($n->store($db));
+ $this->assertTrue($n->delete());
+ $user->delete();
+ }
+
+ public function testCanBeStoredAndDeletedWithMultipleRelatedUsers()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+ $db = $this->getDb();
+
+ $user1 = $this->user1();
+ $user1->store($db);
+
+ $user2 = $this->user2();
+ $user2->store($db);
+
+ $n = $this->notification();
+ $n->users = array($user1->object_name, $user2->object_name);
+ $this->assertTrue($n->store($db));
+ $this->assertTrue($n->delete());
+ $user1->delete();
+ $user2->delete();
+ }
+
+ public function testGivesPlainObjectWithRelatedUsers()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+ $db = $this->getDb();
+
+ $user1 = $this->user1();
+ $user1->store($db);
+
+ $user2 = $this->user2();
+ $user2->store($db);
+
+ $n = $this->notification();
+ $n->users = array($user1->object_name, $user2->object_name);
+ $n->store($db);
+ $this->assertEquals(
+ (object) array(
+ 'object_name' => $this->testNotificationName,
+ 'object_type' => 'object',
+ 'users' => array(
+ $user1->object_name,
+ $user2->object_name
+ )
+ ),
+ $n->toPlainObject(false, true)
+ );
+
+ $n = IcingaNotification::load($n->object_name, $db);
+ $this->assertEquals(
+ (object) array(
+ 'object_name' => $this->testNotificationName,
+ 'object_type' => 'object',
+ 'users' => array(
+ $user1->object_name,
+ $user2->object_name
+ )
+ ),
+ $n->toPlainObject(false, true)
+ );
+ $this->assertEquals(
+ array(),
+ $n->toPlainObject()->user_groups
+ );
+ $n->delete();
+
+ $user1->delete();
+ $user2->delete();
+ }
+
+ public function testHandlesChangesForStoredRelations()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+ $db = $this->getDb();
+
+ $user1 = $this->user1();
+ $user1->store($db);
+
+ $user2 = $this->user2();
+ $user2->store($db);
+
+ $n = $this->notification();
+ $n->users = array($user1->object_name, $user2->object_name);
+ $n->store($db);
+
+ $n = IcingaNotification::load($n->object_name, $db);
+ $this->assertFalse($n->hasBeenModified());
+
+ $n->users = array($user2->object_name);
+ $this->assertTrue($n->hasBeenModified());
+
+ $n->store();
+
+ $n = IcingaNotification::load($n->object_name, $db);
+ $this->assertEquals(
+ array($user2->object_name),
+ $n->users
+ );
+
+ $n->users = array();
+ $n->store();
+
+ $n = IcingaNotification::load($n->object_name, $db);
+ $this->assertEquals(
+ array(),
+ $n->users
+ );
+
+ // Should be fixed with lazy loading:
+ // $n->users = array($user1->object_name, $user2->object_name);
+ // $this->assertFalse($n->hasBeenModified());
+
+ $n->delete();
+
+ $user1->delete();
+ $user2->delete();
+ }
+
+ public function testRendersConfigurationWithRelatedUsers()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+ $db = $this->getDb();
+
+ $user1 = $this->user1();
+ $user1->store($db);
+
+ $user2 = $this->user2();
+ $user2->store($db);
+
+ $n = $this->notification();
+ $n->users = array($user1->object_name, $user2->object_name);
+
+ $this->assertEquals(
+ $this->loadRendered('notification1'),
+ (string) $n
+ );
+ }
+
+ public function testLazyUsersCanBeSet()
+ {
+ $this->markTestSkipped('Setting lazy properties not yet completed');
+
+ $n = $this->notification();
+ $n->users = 'bla';
+ }
+
+ protected function user1()
+ {
+ return IcingaUser::create(array(
+ 'object_name' => $this->testUserName1,
+ 'object_type' => 'object',
+ 'email' => 'nowhere@example.com',
+ ), $this->getDb());
+ }
+
+ protected function user2()
+ {
+ return IcingaUser::create(array(
+ 'object_name' => $this->testUserName2,
+ 'object_type' => 'object',
+ 'email' => 'nowhere.else@example.com',
+ ), $this->getDb());
+ }
+
+ protected function notification()
+ {
+ return IcingaNotification::create(array(
+ 'object_name' => $this->testNotificationName,
+ 'object_type' => 'object',
+ ), $this->getDb());
+ }
+
+ protected function loadRendered($name)
+ {
+ return file_get_contents(__DIR__ . '/rendered/' . $name . '.out');
+ }
+
+ public function tearDown()
+ {
+ if ($this->hasDb()) {
+ $db = $this->getDb();
+ $kill = array($this->testNotificationName);
+ foreach ($kill as $name) {
+ if (IcingaNotification::exists($name, $db)) {
+ IcingaNotification::load($name, $db)->delete();
+ }
+ }
+
+ $kill = array($this->testUserName1, $this->testUserName2);
+ foreach ($kill as $name) {
+ if (IcingaUser::exists($name, $db)) {
+ IcingaUser::load($name, $db)->delete();
+ }
+ }
+ }
+ }
+}
diff --git a/test/php/library/Director/Objects/IcingaServiceSetTest.php b/test/php/library/Director/Objects/IcingaServiceSetTest.php
new file mode 100644
index 0000000..ad7c135
--- /dev/null
+++ b/test/php/library/Director/Objects/IcingaServiceSetTest.php
@@ -0,0 +1,183 @@
+<?php
+
+namespace Tests\Icinga\Module\Director\Objects;
+
+use Icinga\Module\Director\Objects\IcingaServiceSet;
+use Icinga\Module\Director\Test\IcingaObjectTestCase;
+
+class IcingaServiceSetTest extends IcingaObjectTestCase
+{
+ protected $table = 'icinga_service_set';
+ protected $testObjectName = '___TEST___set';
+
+ public function setUp()
+ {
+ $this->assertNull($this->subject, 'subject must have been taken down before!');
+
+ if ($this->hasDb()) {
+ $this->subject = IcingaServiceSet::create(array(
+ 'object_name' => $this->testObjectName,
+ 'object_type' => 'template',
+ ));
+ $this->subject->store($this->getDb());
+ }
+ }
+
+ public function testUpdatingSet()
+ {
+ $set = IcingaServiceSet::load($this->testObjectName, $this->getDb());
+ $this->assertTrue($set->hasBeenLoadedFromDb());
+
+ $set->set('description', 'This is a set created by Phpunit!');
+ $this->assertTrue($set->hasBeenModified());
+ $set->store();
+
+ $set->set('assign_filter', 'host.name=foobar');
+ $this->assertTrue($set->hasBeenModified());
+ $set->store();
+
+ $this->assertFalse($set->hasBeenModified());
+ }
+
+ public function testAddingSetToHost()
+ {
+ $host = $this->createObject('for_set', 'icinga_host', array(
+ 'object_type' => 'object',
+ 'address' => '1.2.3.4',
+ ));
+
+ $set = IcingaServiceSet::create(array(
+ 'object_name' => $this->testObjectName,
+ 'object_type' => 'object',
+ ), $this->getDb()); // TODO: fails if db not set here...
+
+ $set->setImports($this->testObjectName);
+ $this->assertTrue($set->hasBeenModified());
+ $this->assertEquals(array($this->testObjectName), $set->getImports());
+
+ $set->set('host', $host->getObjectName());
+
+ $set->store();
+ $this->prepareObjectTearDown($set);
+ $this->assertFalse($set->hasBeenModified());
+ }
+
+ public function testDeletingHostWithSet()
+ {
+ $this->createObject('for_set', 'icinga_host', array(
+ 'object_type' => 'object',
+ 'address' => '1.2.3.4',
+ ), false)->store();
+
+ $host = $this->loadObject('for_set', 'icinga_host');
+ $host->delete();
+
+ $this->checkForDanglingHostSets();
+ }
+
+ public function testAddingServicesToSet()
+ {
+ $set = IcingaServiceSet::load($this->testObjectName, $this->getDb());
+
+ // TODO: setting service_set by name should work too...
+
+ $serviceA = $this->createObject('serviceA', 'icinga_service', array(
+ 'object_type' => 'apply',
+ 'service_set_id' => $set->getAutoincId(),
+ ));
+ $nameA = $serviceA->getObjectName();
+
+ $serviceB = $this->createObject('serviceB', 'icinga_service', array(
+ 'object_type' => 'apply',
+ 'service_set_id' => $set->getAutoincId(),
+ ));
+ $nameB = $serviceB->getObjectName();
+
+ $services = $set->getServiceObjects();
+
+ $this->assertCount(2, $services);
+ $this->assertArrayHasKey($nameA, $services);
+ $this->assertArrayHasKey($nameB, $services);
+ $this->assertEquals($serviceA->getAutoincId(), $services[$nameA]->getAutoincId());
+ $this->assertEquals($serviceB->getAutoincId(), $services[$nameB]->getAutoincId());
+
+ // TODO: deleting set should delete services
+
+ $this->checkForDanglingServices();
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testCreatingSetWithoutType()
+ {
+ $set = IcingaServiceSet::create(array(
+ 'object_name' => '___TEST__set_BAD',
+ ));
+ $set->store($this->getDb());
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testCreatingServiceSetWithoutHost()
+ {
+ $set = IcingaServiceSet::create(array(
+ 'object_name' => '___TEST__set_BAD2',
+ 'object_type' => 'object',
+ ));
+
+ $set->store($this->getDb());
+ }
+
+ public function testDeletingSet()
+ {
+ $set = IcingaServiceSet::load($this->testObjectName, $this->getDb());
+ $set->delete();
+
+ $this->assertFalse(IcingaServiceSet::exists($this->testObjectName, $this->getDb()));
+ $this->subject = null;
+ }
+
+ public function checkForDanglingServices()
+ {
+ $db = $this->getDb()->getDbAdapter();
+ $query = $db->select()
+ ->from(array('s' => 'icinga_service'), array('id'))
+ ->joinLeft(
+ array('ss' => 'icinga_service_set'),
+ 'ss.id = s.service_set_id',
+ array()
+ )
+ ->where('s.service_set_id IS NOT NULL')
+ ->where('ss.id IS NULL');
+
+ $ids = $db->fetchCol($query);
+
+ $this->assertEmpty($ids, sprintf('Found dangling service_set services in database: %s', join(', ', $ids)));
+ }
+
+ public function checkForDanglingHostSets()
+ {
+ $db = $this->getDb()->getDbAdapter();
+ $query = $db->select()
+ ->from(array('ss' => 'icinga_service_set'), array('id'))
+ ->joinLeft(
+ array('h' => 'icinga_host'),
+ 'h.id = ss.host_id',
+ array()
+ )
+ ->where('ss.host_id IS NOT NULL')
+ ->where('h.id IS NULL');
+
+ $ids = $db->fetchCol($query);
+
+ $this->assertEmpty(
+ $ids,
+ sprintf(
+ 'Found dangling service_set\'s for a host, without the host in database: %s',
+ join(', ', $ids)
+ )
+ );
+ }
+}
diff --git a/test/php/library/Director/Objects/IcingaServiceTest.php b/test/php/library/Director/Objects/IcingaServiceTest.php
new file mode 100644
index 0000000..468db67
--- /dev/null
+++ b/test/php/library/Director/Objects/IcingaServiceTest.php
@@ -0,0 +1,293 @@
+<?php
+
+namespace Tests\Icinga\Module\Director\Objects;
+
+use Icinga\Module\Director\IcingaConfig\IcingaConfig;
+use Icinga\Module\Director\Objects\IcingaHost;
+use Icinga\Module\Director\Objects\IcingaService;
+use Icinga\Module\Director\Test\BaseTestCase;
+
+class IcingaServiceTest extends BaseTestCase
+{
+ protected $testHostName = '___TEST___host';
+
+ protected $testServiceName = '___TEST___service';
+
+ protected $createdServices = array();
+
+ public function testUnstoredHostCanBeLazySet()
+ {
+ $service = $this->service();
+ $service->display_name = 'Something else';
+ $service->host = 'not yet';
+ $this->assertEquals(
+ 'not yet',
+ $service->host
+ );
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testFailsToStoreWithMissingLazyRelations()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+ $service = $this->service();
+ $service->display_name = 'Something else';
+ $service->host = 'not yet';
+ $service->store($db);
+ $service->delete();
+ }
+
+ public function testAcceptsAssignRules()
+ {
+ $service = $this->service();
+ $service->object_type = 'apply';
+ $service->assign_filter = 'host.address="127.*"';
+ }
+
+ /**
+ * @expectedException \LogicException
+ */
+ public function testRefusesAssignRulesWhenNotBeingAnApply()
+ {
+ $service = $this->service();
+ $service->assign_filter = 'host.address=127.*';
+ }
+
+ public function testAcceptsAndRendersFlatAssignRules()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ $service = $this->service();
+
+ // Service apply rule rendering requires access to settings:
+ $service->setConnection($db);
+ $service->object_type = 'apply';
+ $service->assign_filter = 'host.address="127.*"|host.vars.env="test"';
+
+ $this->assertEquals(
+ $this->loadRendered('service1'),
+ (string) $service
+ );
+
+ $this->assertEquals(
+ 'host.address="127.*"|host.vars.env="test"',
+ $service->assign_filter
+ );
+ }
+
+ public function testAcceptsAndRendersStructuredAssignRules()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ $service = $this->service();
+ // Service apply rule rendering requires access to settings:
+ $service->setConnection($db);
+ $service->object_type = 'apply';
+ $service->assign_filter = 'host.address="127.*"|host.vars.env="test"';
+
+ $this->assertEquals(
+ $this->loadRendered('service1'),
+ (string) $service
+ );
+
+ $this->assertEquals(
+ 'host.address="127.*"|host.vars.env="test"',
+ $service->assign_filter = 'host.address="127.*"|host.vars.env="test"'
+ );
+ }
+
+ public function testPersistsAssignRules()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ $service = $this->service();
+ $service->object_type = 'apply';
+ $service->assign_filter = 'host.address="127.*"|host.vars.env="test"';
+
+ $service->store($db);
+
+ $service = IcingaService::loadWithAutoIncId($service->id, $db);
+ $this->assertEquals(
+ $this->loadRendered('service1'),
+ (string) $service
+ );
+
+ $this->assertEquals(
+ 'host.address="127.*"|host.vars.env="test"',
+ $service->assign_filter
+ );
+
+ $service->delete();
+ }
+
+ public function testRendersToTheCorrectZone()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+ $service = $this->service()->setConnection($db);
+
+ $config = new IcingaConfig($db);
+ $service->renderToConfig($config);
+ $masterzone = $db->getMasterZoneName();
+ $this->assertEquals(
+ array('zones.d/' . $masterzone . '/services.conf'),
+ $config->getFileNames()
+ );
+ }
+
+ public function testVariablesInPropertiesAndCustomVariables()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ $service = $this->service('___TEST___service_$not_replaced$');
+ $service->setConnection($db);
+ $service->object_type = 'apply';
+ $service->display_name = 'Service: $host.vars.replaced$';
+ $service->assign_filter = 'host.address="127.*"';
+ $service->{'vars.custom_var'} = '$host.vars.replaced$';
+
+ $this->assertEquals(
+ $this->loadRendered('service3'),
+ (string) $service
+ );
+ }
+
+ public function testVariablesAreNotReplacedForNonApplyObjects()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ $host = $this->host();
+ $host->store($db);
+
+ $service = $this->service('___TEST___service_$not_replaced$');
+ $service->object_type = 'object';
+ $service->host_id = $host->get('id');
+ $service->display_name = 'Service: $host.vars.not_replaced$';
+ $service->{'vars.custom_var'} = '$host.vars.not_replaced$';
+ $service->store($db);
+
+ $service = IcingaService::loadWithAutoIncId($service->id, $db);
+ $this->assertEquals(
+ $this->loadRendered('service4'),
+ (string) $service
+ );
+ }
+
+ public function testApplyForRendersInVariousModes()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $db = $this->getDb();
+
+ $service = $this->service()->setConnection($db);
+ $service->object_type = 'apply';
+ $service->apply_for = 'host.vars.test1';
+ $service->assign_filter = 'host.vars.env="test"';
+ $this->assertEquals(
+ $this->loadRendered('service5'),
+ (string) $service
+ );
+
+ $service->object_name = '___TEST$config$___service $host.var.bla$';
+ $this->assertEquals(
+ $this->loadRendered('service6'),
+ (string) $service
+ );
+
+ $service->object_name = '';
+ $this->assertEquals(
+ $this->loadRendered('service7'),
+ (string) $service
+ );
+ }
+
+ protected function host()
+ {
+ return IcingaHost::create(array(
+ 'object_name' => $this->testHostName,
+ 'object_type' => 'object',
+ 'address' => '127.0.0.1',
+ ));
+ }
+
+ protected function service($objectName = null)
+ {
+ if ($objectName === null) {
+ $objectName = $this->testServiceName;
+ }
+ $this->createdServices[] = $objectName;
+ return IcingaService::create(array(
+ 'object_name' => $objectName,
+ 'object_type' => 'object',
+ 'display_name' => 'Whatever service',
+ 'vars' => array(
+ 'test1' => 'string',
+ 'test2' => 17,
+ 'test3' => false,
+ 'test4' => (object) array(
+ 'this' => 'is',
+ 'a' => array(
+ 'dict',
+ 'ionary'
+ )
+ )
+ )
+ ));
+ }
+
+ protected function loadRendered($name)
+ {
+ return file_get_contents(__DIR__ . '/rendered/' . $name . '.out');
+ }
+
+ public function tearDown()
+ {
+ if ($this->hasDb()) {
+ $db = $this->getDb();
+ $kill = array($this->testHostName);
+ foreach ($kill as $name) {
+ if (IcingaHost::exists($name, $db)) {
+ IcingaHost::load($name, $db)->delete();
+ }
+ }
+
+ $kill = $this->createdServices;
+ foreach ($kill as $name) {
+ if (IcingaService::exists(array($name), $db)) {
+ IcingaService::load($name, $db)->delete();
+ }
+ }
+ }
+ }
+}
diff --git a/test/php/library/Director/Objects/IcingaTemplateResolverTest.php b/test/php/library/Director/Objects/IcingaTemplateResolverTest.php
new file mode 100644
index 0000000..09d0ead
--- /dev/null
+++ b/test/php/library/Director/Objects/IcingaTemplateResolverTest.php
@@ -0,0 +1,158 @@
+<?php
+
+namespace Tests\Icinga\Module\Director\Objects;
+
+use Icinga\Module\Director\Objects\IcingaHost;
+use Icinga\Module\Director\Test\BaseTestCase;
+
+class IcingaTemplateResolverTest extends BaseTestCase
+{
+ /** @var IcingaHost[] */
+ private $scenario;
+
+ private $prefix = '__TEST_i1_';
+
+ public function testParentNamesCanBeRetrieved()
+ {
+ $this->assertEquals(
+ array(
+ $this->prefixed('t6'),
+ $this->prefixed('t5'),
+ $this->prefixed('t2')
+ ),
+ $this->getHost('t1')->templateResolver()->listParentNames()
+ );
+ }
+
+ public function testFullInhertancePathIdsAreCorrect()
+ {
+ $this->assertEquals(
+ $this->getIds(array('t5', 't6', 't5', 't5', 't4', 't3', 't5', 't6', 't2', 't1')),
+ $this->getHost('t1')->templateResolver()->listFullInheritancePathIds()
+ );
+ }
+
+ public function testInhertancePathIdsAreCorrect()
+ {
+ $this->assertEquals(
+ $this->getIds(array('t4', 't3', 't5', 't6', 't2', 't1')),
+ $this->getHost('t1')->templateResolver()->listInheritancePathIds()
+ );
+ }
+
+ protected function getHost($name)
+ {
+ $hosts = $this->getScenario();
+ return $hosts[$name];
+ }
+
+ protected function getId($name)
+ {
+ $hosts = $this->getScenario();
+ return $hosts[$name]->id;
+ }
+
+ protected function getIds($names)
+ {
+ $ids = array();
+ foreach ($names as $name) {
+ $ids[] = $this->getId($name);
+ }
+
+ return $ids;
+ }
+
+ protected function prefixed($name)
+ {
+ return $this->prefix . $name;
+ }
+
+ /**
+ * @return IcingaHost[]
+ */
+ protected function getScenario()
+ {
+ if ($this->scenario === null) {
+ $this->scenario = $this->createScenario();
+ }
+
+ return $this->scenario;
+ }
+
+ /**
+ * @return IcingaHost[]
+ */
+ protected function createScenario()
+ {
+ // Defionition imports (object -> imported)
+ // t1 -> t6, t5, t2
+ // t6 -> t5
+ // t3 -> t4
+ // t2 -> t3, t6
+ // t4 -> t5
+
+ // 5, 6, 5, 5, 4, 3, 5, 6, 2, 1
+
+ $t1 = $this->create('t1');
+ $t4 = $this->create('t4');
+ $t3 = $this->create('t3');
+ $t2 = $this->create('t2');
+ $t5 = $this->create('t5');
+ $t6 = $this->create('t6');
+
+ // TODO: Must work without this:
+ $t1->templateResolver()->clearCache();
+ $t1->set('imports', array($t6, $t5, $t2));
+ $t6->set('imports', array($t5));
+ $t3->set('imports', array($t4));
+ $t2->set('imports', array($t3, $t6));
+ $t4->set('imports', array($t5));
+
+ $t5->store();
+ $t4->store();
+ $t3->store();
+ $t6->store();
+ $t2->store();
+ $t1->store();
+
+ // TODO: Must work without this:
+ $t1->templateResolver()->clearCache();
+ return array(
+ 't1' => $t1,
+ 't2' => $t2,
+ 't3' => $t3,
+ 't4' => $t4,
+ 't5' => $t5,
+ 't6' => $t6,
+ );
+ }
+
+ /**
+ * @param $name
+ * @return IcingaHost
+ */
+ protected function create($name)
+ {
+ $host = IcingaHost::create(
+ array(
+ 'object_name' => $this->prefixed($name),
+ 'object_type' => 'template'
+ )
+ );
+
+ $host->store($this->getDb());
+ return $host;
+ }
+
+ public function tearDown()
+ {
+ $db = $this->getDb();
+ $kill = array('t1', 't2', 't6', 't3', 't4', 't5');
+ foreach ($kill as $short) {
+ $name = $this->prefixed($short);
+ if (IcingaHost::exists($name, $db)) {
+ IcingaHost::load($name, $db)->delete();
+ }
+ }
+ }
+}
diff --git a/test/php/library/Director/Objects/IcingaTimePeriodTest.php b/test/php/library/Director/Objects/IcingaTimePeriodTest.php
new file mode 100644
index 0000000..84496d3
--- /dev/null
+++ b/test/php/library/Director/Objects/IcingaTimePeriodTest.php
@@ -0,0 +1,184 @@
+<?php
+
+namespace Tests\Icinga\Module\Director\Objects;
+
+use Icinga\Module\Director\Objects\IcingaTimePeriod;
+use Icinga\Module\Director\Test\BaseTestCase;
+
+class IcingaTimePeriodTest extends BaseTestCase
+{
+ protected $testPeriodName = '___TEST___timeperiod';
+
+ protected $createdNames = [];
+
+ public function testWhetherUpdatedTimeperiodsAreCorrectlyStored()
+ {
+ if ($this->skipForMissingDb()) {
+ return;
+ }
+
+ $period = $this->createTestPeriod();
+
+ $newRanges = array(
+ 'monday' => '00:00-24:00',
+ 'tuesday' => '18:00-24:00',
+ 'wednesday' => '00:00-24:00',
+ );
+ $period->ranges = $newRanges;
+ $this->assertEquals(
+ '18:00-24:00',
+ $period->toPlainObject()->ranges->tuesday
+ );
+
+ $period->store();
+
+ $period = $this->loadTestPeriod();
+ $this->assertEquals(
+ '18:00-24:00',
+ $period->ranges()->get('tuesday')->range_value
+ );
+
+ $this->assertEquals(
+ '00:00-24:00',
+ $period->toPlainObject()->ranges->wednesday
+ );
+
+ $period->ranges()->setRange('wednesday', '09:00-17:00');
+
+ $this->assertEquals(
+ '09:00-17:00',
+ $period->toPlainObject()->ranges->wednesday
+ );
+
+ $this->assertEquals(
+ '00:00-24:00',
+ $period->getPlainUnmodifiedObject()->ranges->wednesday
+ );
+ }
+
+ protected function createTestPeriod($suffix = '', $testRanges = [])
+ {
+ $db = $this->getDb();
+ $name = $this->testPeriodName . $suffix;
+
+ $this->createdNames[] = $name;
+ $object = IcingaTimePeriod::create(
+ array(
+ 'object_name' => $name,
+ 'object_type' => 'object'
+ ),
+ $db
+ );
+ $object->store();
+ $ranges = $object->ranges();
+
+ if (empty($testRanges)) {
+ $testRanges = array(
+ 'monday' => '00:00-24:00',
+ 'tuesday' => '00:00-24:00',
+ 'wednesday' => '00:00-24:00',
+ );
+ }
+
+ $ranges->set($testRanges);
+ $object->store();
+
+ return $object;
+ }
+
+ public function testIsActiveWorksForWeekdayRanges()
+ {
+ $period = $this->createTestPeriod();
+
+ $newRanges = array(
+ 'monday' => '00:00-24:00',
+ 'tuesday' => '18:00-24:00',
+ 'wednesday' => '00:00-24:00',
+ );
+ $period->ranges = $newRanges;
+
+ // Tuesday:
+ $this->assertFalse($period->isActive(strtotime('2016-05-17 10:00:00')));
+ // Wednesday:
+ $this->assertTrue($period->isActive(strtotime('2016-05-18 10:00:00')));
+ // Thursday:
+ $this->assertFalse($period->isActive(strtotime('2016-05-19 10:00:00')));
+ }
+
+ public function testPeriodWithIncludes()
+ {
+ $period = $this->createTestPeriod();
+ $include = $this->createTestPeriod('include', ['thursday' => '00:00-24:00']);
+
+ $period->set('includes', $include->object_name);
+ $period->store();
+
+ // Wednesday:
+ $this->assertTrue($period->isActive(strtotime('2016-05-18 10:00:00')));
+ // Thursday:
+ $this->assertTrue($period->isActive(strtotime('2016-05-19 10:00:00')));
+ }
+
+ public function testPeriodWithExcludes()
+ {
+ $period = $this->createTestPeriod();
+ $exclude = $this->createTestPeriod('exclude', ['wednesday' => '00:00-24:00']);
+
+ $period->set('excludes', $exclude->object_name);
+ $period->store();
+
+ // Wednesday:
+ $this->assertFalse($period->isActive(strtotime('2016-05-18 10:00:00')));
+ // Thursday:
+ $this->assertFalse($period->isActive(strtotime('2016-05-19 10:00:00')));
+ }
+
+ public function testPeriodPreferingIncludes()
+ {
+ $period = $this->createTestPeriod();
+ $include = $this->createTestPeriod('include', ['thursday' => '00:00-24:00']);
+ $exclude = $this->createTestPeriod('exclude', ['thursday' => '00:00-24:00']);
+
+ $period->set('includes', $include->object_name);
+ $period->set('excludes', $exclude->object_name);
+ $period->store();
+
+ // Wednesday:
+ $this->assertTrue($period->isActive(strtotime('2016-05-18 10:00:00')));
+ // Thursday:
+ $this->assertTrue($period->isActive(strtotime('2016-05-19 10:00:00')));
+ }
+
+ public function testPeriodPreferingExcludes()
+ {
+ $period = $this->createTestPeriod();
+ $include = $this->createTestPeriod('include', ['thursday' => '00:00-24:00']);
+ $exclude = $this->createTestPeriod('exclude', ['thursday' => '00:00-24:00']);
+
+ $period->set('prefer_includes', false);
+ $period->set('includes', $include->object_name);
+ $period->set('excludes', $exclude->object_name);
+ $period->store();
+
+ // Wednesday:
+ $this->assertTrue($period->isActive(strtotime('2016-05-18 10:00:00')));
+ // Thursday:
+ $this->assertFalse($period->isActive(strtotime('2016-05-19 10:00:00')));
+ }
+
+ protected function loadTestPeriod($suffix = '')
+ {
+ return IcingaTimePeriod::load($this->testPeriodName . $suffix, $this->getDb());
+ }
+
+ public function tearDown()
+ {
+ $db = $this->getDb();
+
+ foreach ($this->createdNames as $name) {
+ if (IcingaTimePeriod::exists($name, $db)) {
+ IcingaTimePeriod::load($name, $db)->delete();
+ }
+ }
+ }
+}
diff --git a/test/php/library/Director/Objects/rendered/command1.out b/test/php/library/Director/Objects/rendered/command1.out
new file mode 100644
index 0000000..12e156f
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/command1.out
@@ -0,0 +1,4 @@
+object CheckCommand "___TEST___command" {
+ command = [ "C:\\test.exe" ]
+}
+
diff --git a/test/php/library/Director/Objects/rendered/command2.out b/test/php/library/Director/Objects/rendered/command2.out
new file mode 100644
index 0000000..e853285
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/command2.out
@@ -0,0 +1,4 @@
+object CheckCommand "___TEST___command" {
+ command = [ "/tmp/bla" ]
+}
+
diff --git a/test/php/library/Director/Objects/rendered/command3.out b/test/php/library/Director/Objects/rendered/command3.out
new file mode 100644
index 0000000..7e7eef9
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/command3.out
@@ -0,0 +1,4 @@
+object CheckCommand "___TEST___command" {
+ command = [ PluginDir + "/tmp/bla" ]
+}
+
diff --git a/test/php/library/Director/Objects/rendered/command4.out b/test/php/library/Director/Objects/rendered/command4.out
new file mode 100644
index 0000000..3dc7ac5
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/command4.out
@@ -0,0 +1,4 @@
+object CheckCommand "___TEST___command" {
+ command = [ "\\\\network\\share\\bla.exe" ]
+}
+
diff --git a/test/php/library/Director/Objects/rendered/command5.out b/test/php/library/Director/Objects/rendered/command5.out
new file mode 100644
index 0000000..1e57577
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/command5.out
@@ -0,0 +1,4 @@
+object CheckCommand "___TEST___command" {
+ command = [ BlahDir + "\\network\\share\\bla.exe" ]
+}
+
diff --git a/test/php/library/Director/Objects/rendered/command6.out b/test/php/library/Director/Objects/rendered/command6.out
new file mode 100644
index 0000000..3f123ce
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/command6.out
@@ -0,0 +1,4 @@
+object CheckCommand "___TEST___command" {
+ command = [ PluginDir + "/network\\share\\bla.exe" ]
+}
+
diff --git a/test/php/library/Director/Objects/rendered/command7.out b/test/php/library/Director/Objects/rendered/command7.out
new file mode 100644
index 0000000..4f966f0
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/command7.out
@@ -0,0 +1,9 @@
+object CheckCommand "___TEST___command" {
+ command = [ PluginDir + "/bla" ]
+ arguments += {
+ "-a" = {
+ set_if = "$a$"
+ }
+ }
+}
+
diff --git a/test/php/library/Director/Objects/rendered/host1.out b/test/php/library/Director/Objects/rendered/host1.out
new file mode 100644
index 0000000..3637f2d
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/host1.out
@@ -0,0 +1,12 @@
+object Host "___TEST___host" {
+ display_name = "Whatever"
+ address = "127.0.0.127"
+ vars.test1 = "string"
+ vars.test2 = 17
+ vars.test3 = false
+ vars.test4 = {
+ a = [ "dict", "ionary" ]
+ @this = "is"
+ }
+}
+
diff --git a/test/php/library/Director/Objects/rendered/host2.out b/test/php/library/Director/Objects/rendered/host2.out
new file mode 100644
index 0000000..74668e1
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/host2.out
@@ -0,0 +1,17 @@
+object Host "___TEST___host" {
+ display_name = "Whatever"
+ address = "127.0.0.127"
+ check_command = "unknown"
+ check_period = "Not time is a good time @ nite"
+ event_command = "What event?"
+ zone = "invalid"
+ command_endpoint = "nirvana"
+ vars.test1 = "string"
+ vars.test2 = 17
+ vars.test3 = false
+ vars.test4 = {
+ a = [ "dict", "ionary" ]
+ @this = "is"
+ }
+}
+
diff --git a/test/php/library/Director/Objects/rendered/host3.out b/test/php/library/Director/Objects/rendered/host3.out
new file mode 100644
index 0000000..5661ca9
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/host3.out
@@ -0,0 +1,14 @@
+object Host "___TEST___host" {
+ import "___TEST___parent"
+
+ display_name = "Whatever"
+ address = "127.0.0.127"
+ vars.test1 = "nada"
+ vars.test2 = 17
+ vars.test3 = false
+ vars.test4 = {
+ a = [ "dict", "ionary" ]
+ @this = "is"
+ }
+}
+
diff --git a/test/php/library/Director/Objects/rendered/notification1.out b/test/php/library/Director/Objects/rendered/notification1.out
new file mode 100644
index 0000000..13f06ce
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/notification1.out
@@ -0,0 +1,4 @@
+object Notification "___TEST___notification" {
+ users = [ "___TEST___user1", "___TEST___user2" ]
+}
+
diff --git a/test/php/library/Director/Objects/rendered/service1.out b/test/php/library/Director/Objects/rendered/service1.out
new file mode 100644
index 0000000..ba65b08
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/service1.out
@@ -0,0 +1,14 @@
+apply Service "___TEST___service" {
+ display_name = "Whatever service"
+ assign where match("127.*", host.address) || host.vars.env == "test"
+ vars.test1 = "string"
+ vars.test2 = 17
+ vars.test3 = false
+ vars.test4 = {
+ a = [ "dict", "ionary" ]
+ @this = "is"
+ }
+
+ import DirectorOverrideTemplate
+}
+
diff --git a/test/php/library/Director/Objects/rendered/service2.out b/test/php/library/Director/Objects/rendered/service2.out
new file mode 100644
index 0000000..ea7d901
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/service2.out
@@ -0,0 +1,16 @@
+apply Service "___TEST___service" {
+ display_name = "Whatever service"
+ vars.test1 = "string"
+ vars.test2 = 17
+ vars.test3 = false
+ vars.test4 = {
+ a = [ "dict", "ionary" ]
+ @this = "is"
+ }
+
+ assign where match("128.*", host.address)
+ ignore where host.name == "localhost"
+
+ import DirectorOverrideTemplate
+}
+
diff --git a/test/php/library/Director/Objects/rendered/service3.out b/test/php/library/Director/Objects/rendered/service3.out
new file mode 100644
index 0000000..0288ee6
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/service3.out
@@ -0,0 +1,15 @@
+apply Service "___TEST___service_$not_replaced$" {
+ display_name = "Service: " + host.vars.replaced
+ assign where match("127.*", host.address)
+ vars.custom_var = "$host.vars.replaced$"
+ vars.test1 = "string"
+ vars.test2 = 17
+ vars.test3 = false
+ vars.test4 = {
+ a = [ "dict", "ionary" ]
+ @this = "is"
+ }
+
+ import DirectorOverrideTemplate
+}
+
diff --git a/test/php/library/Director/Objects/rendered/service4.out b/test/php/library/Director/Objects/rendered/service4.out
new file mode 100644
index 0000000..aeb280a
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/service4.out
@@ -0,0 +1,13 @@
+object Service "___TEST___service_$not_replaced$" {
+ host_name = "___TEST___host"
+ display_name = "Service: $host.vars.not_replaced$"
+ vars.custom_var = "$host.vars.not_replaced$"
+ vars.test1 = "string"
+ vars.test2 = 17
+ vars.test3 = false
+ vars.test4 = {
+ a = [ "dict", "ionary" ]
+ @this = "is"
+ }
+}
+
diff --git a/test/php/library/Director/Objects/rendered/service5.out b/test/php/library/Director/Objects/rendered/service5.out
new file mode 100644
index 0000000..b05e630
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/service5.out
@@ -0,0 +1,14 @@
+apply Service "___TEST___service" for (config in host.vars.test1) {
+ display_name = "Whatever service"
+ assign where host.vars.env == "test"
+ vars.test1 = "string"
+ vars.test2 = 17
+ vars.test3 = false
+ vars.test4 = {
+ a = [ "dict", "ionary" ]
+ @this = "is"
+ }
+
+ import DirectorOverrideTemplate
+}
+
diff --git a/test/php/library/Director/Objects/rendered/service6.out b/test/php/library/Director/Objects/rendered/service6.out
new file mode 100644
index 0000000..fdca11c
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/service6.out
@@ -0,0 +1,15 @@
+apply Service for (config in host.vars.test1) {
+ name = "___TEST" + config + "___service " + host.var.bla
+ display_name = "Whatever service"
+ assign where host.vars.env == "test"
+ vars.test1 = "string"
+ vars.test2 = 17
+ vars.test3 = false
+ vars.test4 = {
+ a = [ "dict", "ionary" ]
+ @this = "is"
+ }
+
+ import DirectorOverrideTemplate
+}
+
diff --git a/test/php/library/Director/Objects/rendered/service7.out b/test/php/library/Director/Objects/rendered/service7.out
new file mode 100644
index 0000000..c125ccc
--- /dev/null
+++ b/test/php/library/Director/Objects/rendered/service7.out
@@ -0,0 +1,14 @@
+apply Service for (config in host.vars.test1) {
+ display_name = "Whatever service"
+ assign where host.vars.env == "test"
+ vars.test1 = "string"
+ vars.test2 = 17
+ vars.test3 = false
+ vars.test4 = {
+ a = [ "dict", "ionary" ]
+ @this = "is"
+ }
+
+ import DirectorOverrideTemplate
+}
+