You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1389 lines
37 KiB

<?php
/*
** Zabbix
** Copyright (C) 2001-2023 Zabbix SIA
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** 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 General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
require_once __DIR__.'/../include/CAPITest.php';
/**
* @onBefore prepareItemsData
*
* @onAfter clearData
*/
class testTaskCreate extends CAPITest {
private static $data = [
'templategroupid' => 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)));
}
}
}