<?php /* ** Copyright (C) 2001-2025 Zabbix SIA ** ** This program is free software: you can redistribute it and/or modify it under the terms of ** the GNU Affero General Public License as published by the Free Software Foundation, version 3. ** ** This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ** without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU Affero General Public License for more details. ** ** You should have received a copy of the GNU Affero General Public License along with this program. ** If not, see <https://www.gnu.org/licenses/>. **/ require_once dirname(__FILE__).'/../include/CIntegrationTest.php'; /** * Test suite for low level discovery (LLD). * * @required-components server * @backup items,hosts,triggers,graphs,hstgrp */ class testLowLevelDiscovery extends CIntegrationTest { const TEMPLATE_NAME_PRE = 'template'; const NUMBER_OF_TEMPLATES = 2; const DRULE_LIFETIME_DEFAULT = '1_drule_default'; const DRULE_LIFETIME_NEVER = '2_drule_never'; const DRULE_LIFETIME_DELETE = '3_drule_delete'; const DRULE_LIFETIME_DISABLE_AFTER = '4_drule_disable_after'; const DRULE_LIFETIME_DELETE_DISABLED = '5_drule_test_delete_disabled'; const HOSTNAME_LIFETIME = 'lifetime'; const LLD_DATA_MACRO = '{#DISC.ID}'; const LLD_DATA_MACRO_VALUE = '01'; private static $hostid; private static $lifetime_hostid; private static $ruleid; private static $disable_itemid; private static $disable_triggerid; private static $disable_hostid; private static $delete_disabled_itemid; private static $delete_disabled_triggerid; private static $delete_disabled_hostid; /** * @inheritdoc */ public function prepareData() { // Create hosts "discovery" and "lifetime". $response = $this->call('host.create', [ [ 'host' => 'discovery', 'interfaces' => [ [ 'type' => 1, 'main' => 1, 'useip' => 1, 'ip' => '127.0.0.1', 'dns' => '', 'port' => $this->getConfigurationValue(self::COMPONENT_AGENT, 'ListenPort') ] ], 'groups' => [ [ 'groupid' => 4 ] ] ], [ 'host' => self::HOSTNAME_LIFETIME, 'interfaces' => [ [ 'type' => 1, 'main' => 1, 'useip' => 1, 'ip' => '127.0.0.1', 'dns' => '', 'port' => $this->getConfigurationValue(self::COMPONENT_AGENT, 'ListenPort') ] ], 'groups' => [ [ 'groupid' => 4 ] ] ] ]); $this->assertCount(2, $response['result']['hostids']); self::$hostid = $response['result']['hostids'][0]; self::$lifetime_hostid = $response['result']['hostids'][1]; // Create discovery rule. $response = $this->call('discoveryrule.create', [ 'hostid' => self::$hostid, 'name' => 'Trapper discovery', 'key_' => 'item_discovery', 'type' => ITEM_TYPE_TRAPPER ]); $this->assertArrayHasKey('itemids', $response['result']); $this->assertArrayHasKey(0, $response['result']['itemids']); self::$ruleid = $response['result']['itemids'][0]; // Create item prototype. $response = $this->call('itemprototype.create', [ 'hostid' => self::$hostid, 'ruleid' => self::$ruleid, 'name' => 'Item: {#KEY}', 'key_' => 'trap[{#KEY}]', 'type' => ITEM_TYPE_TRAPPER, 'value_type' => ITEM_VALUE_TYPE_TEXT ]); $this->assertArrayHasKey('itemids', $response['result']); $this->assertArrayHasKey(0, $response['result']['itemids']); // Get discovered hosts hostgroup ID $response = $this->call('settings.get', [ 'output' => [ 'discovery_groupid' ] ]); $this->assertArrayHasKey('discovery_groupid', $response['result']); $hostgroupid = $response['result']['discovery_groupid']; // Create LLD rules with various lifetimes $this->createLowLevelDiscoveryRule(self::DRULE_LIFETIME_DEFAULT, [], $hostgroupid); $this->createLowLevelDiscoveryRule( self::DRULE_LIFETIME_NEVER, [ 'lifetime_type' => 1, 'enabled_lifetime_type' => 1 ], $hostgroupid); $this->createLowLevelDiscoveryRule(self::DRULE_LIFETIME_DELETE, ['lifetime_type' => 2], $hostgroupid); $this->createLowLevelDiscoveryRule( self::DRULE_LIFETIME_DISABLE_AFTER, [ 'lifetime_type' => 0, 'lifetime' => '2h', 'enabled_lifetime_type' => 0, 'enabled_lifetime' => '1h' ], $hostgroupid); $this->createLowLevelDiscoveryRule(self::DRULE_LIFETIME_DELETE_DISABLED, ['lifetime_type' => 2], $hostgroupid); return true; } private function createLowLevelDiscoveryRule($rule_name, $lt, $hostgroupid) { $lt['name'] = $rule_name; $lt['key_'] = $rule_name; $lt['hostid'] = self::$lifetime_hostid; $lt['type'] = ITEM_TYPE_TRAPPER; $response = $this->call('discoveryrule.create', $lt); $this->assertCount(1, $response['result']['itemids']); $ruleid = $response['result']['itemids'][0]; // Create host prototype with group prototype. $response = $this->call('hostprototype.create', [ 'ruleid' => $ruleid, 'host' => $rule_name.'_h_'.self::LLD_DATA_MACRO, 'groupLinks' => [ [ 'groupid' => $hostgroupid ] ], 'groupPrototypes' => [ [ 'name' => $rule_name.'_hg_'.self::LLD_DATA_MACRO ] ] ]); $this->assertCount(1, $response['result']['hostids']); // Create item prototype. $response = $this->call('itemprototype.create', [ 'hostid' => self::$lifetime_hostid, 'ruleid' => $ruleid, 'name' => $rule_name.'_i_'.self::LLD_DATA_MACRO, 'key_' => $rule_name.'_trap['.self::LLD_DATA_MACRO.']', 'type' => ITEM_TYPE_TRAPPER, 'value_type' => ITEM_VALUE_TYPE_UINT64 ]); $this->assertCount(1, $response['result']['itemids']); $itemprotoid = $response['result']['itemids'][0]; // Create trigger prototype. $response = $this->call('triggerprototype.create', [ 'description' => $rule_name.'_t_'.self::LLD_DATA_MACRO, 'expression' => 'last(/'.self::HOSTNAME_LIFETIME.'/'.$rule_name.'_trap['.self::LLD_DATA_MACRO.'])=1' ]); $this->assertCount(1, $response['result']['triggerids']); // Create graph prototype. $response = $this->call('graphprototype.create', [ 'name' => $rule_name.'_g_'.self::LLD_DATA_MACRO, 'width' => 900, 'height' => 200, 'gitems' => [ [ 'itemid' => $itemprotoid, 'color' => '3333FF' ] ] ]); $this->assertCount(1, $response['result']['graphids']); } /** * Test discovery by checking creation of items from item prototype. */ public function testLowLevelDiscovery_DiscoverItems() { $items = []; for ($i = 1; $i < 10; $i++) { $items[] = ['{#KEY}' => 'item'.$i]; // Send value to discovery trapper. $this->sendSenderValue('discovery', 'item_discovery', ['data' => $items]); // Retrieve data from API. $data = $this->call('item.get', [ 'hostids' => self::$hostid, 'output' => ['name', 'key_', 'type', 'value_type'], 'sortfield' => 'key_' ]); $this->assertTrue(is_array($data['result'])); $this->assertEquals($i, count($data['result'])); foreach ($data['result'] as $n => $item) { $key = 'item'.($n + 1); $this->assertEquals('Item: '.$key, $item['name']); $this->assertEquals('trap['.$key.']', $item['key_']); $this->assertEquals(ITEM_TYPE_TRAPPER, $item['type']); $this->assertEquals(ITEM_VALUE_TYPE_TEXT, $item['value_type']); } } } /** * Test discovery by checking that lost resources are deleted. * * @depends testLowLevelDiscovery_DiscoverItems */ public function testLowLevelDiscovery_LooseItems() { // Update lifetime of discovery rule. $this->call('discoveryrule.update', [ 'itemid' => self::$ruleid, 'lifetime' => 0 ]); // Reload configuration cache. $this->reloadConfigurationCache(); $key = 'item5'; // Send value to discovery trapper. $this->sendSenderValue('discovery', 'item_discovery', ['data' => [['{#KEY}' => $key]]]); // Retrieve data from API. $data = $this->call('item.get', [ 'hostids' => self::$hostid, 'output' => ['itemid', 'name', 'key_', 'type', 'value_type'], 'sortfield' => 'key_' ]); $this->assertTrue(is_array($data['result'])); $this->assertEquals(1, count($data['result'])); $item = $data['result'][0]; $this->assertEquals('Item: '.$key, $item['name']); $this->assertEquals('trap['.$key.']', $item['key_']); $this->assertEquals(ITEM_TYPE_TRAPPER, $item['type']); $this->assertEquals(ITEM_VALUE_TYPE_TEXT, $item['value_type']); // Data from API is passed as an input to testLowLevelDiscovery_CheckDiscoveredItem. return $item; } /** * Test discovery by checking that discovered item can receive data. * * @depends testLowLevelDiscovery_LooseItems */ public function testLowLevelDiscovery_CheckDiscoveredItem($item) { $from = time(); $value = md5($from.rand()).'-'.microtime(); // Send value to discovery trapper. $this->sendSenderValue('discovery', $item['key_'], $value); // Retrieve history data from API as soon it is available. $data = $this->callUntilDataIsPresent('history.get', [ 'itemids' => $item['itemid'], 'history' => ITEM_VALUE_TYPE_TEXT ]); $item = $data['result'][0]; $this->assertEquals($value, $item['value']); $this->assertGreaterThanOrEqual($from, $item['clock']); $this->assertLessThanOrEqual(time(), $item['clock']); } /** * Test discovery by checking link type in host created from host prototype. */ public function testLowLevelDiscovery_LinkTemplates() { // Create templates. $templateids = array(); for ($i = 0; $i < self::NUMBER_OF_TEMPLATES; $i++) { $response = $this->call('template.create', [ 'host' => self::TEMPLATE_NAME_PRE . "_" . $i, 'groups' => [ 'groupid' => 1 ]]); $this->assertArrayHasKey('templateids', $response['result']); $this->assertArrayHasKey(0, $response['result']['templateids']); array_push($templateids, $response['result']['templateids'][0]); } // Create host prototype $response = $this->call('hostprototype.create', [ 'host' => 'host_{#KEY}', 'groupLinks' => [ [ 'groupid' => 4 ] ], 'ruleid' => self::$ruleid, 'templates' => [ [ 'templateid' => $templateids[0] ] ] ]); $this->assertArrayHasKey('hostids', $response['result']); $this->assertArrayHasKey(0, $response['result']['hostids']); $hostprototypeid = $response['result']['hostids'][0]; $key = 'host0'; // Send value to discovery trapper. $this->sendSenderValue('discovery', 'item_discovery', ['data' => [['{#KEY}' => $key]]]); // Retrieve data from API. $response = $this->call('host.get', [ 'filter' => ['host' => 'host_'.$key], 'selectParentTemplates' => ['link_type'] ]); $this->assertArrayHasKey(0, $response['result'], json_encode($response, JSON_PRETTY_PRINT)); $this->assertArrayHasKey('host', $response['result'][0]); $discoveredhostid = $response['result'][0]['hostid']; $this->assertEquals(1, count($response['result'][0]['parentTemplates'])); foreach ($response['result'][0]['parentTemplates'] as $entry) { $this->assertEquals(1, $entry['link_type']); } // Link other templates $templates = array(); for ($i = 0; $i < self::NUMBER_OF_TEMPLATES; $i++) { array_push($templates, [ 'templateid' => $templateids[$i]]); } // Uncomment this code when API allows manual link to discovered hosts $this->call('host.update', ['hostid' => $discoveredhostid, 'templates' => $templates]); $this->call('hostprototype.update', ['hostid' => $hostprototypeid, 'templates' => $templates]); $this->reloadConfigurationCache(); // Send value to discovery trapper. $this->sendSenderValue('discovery', 'item_discovery', ['data' => [['{#KEY}' => $key]]]); // Retrieve data from API. $response = $this->call('host.get', [ 'filter' => ['host' => 'host_'.$key], 'selectParentTemplates' => ['link_type'] ]); $this->assertArrayHasKey(0, $response['result'], json_encode($response, JSON_PRETTY_PRINT)); $this->assertArrayHasKey('host', $response['result'][0]); $this->assertEquals($i, count($response['result'][0]['parentTemplates'])); foreach ($response['result'][0]['parentTemplates'] as $entry) { $this->assertEquals(1, $entry['link_type']); } $this->call('hostprototype.delete', [$hostprototypeid]); // Reload configuration cache. $this->reloadConfigurationCache(); } /** * Test discovery by checking creation of various objects. */ public function testLowLevelDiscovery_DiscoverObjects() { $lld_data[] = [self::LLD_DATA_MACRO => self::LLD_DATA_MACRO_VALUE]; $this->sendSenderValue(self::HOSTNAME_LIFETIME, self::DRULE_LIFETIME_DEFAULT, ['data' => $lld_data]); $this->sendSenderValue(self::HOSTNAME_LIFETIME, self::DRULE_LIFETIME_NEVER, ['data' => $lld_data]); $this->sendSenderValue(self::HOSTNAME_LIFETIME, self::DRULE_LIFETIME_DELETE, ['data' => $lld_data]); $this->sendSenderValue(self::HOSTNAME_LIFETIME, self::DRULE_LIFETIME_DISABLE_AFTER, ['data' => $lld_data]); $this->sendSenderValue(self::HOSTNAME_LIFETIME, self::DRULE_LIFETIME_DELETE_DISABLED, ['data' => $lld_data]); // Check items $response = $this->call('item.get', [ 'hostids' => self::$lifetime_hostid, 'output' => ['name', 'status', 'itemid'], 'sortfield' => 'name' ]); $this->assertCount(5, $response['result']); $item = $response['result'][0]; $this->assertEquals(self::DRULE_LIFETIME_DEFAULT.'_i_'.self::LLD_DATA_MACRO_VALUE, $item['name']); $this->assertEquals(ITEM_STATUS_ACTIVE, $item['status']); $item = $response['result'][1]; $this->assertEquals(self::DRULE_LIFETIME_NEVER.'_i_'.self::LLD_DATA_MACRO_VALUE, $item['name']); $this->assertEquals(ITEM_STATUS_ACTIVE, $item['status']); $item = $response['result'][2]; $this->assertEquals(self::DRULE_LIFETIME_DELETE.'_i_'.self::LLD_DATA_MACRO_VALUE, $item['name']); $this->assertEquals(ITEM_STATUS_ACTIVE, $item['status']); $item = $response['result'][3]; $this->assertEquals(self::DRULE_LIFETIME_DISABLE_AFTER.'_i_'.self::LLD_DATA_MACRO_VALUE, $item['name']); $this->assertEquals(ITEM_STATUS_ACTIVE, $item['status']); self::$disable_itemid = $item['itemid']; $item = $response['result'][4]; $this->assertEquals(self::DRULE_LIFETIME_DELETE_DISABLED.'_i_'.self::LLD_DATA_MACRO_VALUE, $item['name']); $this->assertEquals(ITEM_STATUS_ACTIVE, $item['status']); self::$delete_disabled_itemid = $item['itemid']; // Check triggers $response = $this->call('trigger.get', [ 'hostids' => self::$lifetime_hostid, 'output' => ['description', 'status'], 'sortfield' => 'description' ]); $this->assertCount(5, $response['result']); $trigger = $response['result'][0]; $this->assertEquals(self::DRULE_LIFETIME_DEFAULT.'_t_'.self::LLD_DATA_MACRO_VALUE, $trigger['description']); $this->assertEquals(TRIGGER_STATUS_ENABLED, $trigger['status']); $trigger = $response['result'][1]; $this->assertEquals(self::DRULE_LIFETIME_NEVER.'_t_'.self::LLD_DATA_MACRO_VALUE, $trigger['description']); $this->assertEquals(TRIGGER_STATUS_ENABLED, $trigger['status']); $trigger = $response['result'][2]; $this->assertEquals(self::DRULE_LIFETIME_DELETE.'_t_'.self::LLD_DATA_MACRO_VALUE, $trigger['description']); $this->assertEquals(TRIGGER_STATUS_ENABLED, $trigger['status']); $trigger = $response['result'][3]; $this->assertEquals(self::DRULE_LIFETIME_DISABLE_AFTER.'_t_'.self::LLD_DATA_MACRO_VALUE, $trigger['description']); $this->assertEquals(TRIGGER_STATUS_ENABLED, $trigger['status']); self::$disable_triggerid = $trigger['triggerid']; $trigger = $response['result'][4]; $this->assertEquals(self::DRULE_LIFETIME_DELETE_DISABLED.'_t_'.self::LLD_DATA_MACRO_VALUE, $trigger['description']); $this->assertEquals(TRIGGER_STATUS_ENABLED, $trigger['status']); self::$delete_disabled_triggerid = $trigger['triggerid']; // Check graphs $response = $this->call('graph.get', [ 'hostids' => self::$lifetime_hostid, 'output' => ['name'], 'sortfield' => 'name' ]); $this->assertCount(5, $response['result']); $graph = $response['result'][0]; $this->assertEquals(self::DRULE_LIFETIME_DEFAULT.'_g_'.self::LLD_DATA_MACRO_VALUE, $graph['name']); $graph = $response['result'][1]; $this->assertEquals(self::DRULE_LIFETIME_NEVER.'_g_'.self::LLD_DATA_MACRO_VALUE, $graph['name']); $graph = $response['result'][2]; $this->assertEquals(self::DRULE_LIFETIME_DELETE.'_g_'.self::LLD_DATA_MACRO_VALUE, $graph['name']); $graph = $response['result'][3]; $this->assertEquals(self::DRULE_LIFETIME_DISABLE_AFTER.'_g_'.self::LLD_DATA_MACRO_VALUE, $graph['name']); $graph = $response['result'][4]; $this->assertEquals(self::DRULE_LIFETIME_DELETE_DISABLED.'_g_'.self::LLD_DATA_MACRO_VALUE, $graph['name']); // Check hosts $response = $this->call('host.get', [ 'output' => ['host', 'hostid'], 'sortfield' => 'host', 'filter' => [ 'host' => [ self::DRULE_LIFETIME_DEFAULT.'_h_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_NEVER.'_h_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DELETE.'_h_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DISABLE_AFTER.'_h_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DELETE_DISABLED.'_h_'.self::LLD_DATA_MACRO_VALUE ], 'status' => HOST_STATUS_MONITORED ] ]); $this->assertCount(5, $response['result']); self::$disable_hostid = $response['result'][3]['hostid']; self::$delete_disabled_hostid = $response['result'][4]['hostid']; // Check host groups $response = $this->call('hostgroup.get', [ 'output' => ['name'], 'filter' => [ 'name' => [ self::DRULE_LIFETIME_DEFAULT.'_hg_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_NEVER.'_hg_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DELETE.'_hg_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DISABLE_AFTER.'_hg_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DELETE_DISABLED.'_hg_'.self::LLD_DATA_MACRO_VALUE ] ] ]); $this->assertCount(5, $response['result']); } /** * Test discovery lifetime by checking objects presence and status. * * @depends testLowLevelDiscovery_DiscoverObjects */ public function testLowLevelDiscovery_LooseObjects() { // Disable item, trigger and host to verify that disabled objects are deleted $response = $this->call('item.update', [ 'itemid' => self::$delete_disabled_itemid, 'status' => ITEM_STATUS_DISABLED ]); $this->assertEquals(self::$delete_disabled_itemid, $response['result']['itemids'][0]); $response = $this->call('trigger.update', [ 'triggerid' => self::$delete_disabled_triggerid, 'status' => TRIGGER_STATUS_DISABLED ]); $this->assertEquals(self::$delete_disabled_triggerid, $response['result']['triggerids'][0]); $response = $this->call('host.update', [ 'hostid' => self::$delete_disabled_hostid, 'status' => HOST_STATUS_NOT_MONITORED ]); $this->assertEquals(self::$delete_disabled_hostid, $response['result']['hostids'][0]); $this->reloadConfigurationCache(); $this->sendSenderValue(self::HOSTNAME_LIFETIME, self::DRULE_LIFETIME_DEFAULT, ['data' => []]); $this->sendSenderValue(self::HOSTNAME_LIFETIME, self::DRULE_LIFETIME_NEVER, ['data' => []]); $this->sendSenderValue(self::HOSTNAME_LIFETIME, self::DRULE_LIFETIME_DELETE, ['data' => []]); $this->sendSenderValue(self::HOSTNAME_LIFETIME, self::DRULE_LIFETIME_DISABLE_AFTER, ['data' => []]); $this->sendSenderValue(self::HOSTNAME_LIFETIME, self::DRULE_LIFETIME_DELETE_DISABLED, ['data' => []]); // Check items $response = $this->call('item.get', [ 'hostids' => self::$lifetime_hostid, 'output' => ['name', 'status'], 'sortfield' => 'name' ]); $this->assertCount(4, $response['result']); $item = $response['result'][0]; $this->assertEquals(self::DRULE_LIFETIME_DEFAULT.'_i_'.self::LLD_DATA_MACRO_VALUE, $item['name']); $this->assertEquals(ITEM_STATUS_DISABLED, $item['status']); $item = $response['result'][1]; $this->assertEquals(self::DRULE_LIFETIME_NEVER.'_i_'.self::LLD_DATA_MACRO_VALUE, $item['name']); $this->assertEquals(ITEM_STATUS_ACTIVE, $item['status']); $item = $response['result'][2]; $this->assertEquals(self::DRULE_LIFETIME_DISABLE_AFTER.'_i_'.self::LLD_DATA_MACRO_VALUE, $item['name']); $this->assertEquals(ITEM_STATUS_ACTIVE, $item['status']); $item = $response['result'][3]; $this->assertEquals(self::DRULE_LIFETIME_DELETE_DISABLED.'_i_'.self::LLD_DATA_MACRO_VALUE, $item['name']); $this->assertEquals(ITEM_STATUS_DISABLED, $item['status']); // Check triggers (deleted due to item deletion) $response = $this->call('trigger.get', [ 'hostids' => self::$lifetime_hostid, 'output' => ['description', 'status'], 'sortfield' => 'description' ]); $this->assertCount(4, $response['result']); $trigger = $response['result'][0]; $this->assertEquals(self::DRULE_LIFETIME_DEFAULT.'_t_'.self::LLD_DATA_MACRO_VALUE, $trigger['description']); $this->assertEquals(TRIGGER_STATUS_DISABLED, $trigger['status']); $trigger = $response['result'][1]; $this->assertEquals(self::DRULE_LIFETIME_NEVER.'_t_'.self::LLD_DATA_MACRO_VALUE, $trigger['description']); $this->assertEquals(TRIGGER_STATUS_ENABLED, $trigger['status']); $trigger = $response['result'][2]; $this->assertEquals(self::DRULE_LIFETIME_DISABLE_AFTER.'_t_'.self::LLD_DATA_MACRO_VALUE, $trigger['description']); $this->assertEquals(TRIGGER_STATUS_ENABLED, $trigger['status']); $trigger = $response['result'][3]; $this->assertEquals(self::DRULE_LIFETIME_DELETE_DISABLED.'_t_'.self::LLD_DATA_MACRO_VALUE, $trigger['description']); $this->assertEquals(TRIGGER_STATUS_DISABLED, $trigger['status']); // Check graphs (deleted due to item deletion) $response = $this->call('graph.get', [ 'hostids' => self::$lifetime_hostid, 'output' => ['name'], 'sortfield' => 'name' ]); $this->assertCount(3, $response['result']); $graph = $response['result'][0]; $this->assertEquals(self::DRULE_LIFETIME_DEFAULT.'_g_'.self::LLD_DATA_MACRO_VALUE, $graph['name']); $graph = $response['result'][1]; $this->assertEquals(self::DRULE_LIFETIME_NEVER.'_g_'.self::LLD_DATA_MACRO_VALUE, $graph['name']); $graph = $response['result'][2]; $this->assertEquals(self::DRULE_LIFETIME_DISABLE_AFTER.'_g_'.self::LLD_DATA_MACRO_VALUE, $graph['name']); // Check hosts $response = $this->call('host.get', [ 'output' => ['host', 'status'], 'sortfield' => 'host', 'filter' => [ 'host' => [ self::DRULE_LIFETIME_DEFAULT.'_h_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_NEVER.'_h_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DELETE.'_h_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DISABLE_AFTER.'_h_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DELETE_DISABLED.'_h_'.self::LLD_DATA_MACRO_VALUE ] ] ]); $this->assertCount(4, $response['result']); $host = $response['result'][0]; $this->assertEquals(self::DRULE_LIFETIME_DEFAULT.'_h_'.self::LLD_DATA_MACRO_VALUE, $host['host']); $this->assertEquals(HOST_STATUS_NOT_MONITORED, $host['status']); $host = $response['result'][1]; $this->assertEquals(self::DRULE_LIFETIME_NEVER.'_h_'.self::LLD_DATA_MACRO_VALUE, $host['host']); $this->assertEquals(HOST_STATUS_MONITORED, $host['status']); $host = $response['result'][2]; $this->assertEquals(self::DRULE_LIFETIME_DISABLE_AFTER.'_h_'.self::LLD_DATA_MACRO_VALUE, $host['host']); $this->assertEquals(HOST_STATUS_MONITORED, $host['status']); $host = $response['result'][3]; $this->assertEquals(self::DRULE_LIFETIME_DELETE_DISABLED.'_h_'.self::LLD_DATA_MACRO_VALUE, $host['host']); $this->assertEquals(HOST_STATUS_NOT_MONITORED, $host['status']); // Check host groups $response = $this->call('hostgroup.get', [ 'output' => ['name'], 'sortfield' => 'name', 'filter' => [ 'name' => [ self::DRULE_LIFETIME_DEFAULT.'_hg_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_NEVER.'_hg_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DELETE.'_hg_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DISABLE_AFTER.'_hg_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DELETE_DISABLED.'_hg_'.self::LLD_DATA_MACRO_VALUE ] ] ]); $this->assertCount(3, $response['result']); $hostgroup = $response['result'][0]; $this->assertEquals(self::DRULE_LIFETIME_DEFAULT.'_hg_'.self::LLD_DATA_MACRO_VALUE, $hostgroup['name']); $hostgroup = $response['result'][1]; $this->assertEquals(self::DRULE_LIFETIME_NEVER.'_hg_'.self::LLD_DATA_MACRO_VALUE, $hostgroup['name']); $hostgroup = $response['result'][2]; $this->assertEquals(self::DRULE_LIFETIME_DISABLE_AFTER.'_hg_'.self::LLD_DATA_MACRO_VALUE, $hostgroup['name']); } /** * Test re-discovery by checking object status. * * @depends testLowLevelDiscovery_LooseObjects */ public function testLowLevelDiscovery_RediscoverObjects() { // Disable item, trigger and host $response = $this->call('item.update', [ 'itemid' => self::$disable_itemid, 'status' => ITEM_STATUS_DISABLED ]); $this->assertEquals(self::$disable_itemid, $response['result']['itemids'][0]); $response = $this->call('trigger.update', [ 'triggerid' => self::$disable_triggerid, 'status' => TRIGGER_STATUS_DISABLED ]); $this->assertEquals(self::$disable_triggerid, $response['result']['triggerids'][0]); $response = $this->call('host.update', [ 'hostid' => self::$disable_hostid, 'status' => HOST_STATUS_NOT_MONITORED ]); $this->assertEquals(self::$disable_hostid, $response['result']['hostids'][0]); $this->reloadConfigurationCache(); $lld_data[] = [self::LLD_DATA_MACRO => self::LLD_DATA_MACRO_VALUE]; $this->sendSenderValue(self::HOSTNAME_LIFETIME, self::DRULE_LIFETIME_DEFAULT, ['data' => $lld_data]); $this->sendSenderValue(self::HOSTNAME_LIFETIME, self::DRULE_LIFETIME_DISABLE_AFTER, ['data' => $lld_data]); // Check items $response = $this->call('item.get', [ 'hostids' => self::$lifetime_hostid, 'output' => ['name', 'status'], 'sortfield' => 'name', 'filter' => [ 'name' => [ self::DRULE_LIFETIME_DEFAULT.'_i_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DISABLE_AFTER.'_i_'.self::LLD_DATA_MACRO_VALUE ] ] ]); $this->assertCount(2, $response['result']); $item = $response['result'][0]; $this->assertEquals(self::DRULE_LIFETIME_DEFAULT.'_i_'.self::LLD_DATA_MACRO_VALUE, $item['name']); $this->assertEquals(ITEM_STATUS_ACTIVE, $item['status']); $item = $response['result'][1]; $this->assertEquals(self::DRULE_LIFETIME_DISABLE_AFTER.'_i_'.self::LLD_DATA_MACRO_VALUE, $item['name']); $this->assertEquals(ITEM_STATUS_DISABLED, $item['status']); // Check triggers (deleted due to item deletion) $response = $this->call('trigger.get', [ 'hostids' => self::$lifetime_hostid, 'output' => ['description', 'status'], 'sortfield' => 'description', 'filter' => [ 'description' => [ self::DRULE_LIFETIME_DEFAULT.'_t_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DISABLE_AFTER.'_t_'.self::LLD_DATA_MACRO_VALUE ] ] ]); $this->assertCount(2, $response['result']); $trigger = $response['result'][0]; $this->assertEquals(self::DRULE_LIFETIME_DEFAULT.'_t_'.self::LLD_DATA_MACRO_VALUE, $trigger['description']); $this->assertEquals(TRIGGER_STATUS_ENABLED, $trigger['status']); $trigger = $response['result'][1]; $this->assertEquals(self::DRULE_LIFETIME_DISABLE_AFTER.'_t_'.self::LLD_DATA_MACRO_VALUE, $trigger['description']); $this->assertEquals(TRIGGER_STATUS_DISABLED, $trigger['status']); // Check hosts $response = $this->call('host.get', [ 'output' => ['host', 'status'], 'sortfield' => 'host', 'filter' => [ 'host' => [ self::DRULE_LIFETIME_DEFAULT.'_h_'.self::LLD_DATA_MACRO_VALUE, self::DRULE_LIFETIME_DISABLE_AFTER.'_h_'.self::LLD_DATA_MACRO_VALUE ] ] ]); $this->assertCount(2, $response['result']); $host = $response['result'][0]; $this->assertEquals(self::DRULE_LIFETIME_DEFAULT.'_h_'.self::LLD_DATA_MACRO_VALUE, $host['host']); $this->assertEquals(HOST_STATUS_MONITORED, $host['status']); $host = $response['result'][1]; $this->assertEquals(self::DRULE_LIFETIME_DISABLE_AFTER.'_h_'.self::LLD_DATA_MACRO_VALUE, $host['host']); $this->assertEquals(HOST_STATUS_NOT_MONITORED, $host['status']); } }