diff options
Diffstat (limited to '')
-rw-r--r-- | test/php/library/Director/Objects/HostGroupMembershipResolverTest.php | 353 |
1 files changed, 353 insertions, 0 deletions
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'); + } +} |