null, 'hostgroupid' => null, 'hostids' => [ 'monitored' => null, 'not_monitored' => null, 'template' => null ], 'itemids' => [ 'not_exists' => '01' ] ]; private static $clear_taskids = []; public function prepareItemsData() { // Create template group. $templategroups = CDataHelper::call('templategroup.create', [ [ 'name' => 'API test task.create' ] ]); $this->assertArrayHasKey('groupids', $templategroups); self::$data['templategroupid'] = $templategroups['groupids'][0]; // Create host group. $hostgroups = CDataHelper::call('hostgroup.create', [ [ 'name' => 'API test task.create' ] ]); $this->assertArrayHasKey('groupids', $hostgroups); self::$data['hostgroupid'] = $hostgroups['groupids'][0]; // Create monitored host and not monitored host. $hosts_data = [ [ 'host' => 'api_test_task_create_monitored', 'name' => 'API test task.create monitored', 'groups' => [ [ 'groupid' => self::$data['hostgroupid'] ] ] ], [ 'host' => 'api_test_task_create_not_monitored', 'name' => 'API test task.create not monitored', 'groups' => [ [ 'groupid' => self::$data['hostgroupid'] ] ], 'status' => HOST_STATUS_NOT_MONITORED ] ]; $hosts = CDataHelper::call('host.create', $hosts_data); $this->assertArrayHasKey('hostids', $hosts); self::$data['hostids'] = [ 'monitored' => $hosts['hostids'][0], 'not_monitored' => $hosts['hostids'][1] ]; // Create host interfaces separately. $interfaces_data = [ [ 'hostid' => self::$data['hostids']['monitored'], 'type' => INTERFACE_TYPE_AGENT, 'main' => INTERFACE_PRIMARY, 'useip' => INTERFACE_USE_IP, 'ip' => '192.168.3.1', 'dns' => '', 'port' => '10050' ], [ 'hostid' => self::$data['hostids']['not_monitored'], 'type' => INTERFACE_TYPE_AGENT, 'main' => INTERFACE_PRIMARY, 'useip' => INTERFACE_USE_IP, 'ip' => '192.168.3.2', 'dns' => '', 'port' => '10060' ] ]; $interfaces = CDataHelper::call('hostinterface.create', $interfaces_data); $this->assertArrayHasKey('interfaceids', $interfaces); $interfaceid_monitored = $interfaces['interfaceids'][0]; $interfaceid_not_monitored = $interfaces['interfaceids'][1]; // Create template. $templates_data = [[ 'host' => 'api_test_task_create_template', 'name' => 'API test task.create template', 'groups' => [ [ 'groupid' => self::$data['templategroupid'] ] ] ]]; $templates = CDataHelper::call('template.create', $templates_data); $this->assertArrayHasKey('templateids', $templates); self::$data['hostids']['template'] = $templates['templateids'][0]; // Create top level master items. $items_data = [ // Host is monitored, item is monitored and is of allowed type. [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '1 Item (1/1/1)', 'key_' => '1_item_111', 'type' => ITEM_TYPE_ZABBIX, 'value_type' => ITEM_VALUE_TYPE_FLOAT, 'delay' => '30', 'interfaceid' => $interfaceid_monitored ], [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '2 Item (1/1/1)', 'key_' => '2_item_111', 'type' => ITEM_TYPE_ZABBIX, 'value_type' => ITEM_VALUE_TYPE_FLOAT, 'delay' => '30', 'interfaceid' => $interfaceid_monitored ], // Host is monitored, item is not monitored, but is of allowed type. [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '3 Item (1/0/1)', 'key_' => '3_item_101', 'type' => ITEM_TYPE_ZABBIX, 'value_type' => ITEM_VALUE_TYPE_FLOAT, 'delay' => '30', 'interfaceid' => $interfaceid_monitored, 'status' => ITEM_STATUS_DISABLED ], // Host is monitored, item is monitored, but type is not allowed. [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '4 Item (1/1/0)', 'key_' => '4_item_110', 'type' => ITEM_TYPE_TRAPPER, 'value_type' => ITEM_VALUE_TYPE_FLOAT ], // Host is not monitored, item is monitored and is of allowed type. [ 'hostid' => self::$data['hostids']['not_monitored'], 'name' => '5 Item (0/1/1)', 'key_' => '5_item_011', 'type' => ITEM_TYPE_ZABBIX, 'value_type' => ITEM_VALUE_TYPE_FLOAT, 'delay' => '30', 'interfaceid' => $interfaceid_not_monitored ], // Host is template, item is monitored and is of allowed type. [ 'hostid' => self::$data['hostids']['template'], 'name' => '6 Item-T (0/1/1)', 'key_' => '6_item_t_011', 'type' => ITEM_TYPE_ZABBIX, 'value_type' => ITEM_VALUE_TYPE_FLOAT, 'delay' => '30' ] ]; $items = CDataHelper::call('item.create', $items_data); self::$data['itemids'] += [ '1_item_111' => $items['itemids'][0], '2_item_111' => $items['itemids'][1], '3_item_101' => $items['itemids'][2], '4_item_110' => $items['itemids'][3], '5_item_011' => $items['itemids'][4], '6_item_t_011' => $items['itemids'][5] ]; // Create dependent items. $items_data = [ // Host is monitored, item is monitored and is of allowed type. [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '1.1 Item (1/1/1)', 'key_' => '1_1_item_111', 'type' => ITEM_TYPE_DEPENDENT, 'value_type' => ITEM_VALUE_TYPE_FLOAT, 'master_itemid' => self::$data['itemids']['1_item_111'] ], // Host is monitored, item is monitored and is of allowed type (same as previous). [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '1.2 Item (1/1/1)', 'key_' => '1_2_item_111', 'type' => ITEM_TYPE_DEPENDENT, 'value_type' => ITEM_VALUE_TYPE_FLOAT, 'master_itemid' => self::$data['itemids']['1_item_111'] ], // Host is monitored, item is monitored and is of allowed type (but master item is not monitored). [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '3.1 Item (1/1/1)', 'key_' => '3_1_item_111', 'type' => ITEM_TYPE_DEPENDENT, 'value_type' => ITEM_VALUE_TYPE_FLOAT, 'master_itemid' => self::$data['itemids']['3_item_101'] ], // Host is monitored, item is monitored and is of allowed type (but master item is not of allowed type). [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '4.1 Item (1/1/1)', 'key_' => '4_1_item_111', 'type' => ITEM_TYPE_DEPENDENT, 'value_type' => ITEM_VALUE_TYPE_FLOAT, 'master_itemid' => self::$data['itemids']['4_item_110'] ] ]; $items = CDataHelper::call('item.create', $items_data); self::$data['itemids'] += [ '1_1_item_111' => $items['itemids'][0], '1_2_item_111' => $items['itemids'][1], '3_1_item_111' => $items['itemids'][2], '4_1_item_111' => $items['itemids'][3] ]; // Level 3 item that depends on another dependent item. $items_data = [ [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '1.2.1 Item (1/1/1)', 'key_' => '1_2_1_item_111', 'type' => ITEM_TYPE_DEPENDENT, 'value_type' => ITEM_VALUE_TYPE_FLOAT, 'master_itemid' => self::$data['itemids']['1_2_item_111'] ] ]; $items = CDataHelper::call('item.create', $items_data); self::$data['itemids'] += [ '1_2_1_item_111' => $items['itemids'][0] ]; // Create top level LLD rules. $discovery_rules_data = [ // Host is monitored, LLD rule is monitored and is of allowed type. [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '1 LLD (1/1/1)', 'key_' => '1_lld_111', 'type' => ITEM_TYPE_ZABBIX, 'delay' => '30', 'interfaceid' => $interfaceid_monitored ], // Host is monitored, LLD rule is not monitored, but is of allowed type. [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '2 LLD (1/0/1)', 'key_' => '2_lld_101', 'type' => ITEM_TYPE_ZABBIX, 'delay' => '30', 'interfaceid' => $interfaceid_monitored, 'status' => ITEM_STATUS_DISABLED ], // Host is monitored, LLD rule is monitored, but type is not allowed. [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '3 LLD (1/1/0)', 'key_' => '3_lld_110', 'type' => ITEM_TYPE_TRAPPER ], // Host is not monitored, LLD rule is monitored and is of allowed type. [ 'hostid' => self::$data['hostids']['not_monitored'], 'name' => '4 LLD (0/1/1)', 'key_' => '4_lld_011', 'type' => ITEM_TYPE_ZABBIX, 'delay' => '30', 'interfaceid' => $interfaceid_not_monitored ], // Host is template, LLD rule is monitored and is of allowed type. [ 'hostid' => self::$data['hostids']['template'], 'name' => '5 LLD-T (0/1/1)', 'key_' => '5_lld_t_011', 'type' => ITEM_TYPE_ZABBIX, 'delay' => '30' ] ]; $discovery_rules = CDataHelper::call('discoveryrule.create', $discovery_rules_data); self::$data['itemids'] += [ '1_lld_111' => $discovery_rules['itemids'][0], '2_lld_101' => $discovery_rules['itemids'][1], '3_lld_110' => $discovery_rules['itemids'][2], '4_lld_011' => $discovery_rules['itemids'][3], '5_lld_t_011' => $discovery_rules['itemids'][4] ]; // Create dependent LLD rules (they depend on other items). $discovery_rules_data = [ // Host is monitored, LLD rule is monitored and is of allowed type. [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '1.3 LLD (1/1/1)', 'key_' => '1_3_lld_111', 'type' => ITEM_TYPE_DEPENDENT, 'master_itemid' => self::$data['itemids']['1_item_111'] ], // Host is monitored, LLD rule is monitored and is of allowed type (but master item is not monitored). [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '3.2 LLD (1/1/1)', 'key_' => '3_2_lld_111', 'type' => ITEM_TYPE_DEPENDENT, 'master_itemid' => self::$data['itemids']['3_item_101'] ], // Host is monitored, LLD rule is monitored and is of allowed type (but master item is not of allowed type). [ 'hostid' => self::$data['hostids']['monitored'], 'name' => '4.2 LLD (1/1/1)', 'key_' => '4_2_lld_111', 'type' => ITEM_TYPE_DEPENDENT, 'master_itemid' => self::$data['itemids']['4_item_110'] ] ]; $discovery_rules = CDataHelper::call('discoveryrule.create', $discovery_rules_data); self::$data['itemids'] += [ '1_3_lld_111' => $discovery_rules['itemids'][0], '3_2_lld_111' => $discovery_rules['itemids'][1], '4_2_lld_111' => $discovery_rules['itemids'][2] ]; } /** * Data provider for valid items and LLD rules. * * @return array */ public static function getItemAndLLDDataValid() { return [ // One basic item and LLD rule. 'Test one master item' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_item_111' ] ], 'expected_results' => [ ['itemid' => '1_item_111'] ], 'expected_error' => null ], 'Test one master LLD rule' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_lld_111' ] ], 'expected_results' => [ ['itemid' => '1_lld_111'] ], 'expected_error' => null ], // Mix master items and LLD rules together. 'Test LLD rule and item' => [ 'task' => [ [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_lld_111' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_item_111' ] ] ], 'expected_results' => [ ['itemid' => '1_lld_111'], ['itemid' => '1_item_111'] ], 'expected_error' => null ], // Check dependent items and LLD rules. 'Test one dependent item' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_1_item_111' ] ], 'expected_results' => [ ['itemid' => '1_item_111'] ], 'expected_error' => null ], 'Test two dependent items and dependent LLD rule' => [ 'task' => [ [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_2_item_111' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_1_item_111' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_3_lld_111' ] ] ], 'expected_results' => [ ['itemid' => '1_item_111'], ['itemid' => '1_item_111'], ['itemid' => '1_item_111'] ], 'expected_error' => null ], 'Test dependent item and master item together' => [ 'task' => [ [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_1_item_111' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_item_111' ] ] ], 'expected_results' => [ ['itemid' => '1_item_111'], ['itemid' => '1_item_111'] ], 'expected_error' => null ], 'Test dependent item lvl3 and dependent item lvl2 of same branch' => [ 'task' => [ [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_2_item_111' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_2_1_item_111' ] ] ], 'expected_results' => [ ['itemid' => '1_item_111'], ['itemid' => '1_item_111'] ], 'expected_error' => null ], 'Test dependent item lvl3 and master item of different branch' => [ 'task' => [ [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_2_1_item_111' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '2_item_111' ] ] ], 'expected_results' => [ ['itemid' => '1_item_111'], ['itemid' => '2_item_111'] ], 'expected_error' => null ], // Check diagnostic info. 'Test diagnostic info separately' => [ 'task' => [ [ 'type' => ZBX_TM_DATA_TYPE_DIAGINFO, 'request' => [ 'alerting' => [ 'stats' => [ 'alerts' ] ] ] ] ], 'expected_results' => [ [ 'info' => json_encode([ 'alerting' => [ 'stats' => [ 'alerts' ] ] ]) ] ], 'expected_error' => null ], 'Test check now and diagnostic info (repeating)' => [ 'task' => [ [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '2_item_111' ] ], [ 'type' => ZBX_TM_DATA_TYPE_DIAGINFO, 'request' => [ 'alerting' => [ 'stats' => [ 'alerts' ] ] ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_2_item_111' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '2_item_111' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_2_1_item_111' ] ] ], 'expected_results' => [ ['2_item_111'], [ 'info' => json_encode([ 'alerting' => [ 'stats' => [ 'alerts' ] ] ]) ], ['1_item_111'], ['2_item_111'], ['1_item_111'] ], 'expected_error' => null ] ]; } /** * Data provider for testing the created tasks twice. * * @return array */ public static function getItemExistingDataValid() { return [ 'Test check now and diagnostic info (first)' => [ 'task' => [ [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '2_item_111' ] ], [ 'type' => ZBX_TM_DATA_TYPE_DIAGINFO, 'request' => [ 'alerting' => [ 'stats' => [ 'alerts' ] ] ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_2_item_111' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '2_item_111' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_2_1_item_111' ] ] ], 'expected_results' => [ ['2_item_111'], [ 'info' => json_encode([ 'alerting' => [ 'stats' => [ 'alerts' ] ] ]) ], ['1_item_111'], ['2_item_111'], ['1_item_111'] ], 'expected_error' => null ], 'Test check now and diagnostic info (second)' => [ 'task' => [ [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '2_item_111' ] ], [ 'type' => ZBX_TM_DATA_TYPE_DIAGINFO, 'request' => [ 'alerting' => [ 'stats' => [ 'alerts' ] ] ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_2_item_111' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '2_item_111' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_2_1_item_111' ] ] ], 'expected_results' => [ ['2_item_111'], [ 'info' => json_encode([ 'alerting' => [ 'stats' => [ 'alerts' ] ] ]) ], ['1_item_111'], ['2_item_111'], ['1_item_111'] ], 'expected_error' => null ] ]; } /** * Data provider for common errors like missing fields, invalid fields, empty fields etc. * * @return array */ public static function getItemAndLLDDataCommonInvalid() { // Valid and existing item ID. $itemid = '1_item_111'; return [ // Check required fields. 'Test empty parameters' => [ 'tasks' => [], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/": cannot be empty.' ], 'Test unexpected parameters' => [ 'tasks' => [ 'type' => '6', 'request' => [ 'itemid' => $itemid ], 'flag' => true ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1": unexpected parameter "flag".' ], 'Test missing request' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1": the parameter "request" is missing.' ], // Check "type" field. 'Test missing type' => [ 'task' => [ 'request' => [ 'itemid' => $itemid ] ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1": the parameter "type" is missing.' ], 'Test invalid type (empty)' => [ 'task' => [ 'type' => '', 'request' => [ 'itemid' => $itemid ] ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1/type": an integer is expected.' ], 'Test invalid type (string)' => [ 'task' => [ 'type' => 'æų', 'request' => [ 'itemid' => $itemid ] ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1/type": an integer is expected.' ], 'Test invalid type (value)' => [ 'task' => [ 'type' => '3', 'request' => [ 'itemid' => $itemid ] ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1/type": value must be one of '.(implode(', ', [ ZBX_TM_DATA_TYPE_DIAGINFO, ZBX_TM_DATA_TYPE_PROXYIDS, ZBX_TM_TASK_CHECK_NOW ])).'.' ], // Check "itemid" field. 'Test missing itemid' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [] ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1/request": the parameter "itemid" is missing.' ], 'Test invalid itemid (empty)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '' ] ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1/request/itemid": a number is expected.' ], 'Test invalid itemid (array)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => [''] ] ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1/request/itemid": a number is expected.' ], // Check invalid diagnostic info. 'Test invalid diagnostic info (invalid parent field)' => [ 'task' => [ [ 'type' => ZBX_TM_DATA_TYPE_DIAGINFO, 'request' => [ 'random_field' => [ 'stats' => [ 'alerts' ], 'top' => [ 'media.alerts' => 10 ] ] ] ] ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1/request": unexpected parameter "random_field".' ], 'Test invalid diagnostic info (invalid child field)' => [ 'task' => [ [ 'type' => ZBX_TM_DATA_TYPE_DIAGINFO, 'request' => [ 'alerting' => [ 'random_field' => [ 'alerts' ] ] ] ] ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1/request/alerting": unexpected parameter "random_field".' ], 'Test invalid diagnostic info (invalid stats value)' => [ 'task' => [ [ 'type' => ZBX_TM_DATA_TYPE_DIAGINFO, 'request' => [ 'alerting' => [ 'stats' => [ 'some_value' ] ] ] ] ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1/request/alerting/stats/1": value must be "alerts".' ], 'Test invalid diagnostic info (invalid media.alerts value)' => [ 'task' => [ [ 'type' => ZBX_TM_DATA_TYPE_DIAGINFO, 'request' => [ 'alerting' => [ 'stats' => [ 'alerts' ], 'top' => [ 'media.alerts' => 'abc' ] ] ] ] ], 'expected_results' => [], 'expected_error' => 'Invalid parameter "/1/request/alerting/top/media.alerts": an integer is expected.' ], 'Test invalid diagnostic info (proxy does not exist)' => [ 'task' => [ [ 'type' => ZBX_TM_DATA_TYPE_DIAGINFO, 'request' => [ 'alerting' => [ 'stats' => [ 'alerts' ], 'top' => [ 'media.alerts' => 10 ] ], 'lld' => [ 'stats' => 'extend', 'top' => [ 'values' => 5 ] ] ], 'proxyid' => '01' ] ], 'expected_results' => [], 'expected_error' => 'No permissions to referred object or it does not exist!' ] ]; } /** * Data provider for invalid items and LLD rules. * * @return array */ public static function getItemAndLLDDataInvalid() { return [ // Test non-existent items. 'Test one invalid item' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => 'not_exists' ] ], 'expected_results' => [], 'expected_error' => 'No permissions to referred object or it does not exist!' ], 'Test one valid and one invalid item' => [ 'task' => [ [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => 'not_exists' ] ], [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '1_item_111' ] ] ], 'expected_results' => [], 'expected_error' => 'No permissions to referred object or it does not exist!' ], // Test master items and LLD rules. 'Test item (not monitored)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '3_item_101' ] ], 'expected_results' => [], 'expected_error' => 'Cannot send request: item "3 Item (1/0/1)" on host "API test task.create monitored" is not monitored.' ], 'Test item (type not allowed)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '4_item_110' ] ], 'expected_results' => [], 'expected_error' => 'Cannot send request: wrong item type.' ], 'Test item (host not monitored)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '5_item_011' ] ], 'expected_results' => [], 'expected_error' => 'Cannot send request: item "5 Item (0/1/1)" on host "API test task.create not monitored" is not monitored.' ], 'Test item (host is template)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '6_item_t_011' ] ], 'expected_results' => [], 'expected_error' => 'Cannot send request: item "6 Item-T (0/1/1)" on host "API test task.create template" is not monitored.' ], 'Test LLD rule (not monitored)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '2_lld_101' ] ], 'expected_results' => [], 'expected_error' => 'Cannot send request: discovery rule "2 LLD (1/0/1)" on host "API test task.create monitored" is not monitored.' ], 'Test LLD rule (type not allowed)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '3_lld_110' ] ], 'expected_results' => [], 'expected_error' => 'Cannot send request: wrong discovery rule type.' ], 'Test LLD rule (host not monitored)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '4_lld_011' ] ], 'expected_results' => [], 'expected_error' => 'Cannot send request: discovery rule "4 LLD (0/1/1)" on host "API test task.create not monitored" is not monitored.' ], 'Test LLD rule (host is template)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '5_lld_t_011' ] ], 'expected_results' => [], 'expected_error' => 'Cannot send request: discovery rule "5 LLD-T (0/1/1)" on host "API test task.create template" is not monitored.' ], // Test dependent items and LLD rules. 'Test dependent item (master item is not monitored)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '3_1_item_111' ] ], 'expected_results' => [], 'expected_error' => 'Cannot send request: item "3 Item (1/0/1)" on host "API test task.create monitored" is not monitored.' ], 'Test dependent item (master item type is allowed)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '4_1_item_111' ] ], 'expected_results' => [], 'expected_error' => 'Cannot send request: wrong master item type.' ], 'Test dependent LLD rule (master item is not monitored)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '3_2_lld_111' ] ], 'expected_results' => [], 'expected_error' => 'Cannot send request: item "3 Item (1/0/1)" on host "API test task.create monitored" is not monitored.' ], 'Test dependent LLD rule (master item type is allowed)' => [ 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => '4_2_lld_111' ] ], 'expected_results' => [], 'expected_error' => 'Cannot send request: wrong master item type.' ] ]; } /** * Test valid items, valid LLD rules, invalid items, invalid LLD rules and common errors like missing fields etc. * * @dataProvider getItemAndLLDDataValid * @dataProvider getItemAndLLDDataCommonInvalid * @dataProvider getItemAndLLDDataInvalid */ public function testTaskCreate_new($tasks, $expected_results, $expected_error) { // Accept single and multiple tasks. if (!array_key_exists(0, $tasks)) { $tasks = zbx_toArray($tasks); } // Replace ID placeholders with real IDs for "check now" tasks. foreach ($tasks as &$task) { // Some tests that should fail may not have the required fields or they may be damaged. if (array_key_exists('type', $task) && $task['type'] == ZBX_TM_TASK_CHECK_NOW && array_key_exists('request', $task) && array_key_exists('itemid', $task['request']) && !is_array($task['request']['itemid']) && $task['request']['itemid'] !== '') { $task['request']['itemid'] = self::$data['itemids'][$task['request']['itemid']]; } } unset($task); $sql_check_now_tasks = 'SELECT NULL FROM task_check_now'; $old_hash_check_now_tasks = CDBHelper::getHash($sql_check_now_tasks); $sql_diag_info_task = "select NULL from task_data"; $old_hash_diag_info_tasks = CDBHelper::getHash($sql_diag_info_task); $result = $this->call('task.create', $tasks, $expected_error); if ($expected_error === null) { $check_now = false; $diag_info = false; foreach ($expected_results as $expected_result) { if (array_key_exists('itemid', $expected_result)) { $check_now = true; } if (array_key_exists('info', $expected_result)) { $diag_info = true; } } // Check that changes were made in corresponding tables. if ($check_now) { $this->assertNotSame($old_hash_check_now_tasks, CDBHelper::getHash($sql_check_now_tasks)); } if ($diag_info) { $this->assertNotSame($old_hash_diag_info_tasks, CDBHelper::getHash($sql_diag_info_task)); } // Check the count of expected results. Input item count should match the output task ID count. $this->assertEquals(count($result['result']['taskids']), count($tasks)); foreach ($expected_results as $index => $expected_result) { $taskid = $result['result']['taskids'][$index]; if (array_key_exists('itemid', $expected_result)) { $itemid = self::$data['itemids'][$expected_result['itemid']]; $task_db = CDBHelper::getValue( 'SELECT tcn.itemid'. ' FROM task_check_now tcn'. ' WHERE '.dbConditionId('tcn.taskid', [$taskid]) ); $this->assertSame($itemid, $task_db); } if (array_key_exists('info', $expected_result)) { $task_db = CDBHelper::getValue( 'SELECT td.data'. ' FROM task_data td'. ' WHERE '.dbConditionId('td.taskid', [$taskid]) ); $this->assertSame($expected_result['info'], $task_db); } } // Clear tasks because same items are used multiple times so that hash checking works correctly. DBexecute('DELETE FROM task WHERE '.dbConditionId('taskid', $result['result']['taskids'])); } else { // Check if no changes were made to DB in any of the corresponding tables. $this->assertSame($old_hash_check_now_tasks, CDBHelper::getHash($sql_check_now_tasks)); $this->assertSame($old_hash_diag_info_tasks, CDBHelper::getHash($sql_diag_info_task)); } } /** * Test valid items and create tasks for them. Then create same tasks again for same items and expect task IDs to be * the same. No new records should be added in for "check now". However diagnostic info does not have that check in * API and will create new record for diagnostic info tasks. Those task IDs are collected and then removed * when data is cleared. * * @dataProvider getItemExistingDataValid */ public function testTaskCreate_existing($tasks, $expected_results, $expected_error) { // Accept single and multiple tasks. if (!array_key_exists(0, $tasks)) { $tasks = zbx_toArray($tasks); } // Replace ID placeholders with real IDs for "check now" tasks. foreach ($tasks as &$task) { if ($task['type'] == ZBX_TM_TASK_CHECK_NOW) { $task['request']['itemid'] = self::$data['itemids'][$task['request']['itemid']]; } } unset($task); $sql_check_now_tasks = 'SELECT NULL FROM task_check_now'; $old_hash_check_now_tasks = CDBHelper::getHash($sql_check_now_tasks); $sql_diag_info_task = "select NULL from task_data"; $old_hash_diag_info_tasks = CDBHelper::getHash($sql_diag_info_task); $result = $this->call('task.create', $tasks, $expected_error); // Check the count of expected results. Input item count should match the output task ID count. $this->assertEquals(count($result['result']['taskids']), count($tasks)); foreach ($expected_results as $index => $expected_result) { $taskid = $result['result']['taskids'][$index]; if (array_key_exists('itemid', $expected_result)) { $itemid = self::$data['itemids'][$expected_result['itemid']]; $task_db = CDBHelper::getValue( 'SELECT tcn.itemid'. ' FROM task_check_now tcn'. ' WHERE '.dbConditionId('tcn.taskid', [$taskid]) ); $this->assertSame($itemid, $task_db); if ($index == 0) { // On first iteration task records are created. $this->assertNotSame($old_hash_check_now_tasks, CDBHelper::getHash($sql_check_now_tasks)); } else { // On second iteration task records are the same, because same items were passed. $this->assertSame($old_hash_check_now_tasks, CDBHelper::getHash($sql_check_now_tasks)); } } if (array_key_exists('info', $expected_result)) { $task_db = CDBHelper::getValue( 'SELECT td.data'. ' FROM task_data td'. ' WHERE '.dbConditionId('td.taskid', [$taskid]) ); $this->assertSame($expected_result['info'], $task_db); // For diagnostic info tasks, each time new records are created. $this->assertNotSame($old_hash_diag_info_tasks, CDBHelper::getHash($sql_diag_info_task)); // Collect diagnostic info task IDs because these are not automatically deleted. self::$clear_taskids[$taskid] = true; } } } /** * Data provider for testing permissions. Method task.create externally can only be called by super admins. * * @return array */ public static function getDataPermissions() { // Valid and existing item ID (host monitored, item monitored and type allowed). $itemid = '1_item_111'; return [ // Test check now. 'Test check now (admin)' => [ 'user' => ['user' => 'zabbix-admin', 'password' => 'zabbix'], 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => $itemid ] ], 'expected_error' => 'No permissions to call "task.create".' ], 'Test check now (user)' => [ 'user' => ['user' => 'zabbix-user', 'password' => 'zabbix'], 'task' => [ 'type' => ZBX_TM_TASK_CHECK_NOW, 'request' => [ 'itemid' => $itemid ] ], 'expected_error' => 'No permissions to call "task.create".' ], // Test diagnostic info. 'Test diagnostic info (admin)' => [ 'user' => ['user' => 'zabbix-admin', 'password' => 'zabbix'], 'task' => [ 'type' => ZBX_TM_DATA_TYPE_DIAGINFO, 'request' => [ 'alerting' => [ 'stats' => [ 'alerts' ], 'top' => [ 'media.alerts' => 10 ] ], 'lld' => [ 'stats' => 'extend', 'top' => [ 'values' => 5 ] ] ], 'proxyid' => 0 ], 'expected_error' => 'No permissions to call "task.create".' ], 'Test diagnostic info (user)' => [ 'user' => ['user' => 'zabbix-user', 'password' => 'zabbix'], 'task' => [ 'type' => ZBX_TM_DATA_TYPE_DIAGINFO, 'request' => [ 'alerting' => [ 'stats' => [ 'alerts' ], 'top' => [ 'media.alerts' => 10 ] ], 'lld' => [ 'stats' => 'extend', 'top' => [ 'values' => 5 ] ] ], 'proxyid' => 0 ], 'expected_error' => 'No permissions to call "task.create".' ] ]; } /** * Test user permissions. * * @dataProvider getDataPermissions */ public function testTaskCreate_UserPermissions($user, $task, $expected_error) { $sql_check_now_task = "select NULL from task_check_now"; $old_hash_check_now_tasks = CDBHelper::getHash($sql_check_now_task); $sql_diag_info_task = "select NULL from task_data"; $old_hash_diag_info_tasks = CDBHelper::getHash($sql_diag_info_task); $this->authorize($user['user'], $user['password']); $this->call('task.create', $task, $expected_error); // Check if no changes were made in DB. $this->assertSame($old_hash_check_now_tasks, CDBHelper::getHash($sql_check_now_task)); $this->assertSame($old_hash_diag_info_tasks, CDBHelper::getHash($sql_diag_info_task)); } /** * Delete all created data after test. */ public static function clearData() { // Delete hosts and templates. CDataHelper::call('host.delete', [ self::$data['hostids']['monitored'], self::$data['hostids']['not_monitored'] ]); CDataHelper::call('template.delete', [ self::$data['hostids']['template'] ]); // Delete host group. CDataHelper::call('hostgroup.delete', [ self::$data['hostgroupid'] ]); // Delete template group. CDataHelper::call('templategroup.delete', [ self::$data['templategroupid'] ]); // Once items are deleted, tasks for those items are also deleted. However diangonstic info task remain. if (self::$clear_taskids) { DBexecute('DELETE FROM task WHERE '.dbConditionId('taskid', array_keys(self::$clear_taskids))); } } }